d38bd4ae27
Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
1305 lines
48 KiB
C
1305 lines
48 KiB
C
/**
|
|
******************************************************************************
|
|
* @file stm32g0xx_hal_flash_ex.c
|
|
* @author MCD Application Team
|
|
* @brief Extended FLASH HAL module driver.
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities of the FLASH extended peripheral:
|
|
* + Extended programming operations functions
|
|
*
|
|
@verbatim
|
|
==============================================================================
|
|
##### Flash Extended features #####
|
|
==============================================================================
|
|
|
|
[..] Comparing to other previous devices, the FLASH interface for STM32G0xx
|
|
devices contains the following additional features
|
|
|
|
(+) Capacity up to 128 Kbytes with single bank architecture supporting read-while-write
|
|
capability (RWW)
|
|
(+) Single bank memory organization
|
|
(+) PCROP protection
|
|
|
|
##### How to use this driver #####
|
|
==============================================================================
|
|
[..] This driver provides functions to configure and program the FLASH memory
|
|
of all STM32G0xx devices. It includes
|
|
(#) Flash Memory Erase functions:
|
|
(++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
|
|
HAL_FLASH_Lock() functions
|
|
(++) Erase function: Erase page, erase all sectors
|
|
(++) There are two modes of erase :
|
|
(+++) Polling Mode using HAL_FLASHEx_Erase()
|
|
(+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
|
|
|
|
(#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
|
|
(++) Set/Reset the write protection
|
|
(++) Set the Read protection Level
|
|
(++) Program the user Option Bytes
|
|
(++) Configure the PCROP protection
|
|
(++) Set Securable memory area and boot entry point
|
|
|
|
(#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
|
|
(++) Get the value of a write protection area
|
|
(++) Know if the read protection is activated
|
|
(++) Get the value of the user Option Bytes
|
|
(++) Get Securable memory area and boot entry point information
|
|
|
|
(#) Enable or disable debugger usage using HAL_FLASHEx_EnableDebugger and
|
|
HAL_FLASHEx_DisableDebugger.
|
|
|
|
(#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck.
|
|
and modify this setting (for flash loader purpose e.g.) using
|
|
HAL_FLASHEx_ForceFlashEmpty.
|
|
|
|
(#) Enable securable memory area protectionusing HAL_FLASHEx_EnableSecMemProtection
|
|
|
|
@endverbatim
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2018 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* 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 "stm32g0xx_hal.h"
|
|
|
|
/** @addtogroup STM32G0xx_HAL_Driver
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup FLASHEx FLASHEx
|
|
* @brief FLASH Extended HAL module driver
|
|
* @{
|
|
*/
|
|
|
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
|
|
* @{
|
|
*/
|
|
static void FLASH_MassErase(uint32_t Banks);
|
|
void FLASH_FlushCaches(void);
|
|
static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
|
|
static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
|
|
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
|
|
static uint32_t FLASH_OB_GetRDP(void);
|
|
static uint32_t FLASH_OB_GetUser(void);
|
|
#if defined(FLASH_PCROP_SUPPORT)
|
|
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_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr);
|
|
static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
static void FLASH_OB_PCROP2AConfig(uint32_t PCROP2AStartAddr, uint32_t PCROP2AEndAddr);
|
|
static void FLASH_OB_PCROP2BConfig(uint32_t PCROP2BStartAddr, uint32_t PCROP2BEndAddr);
|
|
static void FLASH_OB_GetPCROP2A(uint32_t *PCROP2AStartAddr, uint32_t *PCROP2AEndAddr);
|
|
static void FLASH_OB_GetPCROP2B(uint32_t *PCROP2BStartAddr, uint32_t *PCROP2BEndAddr);
|
|
#endif
|
|
#endif
|
|
#if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize, uint32_t SecSize2);
|
|
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize, uint32_t *SecSize2);
|
|
#else
|
|
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize);
|
|
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize);
|
|
#endif
|
|
#endif
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* Exported functions -------------------------------------------------------*/
|
|
/** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
|
|
* @brief Extended IO operation functions
|
|
*
|
|
@verbatim
|
|
===============================================================================
|
|
##### Extended programming operation functions #####
|
|
===============================================================================
|
|
[..]
|
|
This subsection provides a set of functions allowing to manage the Extended FLASH
|
|
programming operations Operations.
|
|
|
|
@endverbatim
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Perform a mass erase or erase the specified FLASH memory pages.
|
|
* @param[in] pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
|
|
* contains the configuration information for the erasing.
|
|
* @param[out] PageError Pointer to variable that contains the configuration
|
|
* information on faulty page in case of error (0xFFFFFFFF means that all
|
|
* the pages have been correctly erased)
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
|
|
{
|
|
HAL_StatusTypeDef status;
|
|
uint32_t index;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
|
|
|
/* Process Locked */
|
|
__HAL_LOCK(&pFlash);
|
|
|
|
/* Reset error code */
|
|
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status == HAL_OK)
|
|
{
|
|
#if !defined(FLASH_DBANK_SUPPORT)
|
|
/* For single bank product force Banks to Bank 1 */
|
|
pEraseInit->Banks = FLASH_BANK_1;
|
|
#endif
|
|
|
|
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
|
|
{
|
|
/* Proceed to Mass Erase */
|
|
FLASH_MassErase(pEraseInit->Banks);
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
}
|
|
else
|
|
{
|
|
/*Initialization of PageError variable*/
|
|
*PageError = 0xFFFFFFFFU;
|
|
|
|
for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
|
|
{
|
|
/* Start erase page */
|
|
FLASH_PageErase(pEraseInit->Banks, index);
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status != HAL_OK)
|
|
{
|
|
/* In case of error, stop erase procedure and return the faulty address */
|
|
*PageError = index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* If operation is completed or interrupted, disable the Page Erase Bit */
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
|
|
}
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
/* return status */
|
|
return status;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
|
|
* @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
|
|
* contains the configuration information for the erasing.
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
|
|
{
|
|
HAL_StatusTypeDef status;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
|
|
|
/* Process Locked */
|
|
__HAL_LOCK(&pFlash);
|
|
|
|
/* Reset error code */
|
|
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
|
|
/* save procedure for interrupt treatment */
|
|
pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status != HAL_OK)
|
|
{
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
}
|
|
else
|
|
{
|
|
#if !defined(FLASH_DBANK_SUPPORT)
|
|
/* For single bank product force Banks to Bank 1 */
|
|
pEraseInit->Banks = FLASH_BANK_1;
|
|
#endif
|
|
/* Store Bank number */
|
|
pFlash.Banks = pEraseInit->Banks;
|
|
|
|
/* Enable End of Operation and Error interrupts */
|
|
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
|
|
|
|
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
|
|
{
|
|
/* Set Page to 0 for Interrupt callback management */
|
|
pFlash.Page = 0;
|
|
|
|
/* Proceed to Mass Erase */
|
|
FLASH_MassErase(pEraseInit->Banks);
|
|
}
|
|
else
|
|
{
|
|
/* Erase by page to be done */
|
|
pFlash.NbPagesToErase = pEraseInit->NbPages;
|
|
pFlash.Page = pEraseInit->Page;
|
|
|
|
/*Erase 1st page and wait for IT */
|
|
FLASH_PageErase(pEraseInit->Banks, pEraseInit->Page);
|
|
}
|
|
}
|
|
|
|
/* return status */
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Program Option bytes.
|
|
* @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
|
|
* contains the configuration information for the programming.
|
|
* @note To configure any option bytes, the option lock bit OPTLOCK must be
|
|
* cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
|
|
* @note New option bytes configuration will be taken into account only
|
|
* - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
|
|
* - a Power On Reset
|
|
* - an exit from Standby or Shutdown mode.
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
|
|
{
|
|
uint32_t optr;
|
|
HAL_StatusTypeDef status;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
|
|
|
|
/* Process Locked */
|
|
__HAL_LOCK(&pFlash);
|
|
|
|
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
|
|
/* Write protection configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0x00U)
|
|
{
|
|
/* Configure of Write protection on the selected area */
|
|
FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
|
|
}
|
|
|
|
/* Option register */
|
|
if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
|
|
{
|
|
/* Fully modify OPTR register with RDP & user data */
|
|
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
|
|
}
|
|
else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
|
|
{
|
|
/* Only modify RDP so get current user data */
|
|
optr = FLASH_OB_GetUser();
|
|
FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
|
|
}
|
|
else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
|
|
{
|
|
/* Only modify user so get current RDP level */
|
|
optr = FLASH_OB_GetRDP();
|
|
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
|
|
}
|
|
else
|
|
{
|
|
/* nothing to do */
|
|
}
|
|
|
|
#if defined(FLASH_PCROP_SUPPORT)
|
|
/* PCROP Configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0x00U)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));
|
|
|
|
if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0x00U)
|
|
{
|
|
/* Configure the 1A Proprietary code readout protection */
|
|
FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
|
|
}
|
|
|
|
if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0x00U)
|
|
{
|
|
/* Configure the 1B Proprietary code readout protection */
|
|
FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
|
|
}
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
if ((pOBInit->PCROPConfig & OB_PCROP_ZONE2_A) != 0x00U)
|
|
{
|
|
/* Configure the 2A Proprietary code readout protection */
|
|
FLASH_OB_PCROP2AConfig(pOBInit->PCROP2AStartAddr, pOBInit->PCROP2AEndAddr);
|
|
}
|
|
|
|
if ((pOBInit->PCROPConfig & OB_PCROP_ZONE2_B) != 0x00U)
|
|
{
|
|
/* Configure the 2B Proprietary code readout protection */
|
|
FLASH_OB_PCROP2BConfig(pOBInit->PCROP2BStartAddr, pOBInit->PCROP2BEndAddr);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
|
|
/* Securable Memory Area Configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_SEC) != 0x00U)
|
|
{
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Configure the securable memory area protection */
|
|
FLASH_OB_SecMemConfig(pOBInit->BootEntryPoint, pOBInit->SecSize, pOBInit->SecSize2);
|
|
#else
|
|
/* Configure the securable memory area protection */
|
|
FLASH_OB_SecMemConfig(pOBInit->BootEntryPoint, pOBInit->SecSize);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status == HAL_OK)
|
|
{
|
|
/* Set OPTSTRT Bit */
|
|
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
/* return status */
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the Option bytes configuration.
|
|
* @note warning: this API only read flash register, it does not reflect any
|
|
* change that would have been programmed between previous Option byte
|
|
* loading and current call.
|
|
* @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
|
|
* configuration information. The fields pOBInit->WRPArea should
|
|
* indicate which area is requested for the WRP.
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
|
|
{
|
|
pOBInit->OptionType = OPTIONBYTE_ALL;
|
|
|
|
/* Get write protection on the selected area */
|
|
FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
|
|
|
|
/* Get Read protection level */
|
|
pOBInit->RDPLevel = FLASH_OB_GetRDP();
|
|
|
|
/* Get the user option bytes */
|
|
pOBInit->USERConfig = FLASH_OB_GetUser();
|
|
pOBInit->USERType = OB_USER_ALL;
|
|
|
|
#if defined(FLASH_PCROP_SUPPORT)
|
|
/* Get the Proprietary code readout protection */
|
|
FLASH_OB_GetPCROP1A(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr));
|
|
FLASH_OB_GetPCROP1B(&(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
|
|
pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
FLASH_OB_GetPCROP2A(&(pOBInit->PCROP2AStartAddr), &(pOBInit->PCROP2AEndAddr));
|
|
FLASH_OB_GetPCROP2B(&(pOBInit->PCROP2BStartAddr), &(pOBInit->PCROP2BEndAddr));
|
|
pOBInit->PCROPConfig |= (OB_PCROP_ZONE2_A | OB_PCROP_ZONE2_B);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Get the Securable Memory Area protection */
|
|
FLASH_OB_GetSecMem(&(pOBInit->BootEntryPoint), &(pOBInit->SecSize), &(pOBInit->SecSize2));
|
|
#else
|
|
/* Get the Securable Memory Area protection */
|
|
FLASH_OB_GetSecMem(&(pOBInit->BootEntryPoint), &(pOBInit->SecSize));
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
#if defined(FLASH_ACR_DBG_SWEN)
|
|
/**
|
|
* @brief Enable Debugger.
|
|
* @note After calling this API, flash interface allow debugger intrusion.
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_EnableDebugger(void)
|
|
{
|
|
FLASH->ACR |= FLASH_ACR_DBG_SWEN;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Disable Debugger.
|
|
* @note After calling this API, Debugger is disabled: it is no more possible to
|
|
* break, see CPU register, etc...
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_DisableDebugger(void)
|
|
{
|
|
FLASH->ACR &= ~FLASH_ACR_DBG_SWEN;
|
|
}
|
|
#endif /* FLASH_ACR_DBG_SWEN */
|
|
|
|
/**
|
|
* @brief Flash Empty check
|
|
* @note This API checks if first location in Flash is programmed or not.
|
|
* This check is done once by Option Byte Loader.
|
|
* @retval 0 if 1st location is not programmed else
|
|
*/
|
|
uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
|
|
{
|
|
return ((FLASH->ACR & FLASH_ACR_PROGEMPTY));
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Force Empty check value.
|
|
* @note Allows to modify program empty check value in order to force this
|
|
* infrmation in Flash Interface, for all next reset that do not launch
|
|
* Option Byte Loader.
|
|
* @param FlashEmpty this parameter can be a value of @ref FLASHEx_Empty_Check
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
|
|
{
|
|
uint32_t acr;
|
|
assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
|
|
|
|
acr = (FLASH->ACR & ~FLASH_ACR_PROGEMPTY);
|
|
FLASH->ACR = (acr | FlashEmpty);
|
|
}
|
|
|
|
|
|
#if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
|
|
/**
|
|
* @brief Securable memory area protection enable
|
|
* @param Banks Select Bank to be secured.
|
|
* This parameter can be a value of @ref FLASH_Banks
|
|
* @note On some devices, there is only 1 bank so parameter has to be set FLASH_BANK_1.
|
|
* @note This API locks Securable memory area which is defined in SEC_SIZE option byte
|
|
* (that can be retrieved calling HAL_FLASHEx_OBGetConfig API and checking
|
|
* Secsize).
|
|
* @note SEC_PROT bit can only be set, it will be reset by system reset.
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_EnableSecMemProtection(uint32_t Banks)
|
|
{
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
assert_param(IS_FLASH_BANK(Banks));
|
|
|
|
if (Banks == (FLASH_BANK_2 | FLASH_BANK_1))
|
|
{
|
|
FLASH->CR |= (FLASH_CR_SEC_PROT2 | FLASH_CR_SEC_PROT);
|
|
}
|
|
else if (Banks == FLASH_BANK_2)
|
|
{
|
|
FLASH->CR |= FLASH_CR_SEC_PROT2;
|
|
}
|
|
else
|
|
#else
|
|
UNUSED(Banks);
|
|
#endif
|
|
{
|
|
FLASH->CR |= FLASH_CR_SEC_PROT;
|
|
}
|
|
}
|
|
#endif
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
/** @addtogroup FLASHEx_Private_Functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Mass erase of FLASH memory.
|
|
* @param Banks: Banks to be erased
|
|
* This parameter can be a combination of the following values:
|
|
* @arg FLASH_BANK_1: Bank1 to be erased
|
|
* @arg FLASH_BANK_2: Bank2 to be erased*
|
|
* @note (*) availability depends on devices
|
|
* @retval None
|
|
*/
|
|
static void FLASH_MassErase(uint32_t Banks)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_BANK(Banks));
|
|
|
|
/* Set the Mass Erase Bit and start bit */
|
|
FLASH->CR |= (FLASH_CR_STRT | Banks);
|
|
}
|
|
|
|
/**
|
|
* @brief Erase the specified FLASH memory page.
|
|
* @param Banks: Banks to be erased
|
|
* This parameter can one of the following values:
|
|
* @arg FLASH_BANK_1: Bank1 to be erased
|
|
* @arg FLASH_BANK_2: Bank2 to be erased*
|
|
* @param Page FLASH page to erase
|
|
* This parameter must be a value between 0 and (max number of pages in Flash - 1)
|
|
* @note (*) availability depends on devices
|
|
* @retval None
|
|
*/
|
|
void FLASH_PageErase(uint32_t Banks, uint32_t Page)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_BANK(Banks));
|
|
assert_param(IS_FLASH_PAGE(Page));
|
|
|
|
/* Get configuration register, then clear page number */
|
|
tmp = (FLASH->CR & ~FLASH_CR_PNB);
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Check if page has to be erased in bank 1 or 2 */
|
|
if(Banks != FLASH_BANK_1)
|
|
{
|
|
tmp |= FLASH_CR_BKER;
|
|
}
|
|
else
|
|
{
|
|
tmp &= ~FLASH_CR_BKER;
|
|
}
|
|
#endif
|
|
|
|
/* Set page number, Page Erase bit & Start bit */
|
|
FLASH->CR = (tmp | (FLASH_CR_STRT | (Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER));
|
|
}
|
|
|
|
/**
|
|
* @brief Flush the instruction cache.
|
|
* @retval None
|
|
*/
|
|
void FLASH_FlushCaches(void)
|
|
{
|
|
/* Flush instruction cache */
|
|
if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
|
|
{
|
|
/* Disable instruction cache */
|
|
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
|
/* Reset instruction cache */
|
|
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
|
|
/* Enable instruction cache */
|
|
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Configure the write protection of the desired pages.
|
|
* @note When WRP is active in a zone, it cannot be erased or programmed.
|
|
* Consequently, a software mass erase cannot be performed if one zone
|
|
* is write-protected.
|
|
* @note When the memory read protection level is selected (RDP level = 1),
|
|
* it is not possible to program or erase Flash memory if the CPU debug
|
|
* features are connected (JTAG or single wire) or boot code is being
|
|
* executed from RAM or System flash, even if WRP is not activated.
|
|
* @param WRPArea Specifies the area to be configured.
|
|
* This parameter can be one of the following values:
|
|
* @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
|
|
* @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
|
|
* @arg @ref OB_WRPAREA_ZONE2_A Flash Bank 2 Zone A (*)
|
|
* @arg @ref OB_WRPAREA_ZONE2_B Flash Bank 2 Zone B (*)
|
|
* @note (*) availability depends on devices
|
|
* @param WRPStartOffset Specifies the start page of the write protected area
|
|
* This parameter can be page number between 0 and (max number of pages in the Flash Bank - 1)
|
|
* @param WRDPEndOffset Specifies the end page of the write protected area
|
|
* This parameter can be page number between WRPStartOffset and (max number of pages in the Flash Bank - 1)
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_WRPAREA(WRPArea));
|
|
assert_param(IS_FLASH_PAGE(WRPStartOffset));
|
|
assert_param(IS_FLASH_PAGE(WRDPEndOffset));
|
|
|
|
/* Configure the write protected area */
|
|
if (WRPArea == OB_WRPAREA_ZONE_A)
|
|
{
|
|
FLASH->WRP1AR = ((WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos) | WRPStartOffset);
|
|
}
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
else if (WRPArea == OB_WRPAREA_ZONE2_A)
|
|
{
|
|
FLASH->WRP2AR = ((WRDPEndOffset << FLASH_WRP2AR_WRP2A_END_Pos) | WRPStartOffset);
|
|
}
|
|
else if (WRPArea == OB_WRPAREA_ZONE2_B)
|
|
{
|
|
FLASH->WRP2BR = ((WRDPEndOffset << FLASH_WRP2BR_WRP2B_END_Pos) | WRPStartOffset);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
FLASH->WRP1BR = ((WRDPEndOffset << FLASH_WRP1BR_WRP1B_END_Pos) | WRPStartOffset);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Write Protection Option Bytes value.
|
|
* @param[in] WRPArea Specifies the area to be returned.
|
|
* This parameter can be one of the following values:
|
|
* @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
|
|
* @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
|
|
* @arg @ref OB_WRPAREA_ZONE2_A Flash Bank 2 Zone A (*)
|
|
* @arg @ref OB_WRPAREA_ZONE2_B Flash Bank 2 Zone B (*)
|
|
* @note (*) availability depends on devices
|
|
* @param[out] WRPStartOffset Specifies the address where to copied the start page
|
|
* of the write protected area
|
|
* @param[out] WRDPEndOffset Dpecifies the address where to copied the end page of
|
|
* the write protected area
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_WRPAREA(WRPArea));
|
|
|
|
/* Get the configuration of the write protected area */
|
|
if (WRPArea == OB_WRPAREA_ZONE_A)
|
|
{
|
|
*WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
|
|
*WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
|
|
}
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
else if (WRPArea == OB_WRPAREA_ZONE2_A)
|
|
{
|
|
*WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
|
|
*WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> FLASH_WRP2AR_WRP2A_END_Pos);
|
|
}
|
|
else if (WRPArea == OB_WRPAREA_ZONE2_B)
|
|
{
|
|
*WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
|
|
*WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> FLASH_WRP2BR_WRP2B_END_Pos);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
*WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
|
|
*WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Set user & RDP configuration
|
|
* @note !!! Warning : When enabling OB_RDP level 2 it is no more possible
|
|
* to go back to level 1 or 0 !!!
|
|
* @param UserType The FLASH User Option Bytes to be modified.
|
|
* This parameter can be a combination of @ref FLASH_OB_USER_Type
|
|
* @param UserConfig The FLASH User Option Bytes values.
|
|
* This parameter can be a combination of:
|
|
* @arg @ref FLASH_OB_USER_BOR_ENABLE(*)
|
|
* @arg @ref FLASH_OB_USER_BOR_LEVEL(*)
|
|
* @arg @ref FLASH_OB_USER_RESET_CONFIG(*)
|
|
* @arg @ref FLASH_OB_USER_nRST_STOP
|
|
* @arg @ref FLASH_OB_USER_nRST_STANDBY
|
|
* @arg @ref FLASH_OB_USER_nRST_SHUTDOWN(*)
|
|
* @arg @ref FLASH_OB_USER_IWDG_SW
|
|
* @arg @ref FLASH_OB_USER_IWDG_STOP
|
|
* @arg @ref FLASH_OB_USER_IWDG_STANDBY
|
|
* @arg @ref FLASH_OB_USER_WWDG_SW
|
|
* @arg @ref FLASH_OB_USER_SRAM_PARITY
|
|
* @arg @ref FLASH_OB_USER_BANK_SWAP(*)
|
|
* @arg @ref FLASH_OB_USER_DUAL_BANK(*)
|
|
* @arg @ref FLASH_OB_USER_nBOOT_SEL
|
|
* @arg @ref FLASH_OB_USER_nBOOT1
|
|
* @arg @ref FLASH_OB_USER_nBOOT0
|
|
* @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER(*)
|
|
* @param RDPLevel specifies the read protection level.
|
|
* This parameter can be one of the following values:
|
|
* @arg @ref OB_RDP_LEVEL_0 No protection
|
|
* @arg @ref OB_RDP_LEVEL_1 Memory Read protection
|
|
* @arg @ref OB_RDP_LEVEL_2 Full chip protection
|
|
* @note (*) availability depends on devices
|
|
* @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 Return the FLASH Read Protection level.
|
|
* @retval FLASH ReadOut Protection Status:
|
|
* This return value can be one of the following values:
|
|
* @arg @ref OB_RDP_LEVEL_0 No protection
|
|
* @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
|
|
* @arg @ref OB_RDP_LEVEL_2 Full chip protection
|
|
*/
|
|
static uint32_t FLASH_OB_GetRDP(void)
|
|
{
|
|
uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
|
|
|
|
if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
|
|
{
|
|
return (OB_RDP_LEVEL_1);
|
|
}
|
|
else
|
|
{
|
|
return rdplvl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH User Option Byte value.
|
|
* @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
|
|
* @arg @ref FLASH_OB_USER_BOR_ENABLE(*)
|
|
* @arg @ref FLASH_OB_USER_BOR_LEVEL(*)
|
|
* @arg @ref FLASH_OB_USER_RESET_CONFIG(*)
|
|
* @arg @ref FLASH_OB_USER_nRST_STOP
|
|
* @arg @ref FLASH_OB_USER_nRST_STANDBY
|
|
* @arg @ref FLASH_OB_USER_nRST_SHUTDOWN(*)
|
|
* @arg @ref FLASH_OB_USER_IWDG_SW
|
|
* @arg @ref FLASH_OB_USER_IWDG_STOP
|
|
* @arg @ref FLASH_OB_USER_IWDG_STANDBY
|
|
* @arg @ref FLASH_OB_USER_WWDG_SW
|
|
* @arg @ref FLASH_OB_USER_SRAM_PARITY
|
|
* @arg @ref FLASH_OB_USER_BANK_SWAP(*)
|
|
* @arg @ref FLASH_OB_USER_DUAL_BANK(*)
|
|
* @arg @ref FLASH_OB_USER_nBOOT_SEL
|
|
* @arg @ref FLASH_OB_USER_nBOOT1
|
|
* @arg @ref FLASH_OB_USER_nBOOT0
|
|
* @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER(*)
|
|
* @note (*) availability depends on devices
|
|
*/
|
|
static uint32_t FLASH_OB_GetUser(void)
|
|
{
|
|
uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
|
|
return user;
|
|
}
|
|
|
|
#if defined(FLASH_PCROP_SUPPORT)
|
|
/**
|
|
* @brief Configure the 1A Proprietary code readout protection & erase configuration on RDP regression.
|
|
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
|
* having some executable code in a page where PCROP zone starts or ends.
|
|
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
|
|
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
|
* has to be set to 512 Bytes
|
|
* @param PCROPConfig specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
|
|
* on RDP level 1 regression.
|
|
* @param PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
|
|
* This parameter can be an address between begin and end of the flash
|
|
* @param PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
|
|
* This parameter can be an address between PCROP1AStartAddr and end of the flash
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
|
|
{
|
|
uint32_t startoffset;
|
|
uint32_t endoffset;
|
|
uint32_t pcrop1aend;
|
|
uint32_t ropbase;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1AStartAddr));
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1AEndAddr));
|
|
|
|
/* Bank swap, bank 1 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1AStartAddr));
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1AEndAddr));
|
|
|
|
/* No Bank swap, bank 1 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
/* get pcrop 1A end register */
|
|
pcrop1aend = FLASH->PCROP1AER;
|
|
|
|
/* Configure the Proprietary code readout protection offset */
|
|
if ((PCROPConfig & OB_PCROP_ZONE_A) != 0x00U)
|
|
{
|
|
/* Compute offset depending on pcrop granularity */
|
|
startoffset = ((PCROP1AStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
endoffset = ((PCROP1AEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
|
|
/* Set Zone A start offset */
|
|
FLASH->PCROP1ASR = startoffset;
|
|
|
|
/* Set Zone A end offset */
|
|
pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
|
|
pcrop1aend |= endoffset;
|
|
}
|
|
|
|
/* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
|
|
if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0x00U)
|
|
{
|
|
pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
|
|
}
|
|
|
|
/* set 1A End register */
|
|
FLASH->PCROP1AER = pcrop1aend;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the 1B Proprietary code readout protection.
|
|
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
|
* having some executable code in a page where PCROP zone starts or ends.
|
|
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROPB_STRT and PCROPB_END.
|
|
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
|
* has to be set to 512 Bytes
|
|
* @param PCROP1BStartAddr Specifies the Zone 1B Start address of the Proprietary code readout protection
|
|
* This parameter can be an address between begin and end of the flash
|
|
* @param PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
|
|
* This parameter can be an address between PCROP1BStartAddr and end of the flash
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
|
|
{
|
|
uint32_t startoffset;
|
|
uint32_t endoffset;
|
|
uint32_t ropbase;
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1BStartAddr));
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1BEndAddr));
|
|
|
|
/* Bank swap, bank 1 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1BStartAddr));
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1BEndAddr));
|
|
|
|
/* No Bank swap, bank 1 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
/* Configure the Proprietary code readout protection offset */
|
|
startoffset = ((PCROP1BStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
endoffset = ((PCROP1BEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
|
|
/* Set Zone B start offset */
|
|
FLASH->PCROP1BSR = startoffset;
|
|
/* Set Zone B end offset */
|
|
FLASH->PCROP1BER = endoffset;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
|
* @param PCROPConfig [out] specifies the configuration of PCROP_RDP option.
|
|
* @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
|
|
* of the 1A Proprietary code readout protection
|
|
* @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
|
|
* the 1A Proprietary code readout protection
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr)
|
|
{
|
|
uint32_t pcrop;
|
|
uint32_t ropbase;
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK)
|
|
{
|
|
/* Bank swap, bank 1 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/* No Bank swap, bank 1 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
pcrop = (FLASH->PCROP1ASR & FLASH_PCROP1ASR_PCROP1A_STRT);
|
|
*PCROP1AStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP1AStartAddr += ropbase;
|
|
|
|
pcrop = FLASH->PCROP1AER;
|
|
*PCROP1AEndAddr = ((pcrop & FLASH_PCROP1AER_PCROP1A_END) << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP1AEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
|
|
|
|
*PCROPConfig &= ~OB_PCROP_RDP_ERASE;
|
|
*PCROPConfig |= (pcrop & FLASH_PCROP1AER_PCROP_RDP);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
|
* @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
|
|
* of the 1B Proprietary code readout protection
|
|
* @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
|
|
* the 1B Proprietary code readout protection
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
|
|
{
|
|
uint32_t pcrop;
|
|
uint32_t ropbase;
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK)
|
|
{
|
|
/* Bank swap, bank 1 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/* No Bank swap, bank 1 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
pcrop = (FLASH->PCROP1BSR & FLASH_PCROP1BSR_PCROP1B_STRT);
|
|
*PCROP1BStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP1BStartAddr += ropbase;
|
|
|
|
pcrop = (FLASH->PCROP1BER & FLASH_PCROP1BER_PCROP1B_END);
|
|
*PCROP1BEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP1BEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
|
|
}
|
|
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/**
|
|
* @brief Configure the 2A Proprietary code readout protection.
|
|
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
|
* having some executable code in a page where PCROP zone starts or ends.
|
|
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
|
|
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
|
* has to be set to 512 Bytes
|
|
* @param PCROP2AStartAddr Specifies the Zone 2A Start address of the Proprietary code readout protection
|
|
* This parameter can be an address between begin and end of the flash
|
|
* @param PCROP2AEndAddr Specifies the Zone 2A end address of the Proprietary code readout protection
|
|
* This parameter can be an address between PCROP2AStartAddr and end of the flash
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_PCROP2AConfig(uint32_t PCROP2AStartAddr, uint32_t PCROP2AEndAddr)
|
|
{
|
|
uint32_t startoffset;
|
|
uint32_t endoffset;
|
|
uint32_t ropbase;
|
|
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2AStartAddr));
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2AEndAddr));
|
|
|
|
/* No Bank swap, bank 2 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2AStartAddr));
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2AEndAddr));
|
|
|
|
/* Bank swap, bank 2 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
/* Configure the Proprietary code readout protection offset */
|
|
startoffset = ((PCROP2AStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
endoffset = ((PCROP2AEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
|
|
/* Set Zone A start offset */
|
|
FLASH->PCROP2ASR = startoffset;
|
|
/* Set Zone A end offset */
|
|
FLASH->PCROP2AER = endoffset;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the 2B Proprietary code readout protection.
|
|
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
|
* having some executable code in a page where PCROP zone starts or ends.
|
|
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROP_STRT and PCROP_END.
|
|
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
|
* has to be set to 512 Bytes
|
|
* @param PCROP2BStartAddr Specifies the Zone 2B Start address of the Proprietary code readout protection
|
|
* This parameter can be an address between begin and end of the flash
|
|
* @param PCROP2BEndAddr Specifies the Zone 2B end address of the Proprietary code readout protection
|
|
* This parameter can be an address between PCROP2BStartAddr and end of the flash
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_PCROP2BConfig(uint32_t PCROP2BStartAddr, uint32_t PCROP2BEndAddr)
|
|
{
|
|
uint32_t startoffset;
|
|
uint32_t endoffset;
|
|
uint32_t ropbase;
|
|
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2BStartAddr));
|
|
assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2BEndAddr));
|
|
|
|
/* No Bank swap, bank 2 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2BStartAddr));
|
|
assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2BEndAddr));
|
|
|
|
/* Bank swap, bank 2 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
/* Configure the Proprietary code readout protection offset */
|
|
startoffset = ((PCROP2BStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
endoffset = ((PCROP2BEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
|
|
|
/* Set Zone B start offset */
|
|
FLASH->PCROP2BSR = startoffset;
|
|
/* Set Zone B end offset */
|
|
FLASH->PCROP2BER = endoffset;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
|
* @param PCROP2AStartAddr [out] Specifies the address where to copied the start address
|
|
* of the 2A Proprietary code readout protection
|
|
* @param PCROP2AEndAddr [out] Specifies the address where to copied the end address of
|
|
* the 2A Proprietary code readout protection
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetPCROP2A(uint32_t *PCROP2AStartAddr, uint32_t *PCROP2AEndAddr)
|
|
{
|
|
uint32_t pcrop;
|
|
uint32_t ropbase;
|
|
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
|
|
{
|
|
/* No Bank swap, bank 2 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
{
|
|
/* Bank swap, bank 2 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
pcrop = (FLASH->PCROP2ASR & FLASH_PCROP2ASR_PCROP2A_STRT);
|
|
*PCROP2AStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP2AStartAddr += ropbase;
|
|
|
|
pcrop = (FLASH->PCROP2AER & FLASH_PCROP2AER_PCROP2A_END);
|
|
*PCROP2AEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP2AEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
|
* @param PCROP2BStartAddr [out] Specifies the address where to copied the start address
|
|
* of the 2B Proprietary code readout protection
|
|
* @param PCROP2BEndAddr [out] Specifies the address where to copied the end address of
|
|
* the 2B Proprietary code readout protection
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetPCROP2B(uint32_t *PCROP2BStartAddr, uint32_t *PCROP2BEndAddr)
|
|
{
|
|
uint32_t pcrop;
|
|
uint32_t ropbase;
|
|
|
|
/* Check if banks are swapped */
|
|
if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
|
|
{
|
|
/* No Bank swap, bank 2 read only protection is on second half of Flash */
|
|
ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
|
|
}
|
|
else
|
|
{
|
|
/* Bank swap, bank 2 read only protection is on first half of Flash */
|
|
ropbase = FLASH_BASE;
|
|
}
|
|
|
|
pcrop = (FLASH->PCROP2BSR & FLASH_PCROP2BSR_PCROP2B_STRT);
|
|
*PCROP2BStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP2BStartAddr += ropbase;
|
|
|
|
pcrop = (FLASH->PCROP2BER & FLASH_PCROP2BER_PCROP2B_END);
|
|
*PCROP2BEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
|
*PCROP2BEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
|
|
#if defined(FLASH_DBANK_SUPPORT)
|
|
/**
|
|
* @brief Configure Securable Memory area feature.
|
|
* @param BootEntry specifies if boot scheme is forced to Flash (System or user) or not
|
|
* This parameter can be one of the following values:
|
|
* @arg @ref OB_BOOT_ENTRY_FORCED_NONE No boot entry forced
|
|
* @arg @ref OB_BOOT_ENTRY_FORCED_FLASH Flash selected as unique entry boot
|
|
* @param SecSize specifies number of pages to protect as securable memory area, starting from
|
|
* beginning of Bank1 (page 0).
|
|
* @param SecSize2 specifies number of pages to protect as securable memory area, starting from
|
|
* beginning of Bank2 (page 0).
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize, uint32_t SecSize2)
|
|
{
|
|
uint32_t secmem;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_SEC_BOOT_LOCK(BootEntry));
|
|
assert_param(IS_OB_SEC_SIZE(SecSize));
|
|
assert_param(IS_OB_SEC_SIZE(SecSize2));
|
|
|
|
/* Set securable memory area configuration */
|
|
secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_SEC_SIZE | FLASH_SECR_SEC_SIZE2));
|
|
FLASH->SECR = (secmem | BootEntry | SecSize | (SecSize2 << FLASH_SECR_SEC_SIZE2_Pos));
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Securable memory area protection Option Bytes value.
|
|
* @param BootEntry specifies boot scheme configuration
|
|
* @param SecSize specifies number of pages to protect as secure memory area, starting from
|
|
* beginning of Bank1 (page 0).
|
|
* @param SecSize2 specifies number of pages to protect as secure memory area, starting from
|
|
* beginning of Bank2 (page 0).
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize, uint32_t *SecSize2)
|
|
{
|
|
uint32_t secmem = FLASH->SECR;
|
|
|
|
*BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
|
|
*SecSize = (secmem & FLASH_SECR_SEC_SIZE);
|
|
*SecSize2 = (secmem & FLASH_SECR_SEC_SIZE2) >> FLASH_SECR_SEC_SIZE2_Pos;
|
|
}
|
|
|
|
#else
|
|
/**
|
|
* @brief Configure Securable Memory area feature.
|
|
* @param BootEntry specifies if boot scheme is forced to Flash (System or user) or not
|
|
* This parameter can be one of the following values:
|
|
* @arg @ref OB_BOOT_ENTRY_FORCED_NONE No boot entry forced
|
|
* @arg @ref OB_BOOT_ENTRY_FORCED_FLASH FLash selected as unique entry boot
|
|
* @param SecSize specifies number of pages to protect as securable memory area, starting from
|
|
* beginning of the Flash (page 0).
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize)
|
|
{
|
|
uint32_t secmem;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_SEC_BOOT_LOCK(BootEntry));
|
|
assert_param(IS_OB_SEC_SIZE(SecSize));
|
|
|
|
/* Set securable memory area configuration */
|
|
secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_SEC_SIZE));
|
|
FLASH->SECR = (secmem | BootEntry | SecSize);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Securable memory area protection Option Bytes value.
|
|
* @param BootEntry specifies boot scheme configuration
|
|
* @param SecSize specifies number of pages to protect as secure memory area, starting from
|
|
* beginning of the Flash (page 0).
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize)
|
|
{
|
|
uint32_t secmem = FLASH->SECR;
|
|
|
|
*BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
|
|
*SecSize = (secmem & FLASH_SECR_SEC_SIZE);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|