| /** |
| ****************************************************************************** |
| * @file stm32wbxx_hal_flash_ex.c |
| * @author MCD Application Team |
| * @brief Extended FLASH HAL module driver. |
| * This file provides firmware functions to manage the following |
| * functionalities of the FLASH extended peripheral: |
| * + Extended programming operations functions |
| ****************************************************************************** |
| * @attention |
| * |
| * Copyright (c) 2019 STMicroelectronics. |
| * All rights reserved. |
| * |
| * This software is licensed under terms that can be found in the LICENSE file |
| * in the root directory of this software component. |
| * If no LICENSE file comes with this software, it is provided AS-IS. |
| * |
| ****************************************************************************** |
| @verbatim |
| ============================================================================== |
| ##### Flash Extended features ##### |
| ============================================================================== |
| |
| [..] Comparing to other previous devices, the FLASH interface for STM32WBxx |
| devices contains the following additional features |
| |
| (+) Capacity up to 1 Mbyte with single bank architecture supporting read-while-write |
| capability (RWW) |
| (+) Single bank memory organization |
| (+) PCROP protection |
| (+) WRP protection |
| (+) CPU2 Security area |
| (+) Program Erase Suspend feature |
| |
| ##### How to use this driver ##### |
| ============================================================================== |
| [..] This driver provides functions to configure and program the FLASH memory |
| of all STM32WBxx devices. It includes |
| (#) Flash Memory Erase functions: |
| (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and |
| HAL_FLASH_Lock() functions |
| (++) Erase function: Erase page, erase all sectors |
| (++) There are two modes of erase : |
| (+++) Polling Mode using HAL_FLASHEx_Erase() |
| (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() |
| |
| (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to : |
| (++) Set/Reset the write protection (per 4 KByte) |
| (++) Set the Read protection Level |
| (++) Program the user Option Bytes |
| (++) Configure the PCROP protection (per 2 KByte) |
| (++) Configure the IPCC Buffer start Address |
| (++) Configure the CPU2 boot region and reset vector start Address |
| (++) Configure the Flash and SRAM2 secure area |
| |
| (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to : |
| (++) Get the value of a write protection area |
| (++) Know if the read protection is activated |
| (++) Get the value of the user Option Bytes |
| (++) Get the value of a PCROP area |
| (++) Get the IPCC Buffer start Address |
| (++) Get the CPU2 boot region and reset vector start Address |
| (++) Get the Flash and SRAM2 secure area |
| |
| (#) Flash Suspend, Allow functions: |
| (++) Suspend or Allow new program or erase operation request using HAL_FLASHEx_SuspendOperation() and |
| HAL_FLASHEx_AllowOperation() functions |
| |
| (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck(). |
| and modify this setting (for flash loader purpose e.g.) using |
| HAL_FLASHEx_ForceFlashEmpty(). |
| |
| @endverbatim |
| ****************************************************************************** |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32wbxx_hal.h" |
| |
| /** @addtogroup STM32WBxx_HAL_Driver |
| * @{ |
| */ |
| |
| /** @defgroup FLASHEx FLASHEx |
| * @brief FLASH Extended HAL module driver |
| * @{ |
| */ |
| |
| #ifdef HAL_FLASH_MODULE_ENABLED |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /* Private define ------------------------------------------------------------*/ |
| /* Private macro -------------------------------------------------------------*/ |
| /* Private variables ---------------------------------------------------------*/ |
| /* Private function prototypes -----------------------------------------------*/ |
| /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions |
| * @{ |
| */ |
| static void FLASH_AcknowledgePageErase(void); |
| static void FLASH_FlushCaches(void); |
| static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset); |
| static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel); |
| static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, |
| uint32_t PCROP1AEndAddr); |
| static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr); |
| static void FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr); |
| static void FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam); |
| static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset); |
| static uint32_t FLASH_OB_GetRDP(void); |
| static uint32_t FLASH_OB_GetUser(void); |
| static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, |
| uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr); |
| static uint32_t FLASH_OB_GetIPCCBufferAddr(void); |
| static void FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr, |
| uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode); |
| static void FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion); |
| static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void); |
| /** |
| * @} |
| */ |
| |
| /* Exported functions -------------------------------------------------------*/ |
| /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions |
| * @{ |
| */ |
| |
| /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions |
| * @brief Extended IO operation functions |
| * |
| @verbatim |
| =============================================================================== |
| ##### Extended programming operation functions ##### |
| =============================================================================== |
| [..] |
| This subsection provides a set of functions allowing to manage the Extended FLASH |
| programming operations Operations. |
| |
| @endverbatim |
| * @{ |
| */ |
| /** |
| * @brief Perform an erase of the specified FLASH memory pages. |
| * @note Before any operation, it is possible to check there is no operation suspended |
| * by call HAL_FLASHEx_IsOperationSuspended() |
| * @param[in] pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that |
| * contains the configuration information for the erasing. |
| * @param[out] PageError Pointer to variable that contains the configuration |
| * information on faulty page in case of error (0xFFFFFFFF means that all |
| * the pages have been correctly erased) |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) |
| { |
| HAL_StatusTypeDef status; |
| uint32_t index; |
| |
| /* Check the parameters */ |
| assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); |
| |
| /* Process Locked */ |
| __HAL_LOCK(&pFlash); |
| |
| /* Reset error code */ |
| pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; |
| |
| /* Verify that next operation can be proceed */ |
| status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); |
| |
| if (status == HAL_OK) |
| { |
| if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGES) |
| { |
| /*Initialization of PageError variable*/ |
| *PageError = 0xFFFFFFFFU; |
| |
| for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++) |
| { |
| /* Start erase page */ |
| FLASH_PageErase(index); |
| |
| /* Wait for last operation to be completed */ |
| status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); |
| |
| if (status != HAL_OK) |
| { |
| /* In case of error, stop erase procedure and return the faulty address */ |
| *PageError = index; |
| break; |
| } |
| } |
| |
| /* If operation is completed or interrupted, disable the Page Erase Bit */ |
| FLASH_AcknowledgePageErase(); |
| } |
| |
| /* Flush the caches to be sure of the data consistency */ |
| FLASH_FlushCaches(); |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(&pFlash); |
| |
| return status; |
| } |
| |
| /** |
| * @brief Perform an erase of the specified FLASH memory pages with interrupt enabled. |
| * @note Before any operation, it is possible to check there is no operation suspended |
| * by call HAL_FLASHEx_IsOperationSuspended() |
| * @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that |
| * contains the configuration information for the erasing. |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Check the parameters */ |
| assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); |
| |
| /* Process Locked */ |
| __HAL_LOCK(&pFlash); |
| |
| /* Reset error code */ |
| pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; |
| |
| /* save procedure for interrupt treatment */ |
| pFlash.ProcedureOnGoing = pEraseInit->TypeErase; |
| |
| /* Verify that next operation can be proceed */ |
| status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); |
| |
| if (status != HAL_OK) |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(&pFlash); |
| } |
| else |
| { |
| /* Enable End of Operation and Error interrupts */ |
| __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR); |
| |
| if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGES) |
| { |
| /* Erase by page to be done */ |
| pFlash.NbPagesToErase = pEraseInit->NbPages; |
| pFlash.Page = pEraseInit->Page; |
| |
| /*Erase 1st page and wait for IT */ |
| FLASH_PageErase(pEraseInit->Page); |
| } |
| } |
| |
| /* return status */ |
| return status; |
| } |
| |
| /** |
| * @brief Program Option bytes. |
| * @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that |
| * contains the configuration information for the programming. |
| * @note To configure any option bytes, the option lock bit OPTLOCK must be |
| * cleared with the call of @ref HAL_FLASH_OB_Unlock() function. |
| * @note New option bytes configuration will be taken into account only |
| * - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch() |
| * - a Power On Reset |
| * - an exit from Standby or Shutdown mode. |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) |
| { |
| uint32_t optr; |
| HAL_StatusTypeDef status; |
| |
| /* Check the parameters */ |
| assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); |
| |
| /* Process Locked */ |
| __HAL_LOCK(&pFlash); |
| |
| pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; |
| |
| /* Write protection configuration */ |
| if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U) |
| { |
| /* Configure of Write protection on the selected area */ |
| FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset); |
| } |
| |
| /* Option register */ |
| if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER)) |
| { |
| /* Fully modify OPTR register with RDP & user data */ |
| FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, pOBInit->RDPLevel); |
| } |
| else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U) |
| { |
| /* Only modify RDP so get current user data */ |
| optr = FLASH_OB_GetUser(); |
| |
| /* Remove BOR LEVEL User Type*/ |
| optr &= ~OB_USER_BOR_LEV; |
| |
| FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel); |
| } |
| else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U) |
| { |
| /* Only modify user so get current RDP level */ |
| optr = FLASH_OB_GetRDP(); |
| FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, optr); |
| } |
| else |
| { |
| /* Do Nothing */ |
| } |
| |
| /* PCROP Configuration */ |
| if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U) |
| { |
| /* Check the parameters */ |
| assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig)); |
| |
| if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0U) |
| { |
| /* Configure the Zone 1A Proprietary code readout protection */ |
| FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr); |
| } |
| |
| if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0U) |
| { |
| /* Configure the Zone 1B Proprietary code readout protection */ |
| FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr); |
| } |
| } |
| |
| /* Secure mode and CPU2 Boot Vector */ |
| if ((pOBInit->OptionType & (OPTIONBYTE_SECURE_MODE | OPTIONBYTE_C2_BOOT_VECT)) != 0U) |
| { |
| /* Set the secure flash and SRAM memory start address */ |
| FLASH_OB_SecureConfig(pOBInit); |
| } |
| |
| /* IPCC mailbox data buffer address */ |
| if ((pOBInit->OptionType & OPTIONBYTE_IPCC_BUF_ADDR) != 0U) |
| { |
| /* Configure the IPCC data buffer address */ |
| FLASH_OB_IPCCBufferAddrConfig(pOBInit->IPCCdataBufAddr); |
| } |
| |
| /* Proceed the OB Write Operation */ |
| status = FLASH_OB_ProceedWriteOperation(); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(&pFlash); |
| |
| /* return status */ |
| return status; |
| } |
| |
| /** |
| * @brief Get the Option bytes configuration. |
| * @note warning: this API only read flash register, it does not reflect any |
| * change that would have been programmed between previous Option byte |
| * loading and current call. |
| * @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the |
| * configuration information. The fields pOBInit->WRPArea and |
| * pOBInit->PCROPConfig should indicate which area is requested |
| * for the WRP and PCROP. |
| * @retval None |
| */ |
| void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) |
| { |
| pOBInit->OptionType = OPTIONBYTE_ALL; |
| |
| if ((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB)) |
| { |
| /* Get write protection on the selected area */ |
| FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset)); |
| } |
| |
| /* Get Read protection level */ |
| pOBInit->RDPLevel = FLASH_OB_GetRDP(); |
| |
| /* Get the user option bytes */ |
| pOBInit->UserConfig = FLASH_OB_GetUser(); |
| pOBInit->UserType = OB_USER_ALL; |
| |
| /* Get the Zone 1A and 1B Proprietary code readout protection */ |
| FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr), |
| &(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr)); |
| pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B); |
| |
| /* Get the IPCC start Address */ |
| pOBInit->IPCCdataBufAddr = FLASH_OB_GetIPCCBufferAddr(); |
| |
| /* Get the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the Security Mode, */ |
| FLASH_OB_GetSecureMemoryConfig(&(pOBInit->SecureFlashStartAddr), &(pOBInit->SecureRAM2aStartAddr), |
| &(pOBInit->SecureRAM2bStartAddr), &(pOBInit->SecureMode)); |
| |
| /* Get the M0+ Secure Boot reset vector and Secure Boot memory selection */ |
| FLASH_OB_GetC2BootResetConfig(&(pOBInit->C2SecureBootVectAddr), &(pOBInit->C2BootRegion)); |
| } |
| |
| /** |
| * @brief Flash Empty check |
| * @note This API checks if first location in Flash is programmed or not. |
| * This check is done once by Option Byte Loader. |
| * @retval Returned value can be one of the following values: |
| * @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed |
| * @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty |
| */ |
| uint32_t HAL_FLASHEx_FlashEmptyCheck(void) |
| { |
| return (READ_BIT(FLASH->ACR, FLASH_ACR_EMPTY)); |
| } |
| |
| |
| /** |
| * @brief Force Empty check value. |
| * @note Allows to modify program empty check value in order to force this |
| * information in Flash Interface, for all next reset that do not launch |
| * Option Byte Loader. |
| * @param FlashEmpty Specifies the empty check value |
| * This parameter can be one of the following values: |
| * @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed |
| * @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty |
| * @retval None |
| */ |
| void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty) |
| { |
| assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty)); |
| |
| MODIFY_REG(FLASH->ACR, FLASH_ACR_EMPTY, FlashEmpty); |
| } |
| |
| /** |
| * @brief Suspend new program or erase operation request. |
| * @note Any new Flash program and erase operation on both CPU side will be suspended |
| * until this bit and the same bit in Flash CPU2 access control register (FLASH_C2ACR) are |
| * cleared. The PESD bit in both the Flash status register (FLASH_SR) and Flash |
| * CPU2 status register (FLASH_C2SR) register will be set when at least one PES |
| * bit in FLASH_ACR or FLASH_C2ACR is set. |
| * @retval None |
| */ |
| void HAL_FLASHEx_SuspendOperation(void) |
| { |
| SET_BIT(FLASH->ACR, FLASH_ACR_PES); |
| } |
| |
| /** |
| * @brief Allow new program or erase operation request. |
| * @note Any new Flash program and erase operation on both CPU side will be allowed |
| * until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is |
| * set. The PESD bit in both the Flash status register (FLASH_SR) and Flash |
| * CPU2 status register (FLASH_C2SR) register will be clear when both PES |
| * bit in FLASH_ACR or FLASH_C2ACR is cleared. |
| * @retval None |
| */ |
| void HAL_FLASHEx_AllowOperation(void) |
| { |
| CLEAR_BIT(FLASH->ACR, FLASH_ACR_PES); |
| } |
| |
| /** |
| * @brief Check if new program or erase operation request from CPU1 or CPU2 is suspended |
| * @note Any new Flash program and erase operation on both CPU side will be allowed |
| * until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is |
| * set. The PESD bit in both the Flash status register (FLASH_SR) and Flash |
| * CPU2 status register (FLASH_C2SR) register will be cleared when both PES |
| * bit in FLASH_ACR and FLASH_C2ACR are cleared. |
| * @retval Status |
| * - 0 : No suspended flash operation |
| * - 1 : Flash operation is suspended |
| */ |
| uint32_t HAL_FLASHEx_IsOperationSuspended(void) |
| { |
| uint32_t status = 0U; |
| |
| if (READ_BIT(FLASH->SR, FLASH_SR_PESD) == FLASH_SR_PESD) |
| { |
| status = 1U; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| /* Private functions ---------------------------------------------------------*/ |
| /** @addtogroup FLASHEx_Private_Functions |
| * @{ |
| */ |
| |
| /** |
| * @brief Erase the specified FLASH memory page. |
| * @param Page FLASH page to erase |
| * This parameter must be a value between 0 and (max number of pages in Flash - 1) |
| * @retval None |
| */ |
| void FLASH_PageErase(uint32_t Page) |
| { |
| /* Check the parameters */ |
| assert_param(IS_FLASH_PAGE(Page)); |
| |
| /* Proceed to erase the page */ |
| MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT)); |
| } |
| |
| /** |
| * @brief Flush the instruction and data caches. |
| * @retval None |
| */ |
| static void FLASH_FlushCaches(void) |
| { |
| /* Flush instruction cache */ |
| if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == FLASH_ACR_ICEN) |
| { |
| /* Disable instruction cache */ |
| __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
| /* Reset instruction cache */ |
| __HAL_FLASH_INSTRUCTION_CACHE_RESET(); |
| /* Enable instruction cache */ |
| __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
| } |
| |
| /* Flush data cache */ |
| if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == FLASH_ACR_DCEN) |
| { |
| /* Disable data cache */ |
| __HAL_FLASH_DATA_CACHE_DISABLE(); |
| /* Reset data cache */ |
| __HAL_FLASH_DATA_CACHE_RESET(); |
| /* Enable data cache */ |
| __HAL_FLASH_DATA_CACHE_ENABLE(); |
| } |
| } |
| |
| /** |
| * @brief Acknlowldge the page erase operation. |
| * @retval None |
| */ |
| static void FLASH_AcknowledgePageErase(void) |
| { |
| CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB)); |
| } |
| |
| /** |
| * @brief Configure the write protection of the desired pages. |
| * @note When WRP is active in a zone, it cannot be erased or programmed. |
| * Consequently, a software mass erase cannot be performed if one zone |
| * is write-protected. |
| * @note When the memory read protection level is selected (RDP level = 1), |
| * it is not possible to program or erase Flash memory if the CPU debug |
| * features are connected (JTAG or single wire) or boot code is being |
| * executed from RAM or System flash, even if WRP is not activated. |
| * @note To configure the WRP options, the option lock bit OPTLOCK must be |
| * cleared with the call of the @ref HAL_FLASH_OB_Unlock() function. |
| * @note To validate the WRP options, the option bytes must be reloaded |
| * through the call of the @ref HAL_FLASH_OB_Launch() function. |
| * @param WRPArea Specifies the area to be configured. |
| * This parameter can be one of the following values: |
| * @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A |
| * @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B |
| * @param WRPStartOffset Specifies the start page of the write protected area |
| * This parameter can be page number between 0 and (max number of pages in the Flash - 1) |
| * @param WRDPEndOffset Specifies the end page of the write protected area |
| * This parameter can be page number between WRPStartOffset and (max number of pages in the Flash - 1) |
| * @retval None |
| */ |
| static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset) |
| { |
| /* Check the parameters */ |
| assert_param(IS_OB_WRPAREA(WRPArea)); |
| assert_param(IS_FLASH_PAGE(WRPStartOffset)); |
| assert_param(IS_FLASH_PAGE(WRDPEndOffset)); |
| |
| /* Configure the write protected area */ |
| if (WRPArea == OB_WRPAREA_BANK1_AREAA) |
| { |
| MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END), |
| (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos))); |
| } |
| else /* OB_WRPAREA_BANK1_AREAB */ |
| { |
| MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END), |
| (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos))); |
| } |
| } |
| |
| /** |
| * @brief Set user & RDP configuration |
| * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible |
| * to go back to level 1 or 0 !!! |
| * @param UserType The FLASH User Option Bytes to be modified |
| * This parameter can be a combination of all the following values: |
| * @arg @ref OB_USER_BOR_LEV or @ref OB_USER_nRST_STOP or @ref OB_USER_nRST_STDBY or |
| * @arg @ref OB_USER_nRST_SHDW or @ref OB_USER_IWDG_SW or @ref OB_USER_IWDG_STOP or |
| * @arg @ref OB_USER_IWDG_STDBY or @ref OB_USER_WWDG_SW or @ref OB_USER_nBOOT1 or |
| * @arg @ref OB_USER_SRAM2PE or @ref OB_USER_SRAM2RST or @ref OB_USER_nSWBOOT0 or |
| * @arg @ref OB_USER_nBOOT0 or @ref OB_USER_AGC_TRIM or @ref OB_USER_ALL |
| * @param UserConfig The FLASH User Option Bytes values. |
| * This parameter can be a combination of all the following values: |
| * @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4 |
| * @arg @ref OB_STOP_RST or @ref OB_STOP_NORST |
| * @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST |
| * @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST |
| * @arg @ref OB_IRH_ENABLE or @ref OB_IRH_DISABLE (*) |
| * @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW |
| * @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN |
| * @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN |
| * @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW |
| * @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM |
| * @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE |
| * @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE |
| * @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN |
| * @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET |
| * @arg @ref OB_RESET_MODE_INPUT_ONLY or @ref OB_RESET_MODE_GPIO or @ref OB_RESET_MODE_INPUT_OUTPUT (*) |
| * @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7 |
| * @param RDPLevel: specifies the read protection level. |
| * This parameter can be one of the following values: |
| * @arg @ref OB_RDP_LEVEL_0 No protection |
| * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory |
| * @arg @ref OB_RDP_LEVEL_2 Full chip protection |
| * @retval None |
| */ |
| static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel) |
| { |
| uint32_t optr; |
| |
| /* Check the parameters */ |
| assert_param(IS_OB_USER_TYPE(UserType)); |
| assert_param(IS_OB_USER_CONFIG(UserType, UserConfig)); |
| assert_param(IS_OB_RDP_LEVEL(RDPLevel)); |
| |
| /* Configure the RDP level in the option bytes register */ |
| optr = FLASH->OPTR; |
| optr &= ~(UserType | FLASH_OPTR_RDP); |
| FLASH->OPTR = (optr | UserConfig | RDPLevel); |
| } |
| |
| /** |
| * @brief Configure the Zone 1A Proprietary code readout protection of the desired addresses, |
| * and erase configuration on RDP regression. |
| * @note To configure the PCROP options, the option lock bit OPTLOCK must be |
| * cleared with the call of the @ref HAL_FLASH_OB_Unlock() function. |
| * @note To validate the PCROP options, the option bytes must be reloaded |
| * through the call of the @ref HAL_FLASH_OB_Launch() function. |
| * @param PCROPConfig: specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE) |
| * on RDP level 1 regression. |
| * @param PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection |
| * This parameter can be an address between begin and end of the flash |
| * @param PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection |
| * This parameter can be an address between PCROP1AStartAddr and end of the flash |
| * @retval None |
| */ |
| static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr) |
| { |
| uint32_t startoffset; |
| uint32_t endoffset; |
| uint32_t pcrop1aend; |
| |
| /* Check the parameters */ |
| assert_param(IS_OB_PCROP_CONFIG(PCROPConfig)); |
| assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AStartAddr)); |
| assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AEndAddr)); |
| |
| /* get pcrop 1A end register */ |
| pcrop1aend = FLASH->PCROP1AER; |
| |
| /* Configure the Proprietary code readout protection offset */ |
| if ((PCROPConfig & OB_PCROP_ZONE_A) != 0U) |
| { |
| /* Compute offset depending on pcrop granularity */ |
| startoffset = ((PCROP1AStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */ |
| endoffset = ((PCROP1AEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */ |
| |
| /* Set Zone A start offset */ |
| WRITE_REG(FLASH->PCROP1ASR, startoffset); |
| |
| /* Set Zone A end offset */ |
| pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END; |
| pcrop1aend |= endoffset; |
| } |
| |
| /* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */ |
| if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0U) |
| { |
| pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP; |
| } |
| |
| /* set 1A End register */ |
| WRITE_REG(FLASH->PCROP1AER, pcrop1aend); |
| } |
| |
| /** |
| * @brief Configure the Zone 1B 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 @ref HAL_FLASH_OB_Unlock() function. |
| * @note To validate the PCROP options, the option bytes must be reloaded |
| * through the call of the @ref HAL_FLASH_OB_Launch() function. |
| * @param PCROP1BStartAddr Specifies the Zone 1BStart address of the Proprietary code readout protection |
| * This parameter can be an address between begin and end of the flash |
| * @param PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection |
| * This parameter can be an address between PCROP1BStartAddr and end of the flash |
| * @retval None |
| */ |
| static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr) |
| { |
| uint32_t startoffset; |
| uint32_t endoffset; |
| |
| /* Check the parameters */ |
| assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BStartAddr)); |
| assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BEndAddr)); |
| |
| /* Compute offset depending on pcrop granularity */ |
| startoffset = ((PCROP1BStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */ |
| endoffset = ((PCROP1BEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */ |
| |
| /* Configure the Proprietary code readout protection start address */ |
| WRITE_REG(FLASH->PCROP1BSR, startoffset); |
| |
| /* Configure the Proprietary code readout protection end address */ |
| WRITE_REG(FLASH->PCROP1BER, endoffset); |
| } |
| |
| /** |
| * @brief Program the FLASH IPCC data buffer address. |
| * @note To configure the extra user option bytes, the option lock bit OPTLOCK must |
| * be cleared with the call of the @ref HAL_FLASH_OB_Unlock() function. |
| * @note To validate the extra user option bytes, the option bytes must be reloaded |
| * through the call of the @ref HAL_FLASH_OB_Launch() function. |
| * @param IPCCDataBufAddr IPCC data buffer start address area in SRAM2 |
| * This parameter must be the double-word aligned |
| * @retval None |
| */ |
| static void FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr) |
| { |
| assert_param(IS_OB_IPCC_BUF_ADDR(IPCCDataBufAddr)); |
| |
| /* Configure the option bytes register */ |
| WRITE_REG(FLASH->IPCCBR, (uint32_t)((IPCCDataBufAddr - SRAM2A_BASE) >> 4)); |
| } |
| |
| /** |
| * @brief Configure the secure start address of the different memories (FLASH and SRAM2), |
| * the secure mode and the CPU2 Secure Boot reset vector |
| * @note To configure the PCROP options, the option lock bit OPTLOCK must be |
| * cleared with the call of the @ref HAL_FLASH_OB_Unlock() function. |
| * @param pOBParam Pointer to an @ref FLASH_OBProgramInitTypeDef structure that |
| * contains the configuration information for the programming |
| * @retval void |
| */ |
| static void FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam) |
| { |
| uint32_t sfr_reg_val = READ_REG(FLASH->SFR); |
| uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR); |
| |
| if ((pOBParam->OptionType & OPTIONBYTE_SECURE_MODE) != 0U) |
| { |
| assert_param(IS_OB_SFSA_START_ADDR(pOBParam->SecureFlashStartAddr)); |
| assert_param(IS_OB_SBRSA_START_ADDR(pOBParam->SecureRAM2aStartAddr)); |
| assert_param(IS_OB_SNBRSA_START_ADDR(pOBParam->SecureRAM2bStartAddr)); |
| assert_param(IS_OB_SECURE_MODE(pOBParam->SecureMode)); |
| |
| /* Configure SFR register content with start PAGE index to secure */ |
| MODIFY_REG(sfr_reg_val, FLASH_SFR_SFSA, (((pOBParam->SecureFlashStartAddr - FLASH_BASE) / FLASH_PAGE_SIZE) << FLASH_SFR_SFSA_Pos)); |
| |
| /* Configure SRRVR register */ |
| #if defined(FLASH_SRRVR_SBRSA_A) |
| MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA_A | FLASH_SRRVR_SBRSA_B), \ |
| (((((pOBParam->SecureRAM2aStartAddr - SRAM2A_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_A_Pos)) | \ |
| ((((pOBParam->SecureRAM2bStartAddr - SRAM2B_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_B_Pos)))); |
| #else |
| MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA | FLASH_SRRVR_SNBRSA), \ |
| (((((pOBParam->SecureRAM2aStartAddr - SRAM2A_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_Pos)) | \ |
| ((((pOBParam->SecureRAM2bStartAddr - SRAM2B_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SNBRSA_Pos)))); |
| #endif /* FLASH_SRRVR_SBRSA_A */ |
| |
| /* If Full System Secure mode is requested, clear all the corresponding bit */ |
| /* Else set the corresponding bit */ |
| if (pOBParam->SecureMode == SYSTEM_IN_SECURE_MODE) |
| { |
| CLEAR_BIT(sfr_reg_val, FLASH_SFR_FSD); |
| #if defined(FLASH_SRRVR_BRSD_A) |
| CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD_A | FLASH_SRRVR_BRSD_B)); |
| #else |
| CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD)); |
| #endif /* FLASH_SRRVR_BRSD_A */ |
| } |
| else |
| { |
| SET_BIT(sfr_reg_val, FLASH_SFR_FSD); |
| #if defined(FLASH_SRRVR_BRSD_A) |
| SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD_A | FLASH_SRRVR_BRSD_B)); |
| #else |
| SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD)); |
| #endif /* FLASH_SRRVR_BRSD_A */ |
| } |
| |
| /* Update Flash registers */ |
| WRITE_REG(FLASH->SFR, sfr_reg_val); |
| } |
| |
| /* Boot vector */ |
| if ((pOBParam->OptionType & OPTIONBYTE_C2_BOOT_VECT) != 0U) |
| { |
| /* Check the parameters */ |
| assert_param(IS_OB_BOOT_VECTOR_ADDR(pOBParam->C2SecureBootVectAddr)); |
| assert_param(IS_OB_BOOT_REGION(pOBParam->C2BootRegion)); |
| |
| /* Set the boot vector */ |
| if (pOBParam->C2BootRegion == OB_C2_BOOT_FROM_FLASH) |
| { |
| MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), |
| (((pOBParam->C2SecureBootVectAddr - FLASH_BASE) >> 2) | pOBParam->C2BootRegion)); |
| } |
| else |
| { |
| MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), |
| (((pOBParam->C2SecureBootVectAddr - SRAM1_BASE) >> 2) | pOBParam->C2BootRegion)); |
| } |
| } |
| |
| /* Update Flash registers */ |
| WRITE_REG(FLASH->SRRVR, srrvr_reg_val); |
| } |
| |
| /** |
| * @brief Return the FLASH Write Protection Option Bytes value. |
| * @param[in] WRPArea Specifies the area to be returned. |
| * This parameter can be one of the following values: |
| * @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A |
| * @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B |
| * @param[out] WRPStartOffset Specifies the address where to copied the start page |
| * of the write protected area |
| * @param[out] WRDPEndOffset Specifies the address where to copied the end page of |
| * the write protected area |
| * @retval None |
| */ |
| static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset) |
| { |
| /* Check the parameters */ |
| assert_param(IS_OB_WRPAREA(WRPArea)); |
| |
| /* Get the configuration of the write protected area */ |
| if (WRPArea == OB_WRPAREA_BANK1_AREAA) |
| { |
| *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT); |
| *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos); |
| } |
| else /* OB_WRPAREA_BANK1_AREAB */ |
| { |
| *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT); |
| *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos); |
| } |
| } |
| |
| /** |
| * @brief Return the FLASH Read Protection level. |
| * @retval FLASH ReadOut Protection Status: |
| * This return value can be one of the following values: |
| * @arg @ref OB_RDP_LEVEL_0 No protection |
| * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory |
| * @arg @ref OB_RDP_LEVEL_2 Full chip protection |
| */ |
| static uint32_t FLASH_OB_GetRDP(void) |
| { |
| uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP); |
| |
| if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2)) |
| { |
| return (OB_RDP_LEVEL_1); |
| } |
| else |
| { |
| return rdplvl; |
| } |
| } |
| |
| /** |
| * @brief Return the FLASH User Option Byte value. |
| * @retval This return value can be a combination of all the following values: |
| * @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4 |
| * @arg @ref OB_STOP_RST or @ref OB_STOP_RST |
| * @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST |
| * @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST |
| * @arg @ref OB_IRH_ENABLE or @ref OB_IRH_DISABLE (*) |
| * @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW |
| * @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN |
| * @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN |
| * @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW |
| * @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM |
| * @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE |
| * @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE |
| * @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN |
| * @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET |
| * @arg @ref OB_RESET_MODE_INPUT_ONLY or @ref OB_RESET_MODE_GPIO or @ref OB_RESET_MODE_INPUT_OUTPUT (*) |
| * @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7 |
| */ |
| static uint32_t FLASH_OB_GetUser(void) |
| { |
| uint32_t user_config = (READ_REG(FLASH->OPTR) & OB_USER_ALL); |
| CLEAR_BIT(user_config, (FLASH_OPTR_RDP | FLASH_OPTR_ESE)); |
| |
| return user_config; |
| } |
| |
| /** |
| * @brief Return the FLASH Write Protection Option Bytes value. |
| * @param PCROPConfig [out] Specifies the address where to copied the configuration of PCROP_RDP option |
| * @param PCROP1AStartAddr [out] Specifies the address where to copied the start address |
| * of the Zone 1A Proprietary code readout protection |
| * @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of |
| * the Zone 1A Proprietary code readout protection |
| * @param PCROP1BStartAddr [out] Specifies the address where to copied the start address |
| * of the Zone 1B Proprietary code readout protection |
| * @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of |
| * the Zone 1B Proprietary code readout protection |
| * @retval None |
| */ |
| static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, |
| uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr) |
| { |
| uint32_t pcrop; |
| |
| pcrop = (READ_BIT(FLASH->PCROP1BSR, FLASH_PCROP1BSR_PCROP1B_STRT)); |
| *PCROP1BStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE); |
| |
| pcrop = (READ_BIT(FLASH->PCROP1BER, FLASH_PCROP1BER_PCROP1B_END)); |
| *PCROP1BEndAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE); |
| |
| pcrop = (READ_BIT(FLASH->PCROP1ASR, FLASH_PCROP1ASR_PCROP1A_STRT)); |
| *PCROP1AStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE); |
| |
| pcrop = (READ_BIT(FLASH->PCROP1AER, FLASH_PCROP1AER_PCROP1A_END)); |
| *PCROP1AEndAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE); |
| |
| *PCROPConfig = (READ_REG(FLASH->PCROP1AER) & FLASH_PCROP1AER_PCROP_RDP); |
| } |
| |
| /** |
| * @brief Return the FLASH IPCC data buffer base address Option Byte value. |
| * @retval Returned value is the IPCC data buffer start address area in SRAM2. |
| */ |
| static uint32_t FLASH_OB_GetIPCCBufferAddr(void) |
| { |
| return (uint32_t)((READ_BIT(FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA) << 4) + SRAM2A_BASE); |
| } |
| |
| /** |
| * @brief Return the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the SecureMode |
| * @param SecureFlashStartAddr Specifies the address where to copied the Secure Flash start address |
| * @param SecureRAM2aStartAddr Specifies the address where to copied the Secure Backup RAM2a start address |
| * @param SecureRAM2bStartAddr Specifies the address where to copied the Secure non-Backup RAM2b start address |
| * @param SecureMode Specifies the address where to copied the Secure Mode. |
| * This return value can be one of the following values: |
| * @arg @ref SYSTEM_IN_SECURE_MODE : Security enabled |
| * @arg @ref SYSTEM_NOT_IN_SECURE_MODE : Security disabled |
| * @retval None |
| */ |
| static void FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr, |
| uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode) |
| { |
| uint32_t sfr_reg_val = READ_REG(FLASH->SFR); |
| uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR); |
| |
| /* Get Secure Flash start address */ |
| uint32_t user_config = (READ_BIT(sfr_reg_val, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos); |
| |
| *SecureFlashStartAddr = ((user_config * FLASH_PAGE_SIZE) + FLASH_BASE); |
| |
| /* Get Secure SRAM2a start address */ |
| #if defined(FLASH_SRRVR_SBRSA_A) |
| user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA_A) >> FLASH_SRRVR_SBRSA_A_Pos); |
| #else |
| user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA) >> FLASH_SRRVR_SBRSA_Pos); |
| #endif /* FLASH_SRRVR_SBRSA_A */ |
| |
| *SecureRAM2aStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2A_BASE); |
| |
| /* Get Secure SRAM2b start address */ |
| #if defined(FLASH_SRRVR_SBRSA_B) |
| user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA_B) >> FLASH_SRRVR_SBRSA_B_Pos); |
| #else |
| user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SNBRSA) >> FLASH_SRRVR_SNBRSA_Pos); |
| #endif /* FLASH_SRRVR_SBRSA_B */ |
| |
| *SecureRAM2bStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2B_BASE); |
| |
| /* Get Secure Area mode */ |
| *SecureMode = (READ_BIT(FLASH->OPTR, FLASH_OPTR_ESE)); |
| } |
| |
| /** |
| * @brief Return the CPU2 Secure Boot reset vector address and the CPU2 Secure Boot Region |
| * @param C2BootResetVectAddr Specifies the address where to copied the CPU2 Secure Boot reset vector address |
| * @param C2BootResetRegion Specifies the Secure Boot reset memory region |
| * @retval None |
| */ |
| static void FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion) |
| { |
| *C2BootResetRegion = (READ_BIT(FLASH->SRRVR, FLASH_SRRVR_C2OPT)); |
| |
| if (*C2BootResetRegion == OB_C2_BOOT_FROM_FLASH) |
| { |
| *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + FLASH_BASE); |
| } |
| else |
| { |
| *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + SRAM1_BASE); |
| } |
| } |
| |
| /** |
| * @brief Proceed the OB Write Operation. |
| * @retval HAL Status |
| */ |
| static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Verify that next operation can be proceed */ |
| status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); |
| |
| if (status == HAL_OK) |
| { |
| /* Set OPTSTRT Bit */ |
| SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT); |
| |
| /* Wait for last operation to be completed */ |
| status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* HAL_FLASH_MODULE_ENABLED */ |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |