From 2b54d2e8b83f9682236ac95d166e53fcf24a2786 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 5 Apr 2022 11:34:25 +0200 Subject: bsp/stm32h7: Convert to UNIX line endings --- bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c | 3418 ++++++++++++------------- 1 file changed, 1709 insertions(+), 1709 deletions(-) (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c') diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c index 8c95d707a0..b458ee26c2 100644 --- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c +++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c @@ -1,1713 +1,1713 @@ -/** - ****************************************************************************** - * @file stm32h7xx_hal_flash_ex.c - * @author MCD Application Team - * @brief Extended FLASH HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the FLASH extension peripheral: - * + Extended programming operations functions - * - @verbatim - ============================================================================== - ##### Flash Extension features ##### - ============================================================================== - - [..] Comparing to other previous devices, the FLASH interface for STM32H7xx - devices contains the following additional features - - (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write - capability (RWW) - (+) Dual bank memory organization - (+) PCROP protection for all banks - (+) Global readout protection (RDP) - (+) Write protection - (+) Secure access only protection - (+) Bank / register swapping - (+) Cyclic Redundancy Check (CRC) - - ##### How to use this driver ##### - ============================================================================== - [..] This driver provides functions to configure and program the FLASH memory - of all STM32H7xx devices. It includes - (#) FLASH Memory Erase functions: - (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and - HAL_FLASH_Lock() functions - (++) Erase function: Sector erase, bank erase and dual-bank mass erase - (++) There are two modes of erase : - (+++) Polling Mode using HAL_FLASHEx_Erase() - (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() - - (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to: - (++) Set/Reset the write protection per bank - (++) Set the Read protection Level - (++) Set the BOR level - (++) Program the user Option Bytes - (++) PCROP protection configuration and control per bank - (++) Secure area configuration and control per bank - (++) Core Boot address configuration - - (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(), - HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions - - (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to: - (++) Enable CRC feature - (++) Program the desired burst size - (++) Define the user Flash Area on which the CRC has be computed - (++) Perform the CRC computation - (++) Disable CRC feature - - @endverbatim - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal.h" - -/** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ - -/** @defgroup FLASHEx FLASHEx +/** + ****************************************************************************** + * @file stm32h7xx_hal_flash_ex.c + * @author MCD Application Team + * @brief Extended FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the FLASH extension peripheral: + * + Extended programming operations functions + * + @verbatim + ============================================================================== + ##### Flash Extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the FLASH interface for STM32H7xx + devices contains the following additional features + + (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write + capability (RWW) + (+) Dual bank memory organization + (+) PCROP protection for all banks + (+) Global readout protection (RDP) + (+) Write protection + (+) Secure access only protection + (+) Bank / register swapping + (+) Cyclic Redundancy Check (CRC) + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the FLASH memory + of all STM32H7xx devices. It includes + (#) FLASH Memory Erase functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Erase function: Sector erase, bank erase and dual-bank mass erase + (++) There are two modes of erase : + (+++) Polling Mode using HAL_FLASHEx_Erase() + (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() + + (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to: + (++) Set/Reset the write protection per bank + (++) Set the Read protection Level + (++) Set the BOR level + (++) Program the user Option Bytes + (++) PCROP protection configuration and control per bank + (++) Secure area configuration and control per bank + (++) Core Boot address configuration + + (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(), + HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions + + (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to: + (++) Enable CRC feature + (++) Program the desired burst size + (++) Define the user Flash Area on which the CRC has be computed + (++) Perform the CRC computation + (++) Disable CRC feature + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + +/** @addtogroup STM32H7xx_HAL_Driver + * @{ + */ + +/** @defgroup FLASHEx FLASHEx * @ingroup RTEMSBSPsARMSTM32H7 - * @brief FLASH HAL Extension module driver - * @{ - */ - -#ifdef HAL_FLASH_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** @addtogroup FLASHEx_Private_Constants - * @{ - */ -#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */ - -/** - * @} - */ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @brief FLASH HAL Extension module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FLASHEx_Private_Constants + * @{ + */ +#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */ + +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions * @ingroup RTEMSBSPsARMSTM32H7 - * @{ - */ -static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks); -static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks); -static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank); -static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank); -static void FLASH_OB_RDPConfig(uint32_t RDPLevel); -static uint32_t FLASH_OB_GetRDP(void); -static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks); -static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank); -static void FLASH_OB_BOR_LevelConfig(uint32_t Level); -static uint32_t FLASH_OB_GetBOR(void); -static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig); -static uint32_t FLASH_OB_GetUser(void); -static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1); -static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1); -static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks); -static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank); -static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank); -static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank); - -#if defined (DUAL_CORE) -static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1); -static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1); -#endif /* DUAL_CORE */ - -#if defined (FLASH_OTPBL_LOCKBL) -static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block); -static uint32_t FLASH_OB_OTP_GetLock(void); -#endif /* FLASH_OTPBL_LOCKBL */ -/** - * @} - */ - -/* Exported functions ---------------------------------------------------------*/ -/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions + * @{ + */ +static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks); +static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks); +static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank); +static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank); +static void FLASH_OB_RDPConfig(uint32_t RDPLevel); +static uint32_t FLASH_OB_GetRDP(void); +static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks); +static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank); +static void FLASH_OB_BOR_LevelConfig(uint32_t Level); +static uint32_t FLASH_OB_GetBOR(void); +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig); +static uint32_t FLASH_OB_GetUser(void); +static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1); +static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1); +static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks); +static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank); +static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank); +static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank); + +#if defined (DUAL_CORE) +static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1); +static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1); +#endif /* DUAL_CORE */ + +#if defined (FLASH_OTPBL_LOCKBL) +static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block); +static uint32_t FLASH_OB_OTP_GetLock(void); +#endif /* FLASH_OTPBL_LOCKBL */ +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions * @ingroup RTEMSBSPsARMSTM32H7 - * @{ - */ - -/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions + * @{ + */ + +/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions * @ingroup RTEMSBSPsARMSTM32H7 - * @brief Extended IO operation functions - * -@verbatim - =============================================================================== - ##### Extended programming operation functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to manage the Extension FLASH - programming operations Operations. - -@endverbatim - * @{ - */ -/** - * @brief Perform a mass erase or erase the specified FLASH memory sectors - * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that - * contains the configuration information for the erasing. - * - * @param[out] SectorError pointer to variable that contains the configuration - * information on faulty sector in case of error (0xFFFFFFFF means that all - * the sectors have been correctly erased) - * - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t sector_index; - - /* Check the parameters */ - assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); - assert_param(IS_FLASH_BANK(pEraseInit->Banks)); - - /* Process Locked */ - __HAL_LOCK(&pFlash); - - /* Reset error code */ - pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Wait for last operation to be completed on Bank1 */ - if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) - { - status = HAL_ERROR; - } - } - - /* Wait for last operation to be completed on Bank2 */ - if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) - { - status = HAL_ERROR; - } - } - - if(status == HAL_OK) - { - if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) - { - /* Mass erase to be done */ - FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); - - /* Wait for last operation to be completed */ - if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) - { - status = HAL_ERROR; - } - /* if the erase operation is completed, disable the Bank1 BER Bit */ - FLASH->CR1 &= (~FLASH_CR_BER); - } - if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) - { - status = HAL_ERROR; - } - /* if the erase operation is completed, disable the Bank2 BER Bit */ - FLASH->CR2 &= (~FLASH_CR_BER); - } - } - else - { - /*Initialization of SectorError variable*/ - *SectorError = 0xFFFFFFFFU; - - /* Erase by sector by sector to be done*/ - for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++) - { - FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange); - - if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); - - /* If the erase operation is completed, disable the SER Bit */ - FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); - } - if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); - - /* If the erase operation is completed, disable the SER Bit */ - FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); - } - - if(status != HAL_OK) - { - /* In case of error, stop erase procedure and return the faulty sector */ - *SectorError = sector_index; - break; - } - } - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(&pFlash); - - return status; -} - -/** - * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled - * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that - * contains the configuration information for the erasing. - * - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) -{ - HAL_StatusTypeDef status = HAL_OK; - - /* Check the parameters */ - assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); - assert_param(IS_FLASH_BANK(pEraseInit->Banks)); - - /* Process Locked */ - __HAL_LOCK(&pFlash); - - /* Reset error code */ - pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Wait for last operation to be completed */ - if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) - { - status = HAL_ERROR; - } - } - - if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) - { - status = HAL_ERROR; - } - } - - if (status != HAL_OK) - { - /* Process Unlocked */ - __HAL_UNLOCK(&pFlash); - } - else - { - if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - /* Enable End of Operation and Error interrupts for Bank 1 */ -#if defined (FLASH_CR_OPERRIE) - __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ - FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1); -#else - __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ - FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1); -#endif /* FLASH_CR_OPERRIE */ - } - if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - /* Enable End of Operation and Error interrupts for Bank 2 */ -#if defined (FLASH_CR_OPERRIE) - __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ - FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2); -#else - __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ - FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2); -#endif /* FLASH_CR_OPERRIE */ - } - - if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) - { - /*Mass erase to be done*/ - if(pEraseInit->Banks == FLASH_BANK_1) - { - pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1; - } - else if(pEraseInit->Banks == FLASH_BANK_2) - { - pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2; - } - else - { - pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE; - } - - FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); - } - else - { - /* Erase by sector to be done */ - if(pEraseInit->Banks == FLASH_BANK_1) - { - pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1; - } - else - { - pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2; - } - - pFlash.NbSectorsToErase = pEraseInit->NbSectors; - pFlash.Sector = pEraseInit->Sector; - pFlash.VoltageForErase = pEraseInit->VoltageRange; - - /* Erase first sector and wait for IT */ - FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange); - } - } - - return status; -} - -/** - * @brief Program option bytes - * @param pOBInit pointer to an FLASH_OBInitStruct structure that - * contains the configuration information for the programming. - * - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) -{ - HAL_StatusTypeDef status; - - /* Check the parameters */ - assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); - - /* Process Locked */ - __HAL_LOCK(&pFlash); - - /* Reset Error Code */ - pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Wait for last operation to be completed */ - if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) - { - status = HAL_ERROR; - } - else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) - { - status = HAL_ERROR; - } - else - { - status = HAL_OK; - } - - if(status == HAL_OK) - { - /*Write protection configuration*/ - if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) - { - assert_param(IS_WRPSTATE(pOBInit->WRPState)); - - if(pOBInit->WRPState == OB_WRPSTATE_ENABLE) - { - /*Enable of Write protection on the selected Sector*/ - FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks); - } - else - { - /*Disable of Write protection on the selected Sector*/ - FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks); - } - } - - /* Read protection configuration */ - if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U) - { - /* Configure the Read protection level */ - FLASH_OB_RDPConfig(pOBInit->RDPLevel); - } - - /* User Configuration */ - if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U) - { - /* Configure the user option bytes */ - FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig); - } - - /* PCROP Configuration */ - if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U) - { - assert_param(IS_FLASH_BANK(pOBInit->Banks)); - - /*Configure the Proprietary code readout protection */ - FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks); - } - - /* BOR Level configuration */ - if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR) - { - FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel); - } - -#if defined(DUAL_CORE) - /* CM7 Boot Address configuration */ - if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD) - { - FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1); - } - - /* CM4 Boot Address configuration */ - if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD) - { - FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1); - } -#else /* Single Core*/ - /* Boot Address configuration */ - if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD) - { - FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1); - } -#endif /*DUAL_CORE*/ - - /* Secure area configuration */ - if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA) - { - FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks); - } - -#if defined(FLASH_OTPBL_LOCKBL) - /* OTP Block Lock configuration */ - if((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) == OPTIONBYTE_OTP_LOCK) - { - FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock); - } -#endif /* FLASH_OTPBL_LOCKBL */ - } - - /* Process Unlocked */ - __HAL_UNLOCK(&pFlash); - - return status; -} - -/** - * @brief Get the Option byte configuration - * @param pOBInit pointer to an FLASH_OBInitStruct structure that - * contains the configuration information for the programming. - * @note The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2, - * as this parameter is use to get the given Bank WRP, PCROP and secured area configuration. - * - * @retval None - */ -void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) -{ - pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR); - - /* Get Read protection level */ - pOBInit->RDPLevel = FLASH_OB_GetRDP(); - - /* Get the user option bytes */ - pOBInit->USERConfig = FLASH_OB_GetUser(); - - /*Get BOR Level*/ - pOBInit->BORLevel = FLASH_OB_GetBOR(); - - if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2)) - { - pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA); - - /* Get write protection on the selected area */ - FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks); - - /* Get the Proprietary code readout protection */ - FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks); - - /*Get Bank Secure area*/ - FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks); - } - - /*Get Boot Address*/ - FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1)); -#if defined(DUAL_CORE) - pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD; - - /*Get CM4 Boot Address*/ - FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1)); -#else - pOBInit->OptionType |= OPTIONBYTE_BOOTADD; -#endif /*DUAL_CORE*/ - -#if defined (FLASH_OTPBL_LOCKBL) - pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK; - - /* Get OTP Block Lock */ - pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock(); -#endif /* FLASH_OTPBL_LOCKBL */ -} - -/** - * @brief Unlock the FLASH Bank1 control registers access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void) -{ - if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U) - { - /* Authorize the FLASH Bank1 Registers access */ - WRITE_REG(FLASH->KEYR1, FLASH_KEY1); - WRITE_REG(FLASH->KEYR1, FLASH_KEY2); - - /* Verify Flash Bank1 is unlocked */ - if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U) - { - return HAL_ERROR; - } - } - - return HAL_OK; -} - -/** - * @brief Locks the FLASH Bank1 control registers access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void) -{ - /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */ - SET_BIT(FLASH->CR1, FLASH_CR_LOCK); - return HAL_OK; -} - -/** - * @brief Unlock the FLASH Bank2 control registers access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void) -{ - if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U) - { - /* Authorize the FLASH Bank2 Registers access */ - WRITE_REG(FLASH->KEYR2, FLASH_KEY1); - WRITE_REG(FLASH->KEYR2, FLASH_KEY2); - - /* Verify Flash Bank1 is unlocked */ - if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U) - { - return HAL_ERROR; - } - } - - return HAL_OK; -} - -/** - * @brief Locks the FLASH Bank2 control registers access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void) -{ - /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */ - SET_BIT(FLASH->CR2, FLASH_CR_LOCK); - return HAL_OK; -} - -/* - * @brief Perform a CRC computation on the specified FLASH memory area - * @param pCRCInit pointer to an FLASH_CRCInitTypeDef structure that - * contains the configuration information for the CRC computation. - * @note CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7 - * @note The application should avoid running a CRC on PCROP or secure-only - * user Flash memory area since it may alter the expected CRC value. - * A special error flag (CRC read error: CRCRDERR) can be used to - * detect such a case. - * @retval HAL Status -*/ -HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result) -{ - HAL_StatusTypeDef status; - uint32_t sector_index; - - /* Check the parameters */ - assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank)); - assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC)); - - /* Wait for OB change operation to be completed */ - status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - - if (status == HAL_OK) - { - if (pCRCInit->Bank == FLASH_BANK_1) - { - /* Enable CRC feature */ - FLASH->CR1 |= FLASH_CR_CRC_EN; - - /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */ - FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR); - - /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */ - FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC; - - if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS) - { - /* Clear sectors list */ - FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT; - - /* Select CRC sectors */ - for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++) - { - FLASH_CRC_AddSector(sector_index, FLASH_BANK_1); - } - } - else if (pCRCInit->TypeCRC == FLASH_CRC_BANK) - { - /* Enable Bank 1 CRC select bit */ - FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK; - } - else - { - /* Select CRC start and end addresses */ - FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1); - } - - /* Start the CRC calculation */ - FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC; - - /* Wait on CRC busy flag */ - status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); - - /* Return CRC result */ - (*CRC_Result) = FLASH->CRCDATA; - - /* Disable CRC feature */ - FLASH->CR1 &= (~FLASH_CR_CRC_EN); - - /* Clear CRC flags */ - __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1); - } - else - { - /* Enable CRC feature */ - FLASH->CR2 |= FLASH_CR_CRC_EN; - - /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */ - FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR); - - /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */ - FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC; - - if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS) - { - /* Clear sectors list */ - FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT; - - /* Add CRC sectors */ - for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++) - { - FLASH_CRC_AddSector(sector_index, FLASH_BANK_2); - } - } - else if (pCRCInit->TypeCRC == FLASH_CRC_BANK) - { - /* Enable Bank 2 CRC select bit */ - FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK; - } - else - { - /* Select CRC start and end addresses */ - FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2); - } - - /* Start the CRC calculation */ - FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC; - - /* Wait on CRC busy flag */ - status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); - - /* Return CRC result */ - (*CRC_Result) = FLASH->CRCDATA; - - /* Disable CRC feature */ - FLASH->CR2 &= (~FLASH_CR_CRC_EN); - - /* Clear CRC flags */ - __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2); - } - } - - return status; -} - -/** - * @} - */ - -/** - * @} - */ - -/* Private functions ---------------------------------------------------------*/ - -/** @addtogroup FLASHEx_Private_Functions - * @{ - */ - -/** - * @brief Mass erase of FLASH memory - * @param VoltageRange The device program/erase parallelism. - * This parameter can be one of the following values: - * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits - * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits - * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits - * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits - * - * @param Banks Banks to be erased - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: Bank1 to be erased - * @arg FLASH_BANK_2: Bank2 to be erased - * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased - * - * @retval HAL Status - */ -static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks) -{ - /* Check the parameters */ -#if defined (FLASH_CR_PSIZE) - assert_param(IS_VOLTAGERANGE(VoltageRange)); -#else - UNUSED(VoltageRange); -#endif /* FLASH_CR_PSIZE */ - assert_param(IS_FLASH_BANK(Banks)); - - /* Flash Mass Erase */ - if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH) - { -#if defined (FLASH_CR_PSIZE) - /* Reset Program/erase VoltageRange for Bank1 and Bank2 */ - FLASH->CR1 &= (~FLASH_CR_PSIZE); - FLASH->CR2 &= (~FLASH_CR_PSIZE); - - /* Set voltage range */ - FLASH->CR1 |= VoltageRange; - FLASH->CR2 |= VoltageRange; -#endif /* FLASH_CR_PSIZE */ - - /* Set Mass Erase Bit */ - FLASH->OPTCR |= FLASH_OPTCR_MER; - } - else - { - /* Proceed to erase Flash Bank */ - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { -#if defined (FLASH_CR_PSIZE) - /* Set Program/erase VoltageRange for Bank1 */ - FLASH->CR1 &= (~FLASH_CR_PSIZE); - FLASH->CR1 |= VoltageRange; -#endif /* FLASH_CR_PSIZE */ - - /* Erase Bank1 */ - FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START); - } - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { -#if defined (FLASH_CR_PSIZE) - /* Set Program/erase VoltageRange for Bank2 */ - FLASH->CR2 &= (~FLASH_CR_PSIZE); - FLASH->CR2 |= VoltageRange; -#endif /* FLASH_CR_PSIZE */ - - /* Erase Bank2 */ - FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START); - } - } -} - -/** - * @brief Erase the specified FLASH memory sector - * @param Sector FLASH sector to erase - * This parameter can be a value of @ref FLASH_Sectors - * @param Banks Banks to be erased - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: Bank1 to be erased - * @arg FLASH_BANK_2: Bank2 to be erased - * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased - * @param VoltageRange The device program/erase parallelism. - * This parameter can be one of the following values: - * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits - * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits - * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits - * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits - * - * @retval None - */ -void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange) -{ - assert_param(IS_FLASH_SECTOR(Sector)); - assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks)); -#if defined (FLASH_CR_PSIZE) - assert_param(IS_VOLTAGERANGE(VoltageRange)); -#else - UNUSED(VoltageRange); -#endif /* FLASH_CR_PSIZE */ - - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { -#if defined (FLASH_CR_PSIZE) - /* Reset Program/erase VoltageRange and Sector Number for Bank1 */ - FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); - - FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); -#else - /* Reset Sector Number for Bank1 */ - FLASH->CR1 &= ~(FLASH_CR_SNB); - - FLASH->CR1 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); -#endif /* FLASH_CR_PSIZE */ - } - - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { -#if defined (FLASH_CR_PSIZE) - /* Reset Program/erase VoltageRange and Sector Number for Bank2 */ - FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); - - FLASH->CR2 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); -#else - /* Reset Sector Number for Bank2 */ - FLASH->CR2 &= ~(FLASH_CR_SNB); - - FLASH->CR2 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); -#endif /* FLASH_CR_PSIZE */ - } -} - -/** - * @brief Enable the write protection of the desired bank1 or bank 2 sectors - * @param WRPSector specifies the sector(s) to be write protected. - * This parameter can be one of the following values: - * @arg WRPSector: A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_All - * - * @param Banks the specific bank to apply WRP sectors - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: enable WRP on specified bank1 sectors - * @arg FLASH_BANK_2: enable WRP on specified bank2 sectors - * @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors - * - * @retval HAL FLASH State - */ -static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) -{ - /* Check the parameters */ - assert_param(IS_OB_WRP_SECTOR(WRPSector)); - assert_param(IS_FLASH_BANK(Banks)); - - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - /* Enable Write Protection for bank 1 */ - FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN)); - } - - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - /* Enable Write Protection for bank 2 */ - FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN)); - } -} - -/** - * @brief Disable the write protection of the desired bank1 or bank 2 sectors - * @param WRPSector specifies the sector(s) to disable write protection. - * This parameter can be one of the following values: - * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All - * - * @param Banks the specific bank to apply WRP sectors - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: disable WRP on specified bank1 sectors - * @arg FLASH_BANK_2: disable WRP on specified bank2 sectors - * @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors - * - * @retval HAL FLASH State - */ -static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) -{ - /* Check the parameters */ - assert_param(IS_OB_WRP_SECTOR(WRPSector)); - assert_param(IS_FLASH_BANK(Banks)); - - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - /* Disable Write Protection for bank 1 */ - FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN); - } - - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - /* Disable Write Protection for bank 2 */ - FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN); - } -} - -/** - * @brief Get the write protection of the given bank 1 or bank 2 sectors - * @param WRPState gives the write protection state on the given bank. - * This parameter can be one of the following values: - * @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE - - * @param WRPSector gives the write protected sector(s) on the given bank . - * This parameter can be one of the following values: - * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All - * - * @param Bank the specific bank to apply WRP sectors - * This parameter can be exclusively one of the following values: - * @arg FLASH_BANK_1: Get bank1 WRP sectors - * @arg FLASH_BANK_2: Get bank2 WRP sectors - * @arg FLASH_BANK_BOTH: note allowed in this functions - * - * @retval HAL FLASH State - */ -static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank) -{ - uint32_t regvalue = 0U; - - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) - { - regvalue = FLASH->WPSN_CUR1; - } - - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) - { - regvalue = FLASH->WPSN_CUR2; - } - - (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN; - - if(*WRPSector == 0U) - { - (*WRPState) = OB_WRPSTATE_DISABLE; - } - else - { - (*WRPState) = OB_WRPSTATE_ENABLE; - } -} - -/** - * @brief Set the read protection level. - * - * @note To configure the RDP level, the option lock bit OPTLOCK must be - * cleared with the call of the HAL_FLASH_OB_Unlock() function. - * @note To validate the RDP level, the option bytes must be reloaded - * through the call of the HAL_FLASH_OB_Launch() function. - * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible - * to go back to level 1 or 0 !!! - * - * @param RDPLevel specifies the read protection level. - * This parameter can be one of the following values: - * @arg OB_RDP_LEVEL_0: No protection - * @arg OB_RDP_LEVEL_1: Read protection of the memory - * @arg OB_RDP_LEVEL_2: Full chip protection - * - * @retval HAL status - */ -static void FLASH_OB_RDPConfig(uint32_t RDPLevel) -{ - /* Check the parameters */ - assert_param(IS_OB_RDP_LEVEL(RDPLevel)); - - /* Configure the RDP level in the option bytes register */ - MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel); -} - -/** - * @brief Get the read protection level. - * @retval RDPLevel specifies the read protection level. - * This return value can be one of the following values: - * @arg OB_RDP_LEVEL_0: No protection - * @arg OB_RDP_LEVEL_1: Read protection of the memory - * @arg OB_RDP_LEVEL_2: Full chip protection - */ -static uint32_t FLASH_OB_GetRDP(void) -{ - uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP); - - if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2)) - { - return (OB_RDP_LEVEL_1); - } - else - { - return rdp_level; - } -} - -#if defined(DUAL_CORE) -/** - * @brief Program the FLASH User Option Byte. - * - * @note To configure the user option bytes, the option lock bit OPTLOCK must - * be cleared with the call of the HAL_FLASH_OB_Unlock() function. - * - * @note To validate the user option bytes, the option bytes must be reloaded - * through the call of the HAL_FLASH_OB_Launch() function. - * - * @param UserType The FLASH User Option Bytes to be modified : - * a combination of @ref FLASHEx_OB_USER_Type - * - * @param UserConfig The FLASH User Option Bytes values: - * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), - * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), - * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24), - * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). - * - * @retval HAL status - */ -#else -/** - * @brief Program the FLASH User Option Byte. - * - * @note To configure the user option bytes, the option lock bit OPTLOCK must - * be cleared with the call of the HAL_FLASH_OB_Unlock() function. - * - * @note To validate the user option bytes, the option bytes must be reloaded - * through the call of the HAL_FLASH_OB_Launch() function. - * - * @param UserType The FLASH User Option Bytes to be modified : - * a combination of @arg FLASHEx_OB_USER_Type - * - * @param UserConfig The FLASH User Option Bytes values: - * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), - * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), - * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). - * - * @retval HAL status - */ -#endif /*DUAL_CORE*/ -static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig) -{ - uint32_t optr_reg_val = 0; - uint32_t optr_reg_mask = 0; - - /* Check the parameters */ - assert_param(IS_OB_USER_TYPE(UserType)); - - if((UserType & OB_USER_IWDG1_SW) != 0U) - { - /* IWDG_HW option byte should be modified */ - assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW)); - - /* Set value and mask for IWDG_HW option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW); - optr_reg_mask |= FLASH_OPTSR_IWDG1_SW; - } -#if defined(DUAL_CORE) - if((UserType & OB_USER_IWDG2_SW) != 0U) - { - /* IWDG2_SW option byte should be modified */ - assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW)); - - /* Set value and mask for IWDG2_SW option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW); - optr_reg_mask |= FLASH_OPTSR_IWDG2_SW; - } -#endif /*DUAL_CORE*/ - if((UserType & OB_USER_NRST_STOP_D1) != 0U) - { - /* NRST_STOP option byte should be modified */ - assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1)); - - /* Set value and mask for NRST_STOP option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1); - optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1; - } - - if((UserType & OB_USER_NRST_STDBY_D1) != 0U) - { - /* NRST_STDBY option byte should be modified */ - assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1)); - - /* Set value and mask for NRST_STDBY option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1); - optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1; - } - - if((UserType & OB_USER_IWDG_STOP) != 0U) - { - /* IWDG_STOP option byte should be modified */ - assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP)); - - /* Set value and mask for IWDG_STOP option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP); - optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP; - } - - if((UserType & OB_USER_IWDG_STDBY) != 0U) - { - /* IWDG_STDBY option byte should be modified */ - assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY)); - - /* Set value and mask for IWDG_STDBY option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY); - optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY; - } - - if((UserType & OB_USER_ST_RAM_SIZE) != 0U) - { - /* ST_RAM_SIZE option byte should be modified */ - assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE)); - - /* Set value and mask for ST_RAM_SIZE option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE); - optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE; - } - - if((UserType & OB_USER_SECURITY) != 0U) - { - /* SECURITY option byte should be modified */ - assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY)); - - /* Set value and mask for SECURITY option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY); - optr_reg_mask |= FLASH_OPTSR_SECURITY; - } - -#if defined(DUAL_CORE) - if((UserType & OB_USER_BCM4) != 0U) - { - /* BCM4 option byte should be modified */ - assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4)); - - /* Set value and mask for BCM4 option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4); - optr_reg_mask |= FLASH_OPTSR_BCM4; - } - - if((UserType & OB_USER_BCM7) != 0U) - { - /* BCM7 option byte should be modified */ - assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7)); - - /* Set value and mask for BCM7 option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7); - optr_reg_mask |= FLASH_OPTSR_BCM7; - } - - if((UserType & OB_USER_NRST_STOP_D2) != 0U) - { - /* NRST_STOP option byte should be modified */ - assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2)); - - /* Set value and mask for NRST_STOP option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2); - optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2; - } - - if((UserType & OB_USER_NRST_STDBY_D2) != 0U) - { - /* NRST_STDBY option byte should be modified */ - assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2)); - - /* Set value and mask for NRST_STDBY option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2); - optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2; - } -#endif /* DUAL_CORE */ - if((UserType & OB_USER_SWAP_BANK) != 0U) - { - /* SWAP_BANK_OPT option byte should be modified */ - assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT)); - - /* Set value and mask for SWAP_BANK_OPT option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT); - optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT; - } - - if((UserType & OB_USER_IOHSLV) != 0U) - { - /* IOHSLV_OPT option byte should be modified */ - assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV)); - - /* Set value and mask for IOHSLV_OPT option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV); - optr_reg_mask |= FLASH_OPTSR_IO_HSLV; - } - -#if defined (FLASH_OPTSR_VDDMMC_HSLV) - if((UserType & OB_USER_VDDMMC_HSLV) != 0U) - { - /* VDDMMC_HSLV option byte should be modified */ - assert_param(IS_OB_USER_VDDMMC_HSLV(UserConfig & FLASH_OPTSR_VDDMMC_HSLV)); - - /* Set value and mask for VDDMMC_HSLV option byte */ - optr_reg_val |= (UserConfig & FLASH_OPTSR_VDDMMC_HSLV); - optr_reg_mask |= FLASH_OPTSR_VDDMMC_HSLV; - } -#endif /* FLASH_OPTSR_VDDMMC_HSLV */ - - /* Configure the option bytes register */ - MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val); -} - -#if defined(DUAL_CORE) -/** - * @brief Return the FLASH User Option Byte value. - * @retval The FLASH User Option Bytes values - * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), - * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), - * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24), - * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). - */ -#else -/** - * @brief Return the FLASH User Option Byte value. - * @retval The FLASH User Option Bytes values - * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), - * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), - * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). - */ -#endif /*DUAL_CORE*/ -static uint32_t FLASH_OB_GetUser(void) -{ - uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR); - userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP)); - - return userConfig; -} - -/** - * @brief Configure the Proprietary code readout protection of the desired addresses - * - * @note To configure the PCROP options, the option lock bit OPTLOCK must be - * cleared with the call of the HAL_FLASH_OB_Unlock() function. - * @note To validate the PCROP options, the option bytes must be reloaded - * through the call of the HAL_FLASH_OB_Launch() function. - * - * @param PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not - * when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal - * This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration - * - * @param PCROPStartAddr specifies the start address of the Proprietary code readout protection - * This parameter can be an address between begin and end of the bank - * - * @param PCROPEndAddr specifies the end address of the Proprietary code readout protection - * This parameter can be an address between PCROPStartAddr and end of the bank - * - * @param Banks the specific bank to apply PCROP protection - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: PCROP on specified bank1 area - * @arg FLASH_BANK_2: PCROP on specified bank2 area - * @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks) - * - * @retval None - */ -static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks) -{ - /* Check the parameters */ - assert_param(IS_FLASH_BANK(Banks)); - assert_param(IS_OB_PCROP_RDP(PCROPConfig)); - - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr)); - - /* Configure the Proprietary code readout protection */ - FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8) | \ - (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \ - PCROPConfig; - } - - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr)); - - /* Configure the Proprietary code readout protection */ - FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8) | \ - (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \ - PCROPConfig; - } -} - -/** - * @brief Get the Proprietary code readout protection configuration on a given Bank - * - * @param PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not - * when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal - * - * @param PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank - * - * @param PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank - * - * @param Bank the specific bank to apply PCROP protection - * This parameter can be exclusively one of the following values: - * @arg FLASH_BANK_1: PCROP on specified bank1 area - * @arg FLASH_BANK_2: PCROP on specified bank2 area - * @arg FLASH_BANK_BOTH: is not allowed here - * - * @retval None - */ -static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank) -{ - uint32_t regvalue = 0; - uint32_t bankBase = 0; - - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) - { - regvalue = FLASH->PRAR_CUR1; - bankBase = FLASH_BANK1_BASE; - } - - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) - { - regvalue = FLASH->PRAR_CUR2; - bankBase = FLASH_BANK2_BASE; - } - - (*PCROPConfig) = (regvalue & FLASH_PRAR_DMEP); - - (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase; - (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos; - (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase; -} - -/** - * @brief Set the BOR Level. - * @param Level specifies the Option Bytes BOR Reset Level. - * This parameter can be one of the following values: - * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V - * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V - * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V - * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V - * @retval None - */ -static void FLASH_OB_BOR_LevelConfig(uint32_t Level) -{ - assert_param(IS_OB_BOR_LEVEL(Level)); - - /* Configure BOR_LEV option byte */ - MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level); -} - -/** - * @brief Get the BOR Level. - * @retval The Option Bytes BOR Reset Level. - * This parameter can be one of the following values: - * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V - * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V - * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V - * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V - */ -static uint32_t FLASH_OB_GetBOR(void) -{ - return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV); -} - -/** - * @brief Set Boot address - * @param BootOption Boot address option byte to be programmed, - * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION - (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH) - * - * @param BootAddress0 Specifies the Boot Address 0 - * @param BootAddress1 Specifies the Boot Address 1 - * @retval HAL Status - */ -static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1) -{ - /* Check the parameters */ - assert_param(IS_OB_BOOT_ADD_OPTION(BootOption)); - - if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0) - { - /* Check the parameters */ - assert_param(IS_BOOT_ADDRESS(BootAddress0)); - - /* Configure CM7 BOOT ADD0 */ -#if defined(DUAL_CORE) - MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16)); -#else /* Single Core*/ - MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16)); -#endif /* DUAL_CORE */ - } - - if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1) - { - /* Check the parameters */ - assert_param(IS_BOOT_ADDRESS(BootAddress1)); - - /* Configure CM7 BOOT ADD1 */ -#if defined(DUAL_CORE) - MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1); -#else /* Single Core*/ - MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1); -#endif /* DUAL_CORE */ - } -} - -/** - * @brief Get Boot address - * @param BootAddress0 Specifies the Boot Address 0. - * @param BootAddress1 Specifies the Boot Address 1. - * @retval HAL Status - */ -static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1) -{ - uint32_t regvalue; - -#if defined(DUAL_CORE) - regvalue = FLASH->BOOT7_CUR; - - (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16; - (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1); -#else /* Single Core */ - regvalue = FLASH->BOOT_CUR; - - (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16; - (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1); -#endif /* DUAL_CORE */ -} - -#if defined(DUAL_CORE) -/** - * @brief Set CM4 Boot address - * @param BootOption Boot address option byte to be programmed, - * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION - (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH) - * - * @param BootAddress0 Specifies the CM4 Boot Address 0. - * @param BootAddress1 Specifies the CM4 Boot Address 1. - * @retval HAL Status - */ -static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1) -{ - /* Check the parameters */ - assert_param(IS_OB_BOOT_ADD_OPTION(BootOption)); - - if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0) - { - /* Check the parameters */ - assert_param(IS_BOOT_ADDRESS(BootAddress0)); - - /* Configure CM4 BOOT ADD0 */ - MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16)); - - } - - if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1) - { - /* Check the parameters */ - assert_param(IS_BOOT_ADDRESS(BootAddress1)); - - /* Configure CM4 BOOT ADD1 */ - MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1); - } -} - -/** - * @brief Get CM4 Boot address - * @param BootAddress0 Specifies the CM4 Boot Address 0. - * @param BootAddress1 Specifies the CM4 Boot Address 1. - * @retval HAL Status - */ -static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1) -{ - uint32_t regvalue; - - regvalue = FLASH->BOOT4_CUR; - - (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16; - (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1); -} -#endif /*DUAL_CORE*/ - -/** - * @brief Set secure area configuration - * @param SecureAreaConfig specify if the secure area will be deleted or not - * when RDP level decreased from Level 1 to Level 0 or during a mass erase. - * - * @param SecureAreaStartAddr Specifies the secure area start address - * @param SecureAreaEndAddr Specifies the secure area end address - * @param Banks the specific bank to apply Security protection - * This parameter can be one of the following values: - * @arg FLASH_BANK_1: Secure area on specified bank1 area - * @arg FLASH_BANK_2: Secure area on specified bank2 area - * @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks) - * @retval None - */ -static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks) -{ - /* Check the parameters */ - assert_param(IS_FLASH_BANK(Banks)); - assert_param(IS_OB_SECURE_RDP(SecureAreaConfig)); - - if((Banks & FLASH_BANK_1) == FLASH_BANK_1) - { - /* Check the parameters */ - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr)); - - /* Configure the secure area */ - FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8) | \ - (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \ - (SecureAreaConfig & FLASH_SCAR_DMES); - } - - if((Banks & FLASH_BANK_2) == FLASH_BANK_2) - { - /* Check the parameters */ - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr)); - - /* Configure the secure area */ - FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8) | \ - (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \ - (SecureAreaConfig & FLASH_SCAR_DMES); - } -} - -/** - * @brief Get secure area configuration - * @param SecureAreaConfig indicates if the secure area will be deleted or not - * when RDP level decreased from Level 1 to Level 0 or during a mass erase. - * @param SecureAreaStartAddr gives the secure area start address - * @param SecureAreaEndAddr gives the secure area end address - * @param Bank Specifies the Bank - * @retval None - */ -static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank) -{ - uint32_t regvalue = 0; - uint32_t bankBase = 0; - - /* Check Bank parameter value */ - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) - { - regvalue = FLASH->SCAR_CUR1; - bankBase = FLASH_BANK1_BASE; - } - - if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) - { - regvalue = FLASH->SCAR_CUR2; - bankBase = FLASH_BANK2_BASE; - } - - /* Get the secure area settings */ - (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES); - (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase; - (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos; - (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase; -} - -/** - * @brief Add a CRC sector to the list of sectors on which the CRC will be calculated - * @param Sector Specifies the CRC sector number - * @param Bank Specifies the Bank - * @retval None - */ -static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank) -{ - /* Check the parameters */ - assert_param(IS_FLASH_SECTOR(Sector)); - - if (Bank == FLASH_BANK_1) - { - /* Clear CRC sector */ - FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT); - - /* Select CRC Sector and activate ADD_SECT bit */ - FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT; - } - else - { - /* Clear CRC sector */ - FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT); - - /* Select CRC Sector and activate ADD_SECT bit */ - FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT; - } -} - -/** - * @brief Select CRC start and end memory addresses on which the CRC will be calculated - * @param CRCStartAddr Specifies the CRC start address - * @param CRCEndAddr Specifies the CRC end address - * @param Bank Specifies the Bank - * @retval None - */ -static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank) -{ - if (Bank == FLASH_BANK_1) - { - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr)); - - /* Write CRC Start and End addresses */ - FLASH->CRCSADD1 = CRCStartAddr; - FLASH->CRCEADD1 = CRCEndAddr; - } - else - { - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr)); - assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr)); - - /* Write CRC Start and End addresses */ - FLASH->CRCSADD2 = CRCStartAddr; - FLASH->CRCEADD2 = CRCEndAddr; - } -} -/** - * @} - */ - -#if defined (FLASH_OTPBL_LOCKBL) -/** - * @brief Configure the OTP Block Lock. - * @param OTP_Block specifies the OTP Block to lock. - * This parameter can be a value of @ref FLASHEx_OTP_Blocks - * @retval None - */ -static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block) -{ - /* Check the parameters */ - assert_param(IS_OTP_BLOCK(OTP_Block)); - - /* Configure the OTP Block lock in the option bytes register */ - FLASH->OTPBL_PRG |= (OTP_Block & FLASH_OTPBL_LOCKBL); -} - -/** - * @brief Get the OTP Block Lock. - * @retval OTP_Block specifies the OTP Block to lock. - * This return value can be a value of @ref FLASHEx_OTP_Blocks - */ -static uint32_t FLASH_OB_OTP_GetLock(void) -{ - return (FLASH->OTPBL_CUR); -} -#endif /* FLASH_OTPBL_LOCKBL */ - -#endif /* HAL_FLASH_MODULE_ENABLED */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + * @brief Extended IO operation functions + * +@verbatim + =============================================================================== + ##### Extended programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the Extension FLASH + programming operations Operations. + +@endverbatim + * @{ + */ +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors + * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @param[out] SectorError pointer to variable that contains the configuration + * information on faulty sector in case of error (0xFFFFFFFF means that all + * the sectors have been correctly erased) + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t sector_index; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + assert_param(IS_FLASH_BANK(pEraseInit->Banks)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed on Bank1 */ + if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) + { + status = HAL_ERROR; + } + } + + /* Wait for last operation to be completed on Bank2 */ + if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) + { + status = HAL_ERROR; + } + } + + if(status == HAL_OK) + { + if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /* Mass erase to be done */ + FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); + + /* Wait for last operation to be completed */ + if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) + { + status = HAL_ERROR; + } + /* if the erase operation is completed, disable the Bank1 BER Bit */ + FLASH->CR1 &= (~FLASH_CR_BER); + } + if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) + { + status = HAL_ERROR; + } + /* if the erase operation is completed, disable the Bank2 BER Bit */ + FLASH->CR2 &= (~FLASH_CR_BER); + } + } + else + { + /*Initialization of SectorError variable*/ + *SectorError = 0xFFFFFFFFU; + + /* Erase by sector by sector to be done*/ + for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++) + { + FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange); + + if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); + + /* If the erase operation is completed, disable the SER Bit */ + FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); + } + if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); + + /* If the erase operation is completed, disable the SER Bit */ + FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); + } + + if(status != HAL_OK) + { + /* In case of error, stop erase procedure and return the faulty sector */ + *SectorError = sector_index; + break; + } + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled + * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + assert_param(IS_FLASH_BANK(pEraseInit->Banks)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) + { + status = HAL_ERROR; + } + } + + if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) + { + status = HAL_ERROR; + } + } + + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + else + { + if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Enable End of Operation and Error interrupts for Bank 1 */ +#if defined (FLASH_CR_OPERRIE) + __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ + FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1); +#else + __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ + FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1); +#endif /* FLASH_CR_OPERRIE */ + } + if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Enable End of Operation and Error interrupts for Bank 2 */ +#if defined (FLASH_CR_OPERRIE) + __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ + FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2); +#else + __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ + FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2); +#endif /* FLASH_CR_OPERRIE */ + } + + if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /*Mass erase to be done*/ + if(pEraseInit->Banks == FLASH_BANK_1) + { + pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1; + } + else if(pEraseInit->Banks == FLASH_BANK_2) + { + pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2; + } + else + { + pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE; + } + + FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); + } + else + { + /* Erase by sector to be done */ + if(pEraseInit->Banks == FLASH_BANK_1) + { + pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1; + } + else + { + pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2; + } + + pFlash.NbSectorsToErase = pEraseInit->NbSectors; + pFlash.Sector = pEraseInit->Sector; + pFlash.VoltageForErase = pEraseInit->VoltageRange; + + /* Erase first sector and wait for IT */ + FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange); + } + } + + return status; +} + +/** + * @brief Program option bytes + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) +{ + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset Error Code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK) + { + status = HAL_ERROR; + } + else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + status = HAL_OK; + } + + if(status == HAL_OK) + { + /*Write protection configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) + { + assert_param(IS_WRPSTATE(pOBInit->WRPState)); + + if(pOBInit->WRPState == OB_WRPSTATE_ENABLE) + { + /*Enable of Write protection on the selected Sector*/ + FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks); + } + else + { + /*Disable of Write protection on the selected Sector*/ + FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks); + } + } + + /* Read protection configuration */ + if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U) + { + /* Configure the Read protection level */ + FLASH_OB_RDPConfig(pOBInit->RDPLevel); + } + + /* User Configuration */ + if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U) + { + /* Configure the user option bytes */ + FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig); + } + + /* PCROP Configuration */ + if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U) + { + assert_param(IS_FLASH_BANK(pOBInit->Banks)); + + /*Configure the Proprietary code readout protection */ + FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks); + } + + /* BOR Level configuration */ + if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR) + { + FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel); + } + +#if defined(DUAL_CORE) + /* CM7 Boot Address configuration */ + if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD) + { + FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1); + } + + /* CM4 Boot Address configuration */ + if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD) + { + FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1); + } +#else /* Single Core*/ + /* Boot Address configuration */ + if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD) + { + FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1); + } +#endif /*DUAL_CORE*/ + + /* Secure area configuration */ + if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA) + { + FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks); + } + +#if defined(FLASH_OTPBL_LOCKBL) + /* OTP Block Lock configuration */ + if((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) == OPTIONBYTE_OTP_LOCK) + { + FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock); + } +#endif /* FLASH_OTPBL_LOCKBL */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Get the Option byte configuration + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * @note The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2, + * as this parameter is use to get the given Bank WRP, PCROP and secured area configuration. + * + * @retval None + */ +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) +{ + pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR); + + /* Get Read protection level */ + pOBInit->RDPLevel = FLASH_OB_GetRDP(); + + /* Get the user option bytes */ + pOBInit->USERConfig = FLASH_OB_GetUser(); + + /*Get BOR Level*/ + pOBInit->BORLevel = FLASH_OB_GetBOR(); + + if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2)) + { + pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA); + + /* Get write protection on the selected area */ + FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks); + + /* Get the Proprietary code readout protection */ + FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks); + + /*Get Bank Secure area*/ + FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks); + } + + /*Get Boot Address*/ + FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1)); +#if defined(DUAL_CORE) + pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD; + + /*Get CM4 Boot Address*/ + FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1)); +#else + pOBInit->OptionType |= OPTIONBYTE_BOOTADD; +#endif /*DUAL_CORE*/ + +#if defined (FLASH_OTPBL_LOCKBL) + pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK; + + /* Get OTP Block Lock */ + pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock(); +#endif /* FLASH_OTPBL_LOCKBL */ +} + +/** + * @brief Unlock the FLASH Bank1 control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void) +{ + if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U) + { + /* Authorize the FLASH Bank1 Registers access */ + WRITE_REG(FLASH->KEYR1, FLASH_KEY1); + WRITE_REG(FLASH->KEYR1, FLASH_KEY2); + + /* Verify Flash Bank1 is unlocked */ + if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Locks the FLASH Bank1 control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void) +{ + /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */ + SET_BIT(FLASH->CR1, FLASH_CR_LOCK); + return HAL_OK; +} + +/** + * @brief Unlock the FLASH Bank2 control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void) +{ + if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U) + { + /* Authorize the FLASH Bank2 Registers access */ + WRITE_REG(FLASH->KEYR2, FLASH_KEY1); + WRITE_REG(FLASH->KEYR2, FLASH_KEY2); + + /* Verify Flash Bank1 is unlocked */ + if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Locks the FLASH Bank2 control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void) +{ + /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */ + SET_BIT(FLASH->CR2, FLASH_CR_LOCK); + return HAL_OK; +} + +/* + * @brief Perform a CRC computation on the specified FLASH memory area + * @param pCRCInit pointer to an FLASH_CRCInitTypeDef structure that + * contains the configuration information for the CRC computation. + * @note CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7 + * @note The application should avoid running a CRC on PCROP or secure-only + * user Flash memory area since it may alter the expected CRC value. + * A special error flag (CRC read error: CRCRDERR) can be used to + * detect such a case. + * @retval HAL Status +*/ +HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result) +{ + HAL_StatusTypeDef status; + uint32_t sector_index; + + /* Check the parameters */ + assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank)); + assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC)); + + /* Wait for OB change operation to be completed */ + status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + if (pCRCInit->Bank == FLASH_BANK_1) + { + /* Enable CRC feature */ + FLASH->CR1 |= FLASH_CR_CRC_EN; + + /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */ + FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR); + + /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */ + FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC; + + if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS) + { + /* Clear sectors list */ + FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT; + + /* Select CRC sectors */ + for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++) + { + FLASH_CRC_AddSector(sector_index, FLASH_BANK_1); + } + } + else if (pCRCInit->TypeCRC == FLASH_CRC_BANK) + { + /* Enable Bank 1 CRC select bit */ + FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK; + } + else + { + /* Select CRC start and end addresses */ + FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1); + } + + /* Start the CRC calculation */ + FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC; + + /* Wait on CRC busy flag */ + status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); + + /* Return CRC result */ + (*CRC_Result) = FLASH->CRCDATA; + + /* Disable CRC feature */ + FLASH->CR1 &= (~FLASH_CR_CRC_EN); + + /* Clear CRC flags */ + __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1); + } + else + { + /* Enable CRC feature */ + FLASH->CR2 |= FLASH_CR_CRC_EN; + + /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */ + FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR); + + /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */ + FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC; + + if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS) + { + /* Clear sectors list */ + FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT; + + /* Add CRC sectors */ + for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++) + { + FLASH_CRC_AddSector(sector_index, FLASH_BANK_2); + } + } + else if (pCRCInit->TypeCRC == FLASH_CRC_BANK) + { + /* Enable Bank 2 CRC select bit */ + FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK; + } + else + { + /* Select CRC start and end addresses */ + FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2); + } + + /* Start the CRC calculation */ + FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC; + + /* Wait on CRC busy flag */ + status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); + + /* Return CRC result */ + (*CRC_Result) = FLASH->CRCDATA; + + /* Disable CRC feature */ + FLASH->CR2 &= (~FLASH_CR_CRC_EN); + + /* Clear CRC flags */ + __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2); + } + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ + +/** + * @brief Mass erase of FLASH memory + * @param VoltageRange The device program/erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits + * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits + * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits + * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits + * + * @param Banks Banks to be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * @arg FLASH_BANK_2: Bank2 to be erased + * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * + * @retval HAL Status + */ +static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks) +{ + /* Check the parameters */ +#if defined (FLASH_CR_PSIZE) + assert_param(IS_VOLTAGERANGE(VoltageRange)); +#else + UNUSED(VoltageRange); +#endif /* FLASH_CR_PSIZE */ + assert_param(IS_FLASH_BANK(Banks)); + + /* Flash Mass Erase */ + if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH) + { +#if defined (FLASH_CR_PSIZE) + /* Reset Program/erase VoltageRange for Bank1 and Bank2 */ + FLASH->CR1 &= (~FLASH_CR_PSIZE); + FLASH->CR2 &= (~FLASH_CR_PSIZE); + + /* Set voltage range */ + FLASH->CR1 |= VoltageRange; + FLASH->CR2 |= VoltageRange; +#endif /* FLASH_CR_PSIZE */ + + /* Set Mass Erase Bit */ + FLASH->OPTCR |= FLASH_OPTCR_MER; + } + else + { + /* Proceed to erase Flash Bank */ + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { +#if defined (FLASH_CR_PSIZE) + /* Set Program/erase VoltageRange for Bank1 */ + FLASH->CR1 &= (~FLASH_CR_PSIZE); + FLASH->CR1 |= VoltageRange; +#endif /* FLASH_CR_PSIZE */ + + /* Erase Bank1 */ + FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START); + } + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { +#if defined (FLASH_CR_PSIZE) + /* Set Program/erase VoltageRange for Bank2 */ + FLASH->CR2 &= (~FLASH_CR_PSIZE); + FLASH->CR2 |= VoltageRange; +#endif /* FLASH_CR_PSIZE */ + + /* Erase Bank2 */ + FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START); + } + } +} + +/** + * @brief Erase the specified FLASH memory sector + * @param Sector FLASH sector to erase + * This parameter can be a value of @ref FLASH_Sectors + * @param Banks Banks to be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * @arg FLASH_BANK_2: Bank2 to be erased + * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * @param VoltageRange The device program/erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits + * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits + * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits + * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits + * + * @retval None + */ +void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange) +{ + assert_param(IS_FLASH_SECTOR(Sector)); + assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks)); +#if defined (FLASH_CR_PSIZE) + assert_param(IS_VOLTAGERANGE(VoltageRange)); +#else + UNUSED(VoltageRange); +#endif /* FLASH_CR_PSIZE */ + + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { +#if defined (FLASH_CR_PSIZE) + /* Reset Program/erase VoltageRange and Sector Number for Bank1 */ + FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); + + FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); +#else + /* Reset Sector Number for Bank1 */ + FLASH->CR1 &= ~(FLASH_CR_SNB); + + FLASH->CR1 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); +#endif /* FLASH_CR_PSIZE */ + } + + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { +#if defined (FLASH_CR_PSIZE) + /* Reset Program/erase VoltageRange and Sector Number for Bank2 */ + FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); + + FLASH->CR2 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); +#else + /* Reset Sector Number for Bank2 */ + FLASH->CR2 &= ~(FLASH_CR_SNB); + + FLASH->CR2 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); +#endif /* FLASH_CR_PSIZE */ + } +} + +/** + * @brief Enable the write protection of the desired bank1 or bank 2 sectors + * @param WRPSector specifies the sector(s) to be write protected. + * This parameter can be one of the following values: + * @arg WRPSector: A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_All + * + * @param Banks the specific bank to apply WRP sectors + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: enable WRP on specified bank1 sectors + * @arg FLASH_BANK_2: enable WRP on specified bank2 sectors + * @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors + * + * @retval HAL FLASH State + */ +static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Enable Write Protection for bank 1 */ + FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN)); + } + + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Enable Write Protection for bank 2 */ + FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN)); + } +} + +/** + * @brief Disable the write protection of the desired bank1 or bank 2 sectors + * @param WRPSector specifies the sector(s) to disable write protection. + * This parameter can be one of the following values: + * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All + * + * @param Banks the specific bank to apply WRP sectors + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: disable WRP on specified bank1 sectors + * @arg FLASH_BANK_2: disable WRP on specified bank2 sectors + * @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors + * + * @retval HAL FLASH State + */ +static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Disable Write Protection for bank 1 */ + FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN); + } + + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Disable Write Protection for bank 2 */ + FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN); + } +} + +/** + * @brief Get the write protection of the given bank 1 or bank 2 sectors + * @param WRPState gives the write protection state on the given bank. + * This parameter can be one of the following values: + * @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE + + * @param WRPSector gives the write protected sector(s) on the given bank . + * This parameter can be one of the following values: + * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All + * + * @param Bank the specific bank to apply WRP sectors + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: Get bank1 WRP sectors + * @arg FLASH_BANK_2: Get bank2 WRP sectors + * @arg FLASH_BANK_BOTH: note allowed in this functions + * + * @retval HAL FLASH State + */ +static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank) +{ + uint32_t regvalue = 0U; + + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) + { + regvalue = FLASH->WPSN_CUR1; + } + + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) + { + regvalue = FLASH->WPSN_CUR2; + } + + (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN; + + if(*WRPSector == 0U) + { + (*WRPState) = OB_WRPSTATE_DISABLE; + } + else + { + (*WRPState) = OB_WRPSTATE_ENABLE; + } +} + +/** + * @brief Set the read protection level. + * + * @note To configure the RDP level, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * @note To validate the RDP level, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible + * to go back to level 1 or 0 !!! + * + * @param RDPLevel specifies the read protection level. + * This parameter can be one of the following values: + * @arg OB_RDP_LEVEL_0: No protection + * @arg OB_RDP_LEVEL_1: Read protection of the memory + * @arg OB_RDP_LEVEL_2: Full chip protection + * + * @retval HAL status + */ +static void FLASH_OB_RDPConfig(uint32_t RDPLevel) +{ + /* Check the parameters */ + assert_param(IS_OB_RDP_LEVEL(RDPLevel)); + + /* Configure the RDP level in the option bytes register */ + MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel); +} + +/** + * @brief Get the read protection level. + * @retval RDPLevel specifies the read protection level. + * This return value can be one of the following values: + * @arg OB_RDP_LEVEL_0: No protection + * @arg OB_RDP_LEVEL_1: Read protection of the memory + * @arg OB_RDP_LEVEL_2: Full chip protection + */ +static uint32_t FLASH_OB_GetRDP(void) +{ + uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP); + + if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2)) + { + return (OB_RDP_LEVEL_1); + } + else + { + return rdp_level; + } +} + +#if defined(DUAL_CORE) +/** + * @brief Program the FLASH User Option Byte. + * + * @note To configure the user option bytes, the option lock bit OPTLOCK must + * be cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @note To validate the user option bytes, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * + * @param UserType The FLASH User Option Bytes to be modified : + * a combination of @ref FLASHEx_OB_USER_Type + * + * @param UserConfig The FLASH User Option Bytes values: + * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), + * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), + * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24), + * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). + * + * @retval HAL status + */ +#else +/** + * @brief Program the FLASH User Option Byte. + * + * @note To configure the user option bytes, the option lock bit OPTLOCK must + * be cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @note To validate the user option bytes, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * + * @param UserType The FLASH User Option Bytes to be modified : + * a combination of @arg FLASHEx_OB_USER_Type + * + * @param UserConfig The FLASH User Option Bytes values: + * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), + * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), + * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). + * + * @retval HAL status + */ +#endif /*DUAL_CORE*/ +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig) +{ + uint32_t optr_reg_val = 0; + uint32_t optr_reg_mask = 0; + + /* Check the parameters */ + assert_param(IS_OB_USER_TYPE(UserType)); + + if((UserType & OB_USER_IWDG1_SW) != 0U) + { + /* IWDG_HW option byte should be modified */ + assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW)); + + /* Set value and mask for IWDG_HW option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW); + optr_reg_mask |= FLASH_OPTSR_IWDG1_SW; + } +#if defined(DUAL_CORE) + if((UserType & OB_USER_IWDG2_SW) != 0U) + { + /* IWDG2_SW option byte should be modified */ + assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW)); + + /* Set value and mask for IWDG2_SW option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW); + optr_reg_mask |= FLASH_OPTSR_IWDG2_SW; + } +#endif /*DUAL_CORE*/ + if((UserType & OB_USER_NRST_STOP_D1) != 0U) + { + /* NRST_STOP option byte should be modified */ + assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1)); + + /* Set value and mask for NRST_STOP option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1); + optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1; + } + + if((UserType & OB_USER_NRST_STDBY_D1) != 0U) + { + /* NRST_STDBY option byte should be modified */ + assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1)); + + /* Set value and mask for NRST_STDBY option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1); + optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1; + } + + if((UserType & OB_USER_IWDG_STOP) != 0U) + { + /* IWDG_STOP option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP)); + + /* Set value and mask for IWDG_STOP option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP); + optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP; + } + + if((UserType & OB_USER_IWDG_STDBY) != 0U) + { + /* IWDG_STDBY option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY)); + + /* Set value and mask for IWDG_STDBY option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY); + optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY; + } + + if((UserType & OB_USER_ST_RAM_SIZE) != 0U) + { + /* ST_RAM_SIZE option byte should be modified */ + assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE)); + + /* Set value and mask for ST_RAM_SIZE option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE); + optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE; + } + + if((UserType & OB_USER_SECURITY) != 0U) + { + /* SECURITY option byte should be modified */ + assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY)); + + /* Set value and mask for SECURITY option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY); + optr_reg_mask |= FLASH_OPTSR_SECURITY; + } + +#if defined(DUAL_CORE) + if((UserType & OB_USER_BCM4) != 0U) + { + /* BCM4 option byte should be modified */ + assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4)); + + /* Set value and mask for BCM4 option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4); + optr_reg_mask |= FLASH_OPTSR_BCM4; + } + + if((UserType & OB_USER_BCM7) != 0U) + { + /* BCM7 option byte should be modified */ + assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7)); + + /* Set value and mask for BCM7 option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7); + optr_reg_mask |= FLASH_OPTSR_BCM7; + } + + if((UserType & OB_USER_NRST_STOP_D2) != 0U) + { + /* NRST_STOP option byte should be modified */ + assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2)); + + /* Set value and mask for NRST_STOP option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2); + optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2; + } + + if((UserType & OB_USER_NRST_STDBY_D2) != 0U) + { + /* NRST_STDBY option byte should be modified */ + assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2)); + + /* Set value and mask for NRST_STDBY option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2); + optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2; + } +#endif /* DUAL_CORE */ + if((UserType & OB_USER_SWAP_BANK) != 0U) + { + /* SWAP_BANK_OPT option byte should be modified */ + assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT)); + + /* Set value and mask for SWAP_BANK_OPT option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT); + optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT; + } + + if((UserType & OB_USER_IOHSLV) != 0U) + { + /* IOHSLV_OPT option byte should be modified */ + assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV)); + + /* Set value and mask for IOHSLV_OPT option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV); + optr_reg_mask |= FLASH_OPTSR_IO_HSLV; + } + +#if defined (FLASH_OPTSR_VDDMMC_HSLV) + if((UserType & OB_USER_VDDMMC_HSLV) != 0U) + { + /* VDDMMC_HSLV option byte should be modified */ + assert_param(IS_OB_USER_VDDMMC_HSLV(UserConfig & FLASH_OPTSR_VDDMMC_HSLV)); + + /* Set value and mask for VDDMMC_HSLV option byte */ + optr_reg_val |= (UserConfig & FLASH_OPTSR_VDDMMC_HSLV); + optr_reg_mask |= FLASH_OPTSR_VDDMMC_HSLV; + } +#endif /* FLASH_OPTSR_VDDMMC_HSLV */ + + /* Configure the option bytes register */ + MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val); +} + +#if defined(DUAL_CORE) +/** + * @brief Return the FLASH User Option Byte value. + * @retval The FLASH User Option Bytes values + * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), + * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), + * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24), + * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). + */ +#else +/** + * @brief Return the FLASH User Option Byte value. + * @retval The FLASH User Option Bytes values + * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7), + * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]), + * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31). + */ +#endif /*DUAL_CORE*/ +static uint32_t FLASH_OB_GetUser(void) +{ + uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR); + userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP)); + + return userConfig; +} + +/** + * @brief Configure the Proprietary code readout protection of the desired addresses + * + * @note To configure the PCROP options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * @note To validate the PCROP options, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * + * @param PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not + * when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal + * This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration + * + * @param PCROPStartAddr specifies the start address of the Proprietary code readout protection + * This parameter can be an address between begin and end of the bank + * + * @param PCROPEndAddr specifies the end address of the Proprietary code readout protection + * This parameter can be an address between PCROPStartAddr and end of the bank + * + * @param Banks the specific bank to apply PCROP protection + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: PCROP on specified bank1 area + * @arg FLASH_BANK_2: PCROP on specified bank2 area + * @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks) + * + * @retval None + */ +static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + assert_param(IS_OB_PCROP_RDP(PCROPConfig)); + + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr)); + + /* Configure the Proprietary code readout protection */ + FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8) | \ + (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \ + PCROPConfig; + } + + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr)); + + /* Configure the Proprietary code readout protection */ + FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8) | \ + (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \ + PCROPConfig; + } +} + +/** + * @brief Get the Proprietary code readout protection configuration on a given Bank + * + * @param PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not + * when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal + * + * @param PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank + * + * @param PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank + * + * @param Bank the specific bank to apply PCROP protection + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: PCROP on specified bank1 area + * @arg FLASH_BANK_2: PCROP on specified bank2 area + * @arg FLASH_BANK_BOTH: is not allowed here + * + * @retval None + */ +static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank) +{ + uint32_t regvalue = 0; + uint32_t bankBase = 0; + + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) + { + regvalue = FLASH->PRAR_CUR1; + bankBase = FLASH_BANK1_BASE; + } + + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) + { + regvalue = FLASH->PRAR_CUR2; + bankBase = FLASH_BANK2_BASE; + } + + (*PCROPConfig) = (regvalue & FLASH_PRAR_DMEP); + + (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase; + (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos; + (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase; +} + +/** + * @brief Set the BOR Level. + * @param Level specifies the Option Bytes BOR Reset Level. + * This parameter can be one of the following values: + * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V + * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V + * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V + * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V + * @retval None + */ +static void FLASH_OB_BOR_LevelConfig(uint32_t Level) +{ + assert_param(IS_OB_BOR_LEVEL(Level)); + + /* Configure BOR_LEV option byte */ + MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level); +} + +/** + * @brief Get the BOR Level. + * @retval The Option Bytes BOR Reset Level. + * This parameter can be one of the following values: + * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V + * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V + * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V + * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V + */ +static uint32_t FLASH_OB_GetBOR(void) +{ + return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV); +} + +/** + * @brief Set Boot address + * @param BootOption Boot address option byte to be programmed, + * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION + (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH) + * + * @param BootAddress0 Specifies the Boot Address 0 + * @param BootAddress1 Specifies the Boot Address 1 + * @retval HAL Status + */ +static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1) +{ + /* Check the parameters */ + assert_param(IS_OB_BOOT_ADD_OPTION(BootOption)); + + if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0) + { + /* Check the parameters */ + assert_param(IS_BOOT_ADDRESS(BootAddress0)); + + /* Configure CM7 BOOT ADD0 */ +#if defined(DUAL_CORE) + MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16)); +#else /* Single Core*/ + MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16)); +#endif /* DUAL_CORE */ + } + + if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1) + { + /* Check the parameters */ + assert_param(IS_BOOT_ADDRESS(BootAddress1)); + + /* Configure CM7 BOOT ADD1 */ +#if defined(DUAL_CORE) + MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1); +#else /* Single Core*/ + MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1); +#endif /* DUAL_CORE */ + } +} + +/** + * @brief Get Boot address + * @param BootAddress0 Specifies the Boot Address 0. + * @param BootAddress1 Specifies the Boot Address 1. + * @retval HAL Status + */ +static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1) +{ + uint32_t regvalue; + +#if defined(DUAL_CORE) + regvalue = FLASH->BOOT7_CUR; + + (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16; + (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1); +#else /* Single Core */ + regvalue = FLASH->BOOT_CUR; + + (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16; + (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1); +#endif /* DUAL_CORE */ +} + +#if defined(DUAL_CORE) +/** + * @brief Set CM4 Boot address + * @param BootOption Boot address option byte to be programmed, + * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION + (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH) + * + * @param BootAddress0 Specifies the CM4 Boot Address 0. + * @param BootAddress1 Specifies the CM4 Boot Address 1. + * @retval HAL Status + */ +static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1) +{ + /* Check the parameters */ + assert_param(IS_OB_BOOT_ADD_OPTION(BootOption)); + + if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0) + { + /* Check the parameters */ + assert_param(IS_BOOT_ADDRESS(BootAddress0)); + + /* Configure CM4 BOOT ADD0 */ + MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16)); + + } + + if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1) + { + /* Check the parameters */ + assert_param(IS_BOOT_ADDRESS(BootAddress1)); + + /* Configure CM4 BOOT ADD1 */ + MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1); + } +} + +/** + * @brief Get CM4 Boot address + * @param BootAddress0 Specifies the CM4 Boot Address 0. + * @param BootAddress1 Specifies the CM4 Boot Address 1. + * @retval HAL Status + */ +static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1) +{ + uint32_t regvalue; + + regvalue = FLASH->BOOT4_CUR; + + (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16; + (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1); +} +#endif /*DUAL_CORE*/ + +/** + * @brief Set secure area configuration + * @param SecureAreaConfig specify if the secure area will be deleted or not + * when RDP level decreased from Level 1 to Level 0 or during a mass erase. + * + * @param SecureAreaStartAddr Specifies the secure area start address + * @param SecureAreaEndAddr Specifies the secure area end address + * @param Banks the specific bank to apply Security protection + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Secure area on specified bank1 area + * @arg FLASH_BANK_2: Secure area on specified bank2 area + * @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks) + * @retval None + */ +static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + assert_param(IS_OB_SECURE_RDP(SecureAreaConfig)); + + if((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr)); + + /* Configure the secure area */ + FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8) | \ + (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \ + (SecureAreaConfig & FLASH_SCAR_DMES); + } + + if((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr)); + + /* Configure the secure area */ + FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8) | \ + (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \ + (SecureAreaConfig & FLASH_SCAR_DMES); + } +} + +/** + * @brief Get secure area configuration + * @param SecureAreaConfig indicates if the secure area will be deleted or not + * when RDP level decreased from Level 1 to Level 0 or during a mass erase. + * @param SecureAreaStartAddr gives the secure area start address + * @param SecureAreaEndAddr gives the secure area end address + * @param Bank Specifies the Bank + * @retval None + */ +static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank) +{ + uint32_t regvalue = 0; + uint32_t bankBase = 0; + + /* Check Bank parameter value */ + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1) + { + regvalue = FLASH->SCAR_CUR1; + bankBase = FLASH_BANK1_BASE; + } + + if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2) + { + regvalue = FLASH->SCAR_CUR2; + bankBase = FLASH_BANK2_BASE; + } + + /* Get the secure area settings */ + (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES); + (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase; + (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos; + (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase; +} + +/** + * @brief Add a CRC sector to the list of sectors on which the CRC will be calculated + * @param Sector Specifies the CRC sector number + * @param Bank Specifies the Bank + * @retval None + */ +static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + + if (Bank == FLASH_BANK_1) + { + /* Clear CRC sector */ + FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT); + + /* Select CRC Sector and activate ADD_SECT bit */ + FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT; + } + else + { + /* Clear CRC sector */ + FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT); + + /* Select CRC Sector and activate ADD_SECT bit */ + FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT; + } +} + +/** + * @brief Select CRC start and end memory addresses on which the CRC will be calculated + * @param CRCStartAddr Specifies the CRC start address + * @param CRCEndAddr Specifies the CRC end address + * @param Bank Specifies the Bank + * @retval None + */ +static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank) +{ + if (Bank == FLASH_BANK_1) + { + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr)); + + /* Write CRC Start and End addresses */ + FLASH->CRCSADD1 = CRCStartAddr; + FLASH->CRCEADD1 = CRCEndAddr; + } + else + { + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr)); + assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr)); + + /* Write CRC Start and End addresses */ + FLASH->CRCSADD2 = CRCStartAddr; + FLASH->CRCEADD2 = CRCEndAddr; + } +} +/** + * @} + */ + +#if defined (FLASH_OTPBL_LOCKBL) +/** + * @brief Configure the OTP Block Lock. + * @param OTP_Block specifies the OTP Block to lock. + * This parameter can be a value of @ref FLASHEx_OTP_Blocks + * @retval None + */ +static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block) +{ + /* Check the parameters */ + assert_param(IS_OTP_BLOCK(OTP_Block)); + + /* Configure the OTP Block lock in the option bytes register */ + FLASH->OTPBL_PRG |= (OTP_Block & FLASH_OTPBL_LOCKBL); +} + +/** + * @brief Get the OTP Block Lock. + * @retval OTP_Block specifies the OTP Block to lock. + * This return value can be a value of @ref FLASHEx_OTP_Blocks + */ +static uint32_t FLASH_OB_OTP_GetLock(void) +{ + return (FLASH->OTPBL_CUR); +} +#endif /* FLASH_OTPBL_LOCKBL */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- cgit v1.2.3