1323 lines
39 KiB
C
1323 lines
39 KiB
C
/**
|
|
******************************************************************************
|
|
* @file stm32h7rsxx_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 STM32H7RSxx
|
|
devices contains the following additional features
|
|
|
|
(+) Non-volatile state, Root-Of-Trust and Epoch option bytes
|
|
(+) Option byte keys associated with hide protection level
|
|
(+) CRC hardware module to check integrity
|
|
(+) OTP blocks lock mechanism
|
|
|
|
##### How to use this driver #####
|
|
==============================================================================
|
|
[..] This driver provides functions to configure and program the FLASH memory
|
|
of all STM32H7RSxx 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 and Mass Erase
|
|
(++) 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:
|
|
(++) Configure the write protection for each sector
|
|
(++) Program the user Option Bytes
|
|
(++) Configure the hide protection area
|
|
(++) Configure the non-volatile state
|
|
|
|
(#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to:
|
|
(++) Get the value of the sectors write protection
|
|
(++) Get the value of the user Option Bytes
|
|
(++) Get the configuration of the hide protection area
|
|
(++) Get the value of the non-volatile state
|
|
(++) Get the value of the Root-Of-Trust configuration
|
|
(++) Get the value of the Epoch
|
|
|
|
(#) OTP lock configuration function: Use HAL_FLASHEx_OTPLockConfig()
|
|
(++) Activate the lock of an OTP block
|
|
|
|
(#) Get the OTP lock configuration function: Use HAL_FLASHEx_GetOTPLock()
|
|
(++) Get the value of the OTP blocks lock configuration
|
|
|
|
(#) Option Byte Keys configuration function: Use HAL_FLASHEx_KeyConfig()
|
|
(++) Program an option key for a specified hide protection level
|
|
|
|
(#) Get an option byte key value: Use HAL_FLASHEx_GetKey()
|
|
(++) Get the value of an option byte key for a specified hide protection level
|
|
|
|
(#) Perform a CRC computation function: Use HAL_FLASHEx_ComputeCRC()
|
|
(++) Perform CRC computation on a area defined either by sectors or by start/end
|
|
addresses and return computation result
|
|
|
|
(#) ECC management functions:
|
|
(++) Handle ECC Detection flash interrupt by calling HAL_FLASHEx_ECCD_IRQHandler()
|
|
(++) Callback functions are called when the ECC detection or correction occurs :
|
|
HAL_FLASHEx_EccDetectionCallback() for ECC detection, otherwise
|
|
HAL_FLASHEx_EccCorrectionCallback()
|
|
(++) Get information about ECC error by calling HAL_FLASHEx_GetEccInfo()
|
|
(++) Enable/Disable the ECC correction and detection interrupts:
|
|
(+++) HAL_FLASHEx_EnableEccCorrectionInterrupt() to enable ECC correction interrupt
|
|
(+++) HAL_FLASHEx_DisableEccCorrectionInterrupt() to disable ECC correction interrupt
|
|
(+++) HAL_FLASHEx_EnableEccDetectionInterrupt() to enable ECC detection interrupt
|
|
(+++) HAL_FLASHEx_DisableEccDetectionInterrupt() to disable ECC detection interrupt
|
|
|
|
@endverbatim
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2022 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stm32h7rsxx_hal.h"
|
|
|
|
/** @addtogroup STM32H7RSxx_HAL_Driver
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup FLASHEx FLASHEx
|
|
* @brief FLASH Extended HAL module driver
|
|
* @{
|
|
*/
|
|
|
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define SYSTEM_FLASH_SIZE 0x00020000UL /*!< System Flash size : 128 KB */
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
|
|
* @{
|
|
*/
|
|
static void FLASH_MassErase(void);
|
|
|
|
static void FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector);
|
|
static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2);
|
|
static void FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage);
|
|
static void FLASH_OB_NVConfig(uint32_t NVState);
|
|
|
|
static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector);
|
|
static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2);
|
|
static void FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage);
|
|
static uint32_t FLASH_OB_GetNV(void);
|
|
static uint32_t FLASH_OB_GetRoT(void);
|
|
static uint32_t FLASH_OB_GetEpoch(void);
|
|
|
|
static void FLASH_CRC_AddSector(uint32_t Sector);
|
|
static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr);
|
|
static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout);
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* 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 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(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
|
|
{
|
|
HAL_StatusTypeDef status;
|
|
uint32_t sector_index;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
|
|
|
/* Process Locked */
|
|
__HAL_LOCK(&pFlash);
|
|
|
|
/* Reset error code */
|
|
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status == HAL_OK)
|
|
{
|
|
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
|
{
|
|
/* Mass erase to be done */
|
|
FLASH_MassErase();
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
}
|
|
else
|
|
{
|
|
/*Initialization of SectorError variable*/
|
|
*SectorError = 0xFFFFFFFFU;
|
|
|
|
for (sector_index = pEraseInit->Sector; sector_index < (pEraseInit->Sector + pEraseInit->NbSectors);
|
|
sector_index++)
|
|
{
|
|
FLASH_SectorErase(sector_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 sector */
|
|
*SectorError = sector_index;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If the erase operation is completed, disable the associated bits */
|
|
CLEAR_BIT(FLASH->CR, (pEraseInit->TypeErase | FLASH_CR_SSN));
|
|
}
|
|
|
|
/* 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(const 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;
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status != HAL_OK)
|
|
{
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
}
|
|
else
|
|
{
|
|
/* Set internal variables used by the IRQ handler */
|
|
pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
|
|
|
|
/* Enable End of Operation and Error interrupts */
|
|
SET_BIT(FLASH->IER, (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | FLASH_IT_INCERR));
|
|
|
|
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
|
{
|
|
/* Mass erase to be done */
|
|
FLASH_MassErase();
|
|
}
|
|
else
|
|
{
|
|
/* Erase by sector to be done */
|
|
pFlash.NbSectorsToErase = pEraseInit->NbSectors;
|
|
pFlash.Sector = pEraseInit->Sector;
|
|
|
|
/* Erase first sector and wait for IT */
|
|
FLASH_SectorErase(pEraseInit->Sector);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Program Option bytes.
|
|
* @param pOBInit pointer to an FLASH_OBInitStruct 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 HAL_FLASH_OB_Unlock() function.
|
|
* @note New option bytes configuration will be taken into account in two cases:
|
|
* - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
|
|
* - after a power reset (BOR reset or exit from Standby/Shutdown modes)
|
|
*
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(const 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 */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if ((status == HAL_OK) && (pOBInit->OptionType != 0U))
|
|
{
|
|
/* Set PG_OPT Bit */
|
|
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
|
|
/* Write protection configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
|
|
{
|
|
/* Configure of Write protection on the selected area */
|
|
FLASH_OB_WRPConfig(pOBInit->WRPState, pOBInit->WRPSector);
|
|
}
|
|
|
|
/* User Configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
|
|
{
|
|
/* Configure the user option bytes */
|
|
FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig1, pOBInit->USERConfig2);
|
|
}
|
|
|
|
/* HDP configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_HDP) != 0U)
|
|
{
|
|
/* Configure the HDP Protection */
|
|
FLASH_OB_HDPConfig(pOBInit->HDPStartPage, pOBInit->HDPEndPage);
|
|
}
|
|
|
|
/* Non-volatile state configuration */
|
|
if ((pOBInit->OptionType & OPTIONBYTE_NV) != 0U)
|
|
{
|
|
/* Configure the non-volatile state */
|
|
FLASH_OB_NVConfig(pOBInit->NVState);
|
|
}
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
/* Clear PG_OPT Bit */
|
|
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the Option bytes configuration.
|
|
* @param pOBInit pointer to an FLASH_OBInitStruct structure that contains the
|
|
* configuration information.
|
|
* @note The fields pOBInit->WRPArea, pOBInit->WMSecConfig and pOBInit->BootAddrConfig
|
|
* should indicate which area/address is requested for the WRP, WM Security or
|
|
* Boot Address, else no information will be returned
|
|
*
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
|
|
{
|
|
/* Get write protection on the selected area */
|
|
FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector));
|
|
|
|
/* Get the user option bytes */
|
|
FLASH_OB_GetUser(&(pOBInit->USERConfig1), &(pOBInit->USERConfig2));
|
|
|
|
/* Get the HDP Protection */
|
|
FLASH_OB_GetHDP(&(pOBInit->HDPStartPage), &(pOBInit->HDPEndPage));
|
|
|
|
/* Get the non-volatile state */
|
|
pOBInit->NVState = FLASH_OB_GetNV();
|
|
|
|
/* Get the Root-Of-Trust configuration */
|
|
pOBInit->ROTConfig = FLASH_OB_GetRoT();
|
|
|
|
/* Get the epoch */
|
|
pOBInit->EPOCH = FLASH_OB_GetEpoch();
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup FLASHEx_Exported_Functions_Group2 Extended protection operation functions
|
|
* @brief Extended protection operation functions
|
|
*
|
|
@verbatim
|
|
===============================================================================
|
|
##### Extended protection operation functions #####
|
|
===============================================================================
|
|
[..]
|
|
This subsection provides a set of functions allowing to manage the Extended FLASH
|
|
CRC operations, OTP lock mechanism and option byte keys management.
|
|
|
|
@endverbatim
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Configure the OTP Lock.
|
|
*
|
|
* @note To configure the OTP Lock options, the option lock bit OPTLOCK must be
|
|
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
|
*
|
|
* @param OTPLBlock Specifies the block(s) to be OTP locked (used for OPTIONBYTE_OTPL).
|
|
* The value of this parameter depend on device used within the same series
|
|
*
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_OTPLockConfig(uint32_t OTPLBlock)
|
|
{
|
|
HAL_StatusTypeDef status;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_OTP_BLOCK(OTPLBlock));
|
|
|
|
/* 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)
|
|
{
|
|
/* Set the bit for the OTP programmation */
|
|
SET_BIT(FLASH->CR, FLASH_CR_PG_OTP);
|
|
|
|
/* Set PG_OPT Bit */
|
|
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
|
|
/* Configure the write protected area */
|
|
MODIFY_REG(FLASH->OTPLSRP, FLASH_OTPLSRP_OTPL, (OTPLBlock & FLASH_OTPLSRP_OTPL));
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
/* Clear PG_OPT Bit */
|
|
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
|
|
/* Clear the bit for the OTP programmation */
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG_OTP);
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH OTP Lock Option Bytes value.
|
|
*
|
|
* @retval Status of the OTP Lock
|
|
*/
|
|
uint32_t HAL_FLASHEx_GetOTPLock(void)
|
|
{
|
|
return (FLASH->OTPLSR & FLASH_OTPLSR_OTPL);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the Keys.
|
|
*
|
|
* @note To configure the Keys options, the option lock bit OPTLOCK must be
|
|
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
|
*
|
|
* @param pKeyConfig Key(s) to be configured.
|
|
*
|
|
* @param pKey Address of the key
|
|
*
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_KeyConfig(const FLASH_KeyConfigTypeDef *pKeyConfig, const uint32_t *pKey)
|
|
{
|
|
uint32_t index;
|
|
uint32_t index_max;
|
|
const uint32_t *pdata;
|
|
HAL_StatusTypeDef status;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_KEY_INDEX(pKeyConfig->Index));
|
|
assert_param(IS_KEY_SIZE(pKeyConfig->Size));
|
|
assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel));
|
|
|
|
/* 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)
|
|
{
|
|
/* Set PG_OPT Bit */
|
|
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
|
|
switch (pKeyConfig->Size)
|
|
{
|
|
case FLASH_KEY_32_BITS :
|
|
index_max = 1U;
|
|
break;
|
|
|
|
case FLASH_KEY_64_BITS :
|
|
index_max = 2U;
|
|
break;
|
|
|
|
case FLASH_KEY_128_BITS :
|
|
index_max = 4U;
|
|
break;
|
|
|
|
case FLASH_KEY_256_BITS :
|
|
index_max = 8U;
|
|
break;
|
|
|
|
default:
|
|
/* This case should not occur */
|
|
index_max = 0U;
|
|
break;
|
|
}
|
|
|
|
pdata = pKey;
|
|
for (index = 0U; index < index_max; index++)
|
|
{
|
|
FLASH->OBKDR[index] = pdata[index];
|
|
}
|
|
|
|
MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE),
|
|
(pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size));
|
|
|
|
SET_BIT(FLASH->OBKCR, (FLASH_OBKCR_KEYSTART | FLASH_OBKCR_KEYPROG));
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
CLEAR_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYPROG);
|
|
|
|
/* Clear PG_OPT Bit */
|
|
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Load and optionally return the FLASH Option Bytes Key value.
|
|
*
|
|
* @param pKeyConfig Configuration of the key to be loaded and optionally returned
|
|
*
|
|
* @param pKey Address to return the FLASH Option Bytes Key value if not NULL.
|
|
*
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_GetKey(const FLASH_KeyConfigTypeDef *pKeyConfig, uint32_t *pKey)
|
|
{
|
|
uint32_t index;
|
|
uint32_t index_max;
|
|
uint32_t *pdata;
|
|
HAL_StatusTypeDef status;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_KEY_INDEX(pKeyConfig->Index));
|
|
assert_param(IS_KEY_SIZE(pKeyConfig->Size));
|
|
assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel));
|
|
|
|
/* 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)
|
|
{
|
|
/* Set PG_OPT Bit */
|
|
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
|
|
/* Configure index and HDPL level */
|
|
MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE | FLASH_OBKCR_KEYPROG),
|
|
(pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size));
|
|
|
|
/* Set the start bit to get the key value */
|
|
SET_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYSTART);
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if ((status == HAL_OK) && (pKey != NULL))
|
|
{
|
|
switch (pKeyConfig->Size)
|
|
{
|
|
case FLASH_KEY_32_BITS :
|
|
index_max = 1U;
|
|
break;
|
|
|
|
case FLASH_KEY_64_BITS :
|
|
index_max = 2U;
|
|
break;
|
|
|
|
case FLASH_KEY_128_BITS :
|
|
index_max = 4U;
|
|
break;
|
|
|
|
case FLASH_KEY_256_BITS :
|
|
index_max = 8U;
|
|
break;
|
|
|
|
default:
|
|
/* This case should not occur */
|
|
index_max = 0U;
|
|
break;
|
|
}
|
|
|
|
pdata = pKey;
|
|
for (index = 0U; index < index_max; index++)
|
|
{
|
|
*pdata = FLASH->OBKDR[index];
|
|
pdata++;
|
|
}
|
|
}
|
|
|
|
/* Clear PG_OPT Bit */
|
|
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
|
|
}
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @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.
|
|
* @param CRC_Result pointer to CRC result
|
|
* @note CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
|
|
* @retval HAL Status
|
|
*/
|
|
HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(const FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
|
|
{
|
|
HAL_StatusTypeDef status;
|
|
uint32_t sector_index;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_TYPE_CRC(pCRCInit->TypeCRC));
|
|
assert_param(IS_FLASH_BURST_SIZE_CRC(pCRCInit->BurstSize));
|
|
|
|
/* Wait for last operation to be completed */
|
|
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
|
|
|
if (status == HAL_OK)
|
|
{
|
|
/* Process Locked */
|
|
__HAL_LOCK(&pFlash);
|
|
|
|
/* Reset error code */
|
|
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
|
|
/* Enable CRC feature */
|
|
SET_BIT(FLASH->CR, FLASH_CR_CRC_EN);
|
|
|
|
/* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
|
|
FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF);
|
|
|
|
/* Clear current CRC result and program burst size */
|
|
MODIFY_REG(FLASH->CRCCR, (FLASH_CRCCR_CLEAN_CRC | FLASH_CRCCR_CRC_BURST),
|
|
(FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize));
|
|
|
|
if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
|
|
{
|
|
/* Select CRC by sector and clear sectors list */
|
|
SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | 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);
|
|
}
|
|
}
|
|
else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
|
|
{
|
|
/* Select CRC by sector and all sectors */
|
|
SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | FLASH_CRCCR_ALL_SECT));
|
|
}
|
|
else
|
|
{
|
|
/* Select CRC by address */
|
|
CLEAR_BIT(FLASH->CRCCR, FLASH_CRCCR_CRC_BY_SECT);
|
|
|
|
/* Select CRC start and end addresses */
|
|
FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr);
|
|
}
|
|
|
|
/* Start the CRC calculation */
|
|
SET_BIT(FLASH->CRCCR, FLASH_CRCCR_START_CRC);
|
|
|
|
/* Wait on CRC busy flag */
|
|
status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
|
|
|
/* Return CRC result */
|
|
(*CRC_Result) = FLASH->CRCDATAR;
|
|
|
|
/* Disable CRC feature */
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_CRC_EN);
|
|
|
|
/* Clear CRC flags */
|
|
FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF);
|
|
|
|
/* Process Unlocked */
|
|
__HAL_UNLOCK(&pFlash);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup FLASHEx_Exported_Functions_Group3 Extended ECC operation functions
|
|
* @brief Extended ECC operation functions
|
|
*
|
|
@verbatim
|
|
===============================================================================
|
|
##### Extended ECC operation functions #####
|
|
===============================================================================
|
|
[..]
|
|
This subsection provides a set of functions allowing to manage the Extended FLASH
|
|
ECC Operations.
|
|
|
|
@endverbatim
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Enable ECC correction interrupt
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_EnableEccCorrectionInterrupt(void)
|
|
{
|
|
__HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR);
|
|
}
|
|
|
|
/**
|
|
* @brief Disable ECC correction interrupt
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_DisableEccCorrectionInterrupt(void)
|
|
{
|
|
__HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR);
|
|
}
|
|
|
|
/**
|
|
* @brief Enable ECC detection interrupt
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_EnableEccDetectionInterrupt(void)
|
|
{
|
|
__HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR);
|
|
}
|
|
|
|
/**
|
|
* @brief Disable ECC detection interrupt
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_DisableEccDetectionInterrupt(void)
|
|
{
|
|
__HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the ECC error information.
|
|
* @param pData Pointer to an FLASH_EccInfoTypeDef structure that contains the
|
|
* ECC error information.
|
|
* @note This function should be called before ECC bit is cleared
|
|
* (in callback function)
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef *pData)
|
|
{
|
|
/* Check Null pointer */
|
|
assert_param(pData != NULL);
|
|
|
|
/* Set address which generate ECC error */
|
|
if ((FLASH->ISR & FLASH_FLAG_SNECCERR) != 0U)
|
|
{
|
|
pData->Address = FLASH->ECCSFADDR;
|
|
}
|
|
else
|
|
{
|
|
pData->Address = FLASH->ECCDFADDR;
|
|
}
|
|
|
|
/* Set area according address */
|
|
if (IS_FLASH_MAIN_MEM_ADDRESS(pData->Address))
|
|
{
|
|
pData->Area = FLASH_ECC_AREA_USER_BANK1;
|
|
}
|
|
else if (IS_FLASH_OTP_ADDRESS(pData->Address))
|
|
{
|
|
pData->Area = FLASH_ECC_AREA_OTP;
|
|
}
|
|
else if ((pData->Address >= SYSTEM_FLASH_BASE) &&
|
|
(pData->Address < (SYSTEM_FLASH_BASE + SYSTEM_FLASH_SIZE)))
|
|
{
|
|
pData->Area = FLASH_ECC_AREA_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
pData->Area = FLASH_ECC_AREA_READ_ONLY;
|
|
}
|
|
|
|
/* Set Master which initiates transaction. On H7RS, it's necessary CPU1 */
|
|
pData->MasterID = FLASH_ECC_MASTER_CPU1;
|
|
}
|
|
|
|
/**
|
|
* @brief Handle Flash ECC Detection interrupt request.
|
|
* @note On STM32H7RS, this Irq Handler should be called in Bus Fault
|
|
* interrupt subroutine.
|
|
* @retval None
|
|
*/
|
|
void HAL_FLASHEx_ECCD_IRQHandler(void)
|
|
{
|
|
/* Check ECC Detection Error */
|
|
if ((FLASH->ISR & FLASH_FLAG_DBECCERR) != 0U)
|
|
{
|
|
/* Call User callback */
|
|
HAL_FLASHEx_EccDetectionCallback();
|
|
|
|
/* Clear ECC detection flag in order to allow new ECC error record */
|
|
FLASH->ICR = FLASH_FLAG_DBECCERR;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief FLASH ECC Correction interrupt callback.
|
|
* @retval None
|
|
*/
|
|
__weak void HAL_FLASHEx_EccCorrectionCallback(void)
|
|
{
|
|
/* NOTE : This function should not be modified, when the callback is needed,
|
|
the HAL_FLASHEx_EccCorrectionCallback could be implemented in the user file
|
|
*/
|
|
}
|
|
|
|
/**
|
|
* @brief FLASH ECC Detection interrupt callback.
|
|
* @retval None
|
|
*/
|
|
__weak void HAL_FLASHEx_EccDetectionCallback(void)
|
|
{
|
|
/* NOTE : This function should not be modified, when the callback is needed,
|
|
the HAL_FLASHEx_EccDetectionCallback could be implemented in the user file
|
|
*/
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
/** @addtogroup FLASHEx_Private_Functions
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Mass erase of FLASH memory.
|
|
* @retval None
|
|
*/
|
|
static void FLASH_MassErase(void)
|
|
{
|
|
/* Set the Mass Erase Bit and proceed to erase */
|
|
SET_BIT(FLASH->CR, (FLASH_CR_BER | FLASH_CR_START));
|
|
}
|
|
|
|
/**
|
|
* @brief Erase the specified FLASH memory sector.
|
|
* @param Sector FLASH sector to erase
|
|
* This parameter must be a value between 0 and (max number of sectors in the bank - 1)
|
|
* @retval None
|
|
*/
|
|
void FLASH_SectorErase(uint32_t Sector)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_SECTOR(Sector));
|
|
|
|
/* Proceed to erase the page */
|
|
MODIFY_REG(FLASH->CR, (FLASH_CR_SSN | FLASH_CR_SER | FLASH_CR_START), \
|
|
((Sector << FLASH_CR_SSN_Pos) | FLASH_CR_SER | FLASH_CR_START));
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the write protection of the desired sectors.
|
|
*
|
|
* @note To configure the WRP options, the option lock bit OPTLOCK must be
|
|
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
|
*
|
|
* @param WRPState
|
|
*
|
|
* @param WRPSector
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_WRPSTATE(WRPState));
|
|
|
|
/* Configure the write protected area */
|
|
if (WRPState == OB_WRPSTATE_DISABLE)
|
|
{
|
|
FLASH->WRPSRP |= (WRPSector & FLASH_WRPSRP_WRPS);
|
|
}
|
|
else if (WRPState == OB_WRPSTATE_ENABLE)
|
|
{
|
|
FLASH->WRPSRP &= (~(WRPSector & FLASH_WRPSRP_WRPS));
|
|
}
|
|
else
|
|
{
|
|
/* Empty statement (to be compliant MISRA 15.7) */
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @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.
|
|
* @param UserType: The FLASH User Option Bytes to be modified.
|
|
* This parameter can be a combination of @ref FLASH_OB_USER_TYPE
|
|
* @param UserConfig1 The selected User Option Bytes values
|
|
* @param UserConfig2 The selected User Option Bytes values
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2)
|
|
{
|
|
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_BOR_LEV) != 0U)
|
|
{
|
|
/* BOR level option byte should be modified */
|
|
assert_param(IS_OB_USER_BOR_LEVEL(UserConfig1 & FLASH_OBW1SR_BOR_LEVEL));
|
|
|
|
/* Set value and mask for BOR level option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_BOR_LEVEL);
|
|
optr_reg_mask |= FLASH_OBW1SR_BOR_LEVEL;
|
|
}
|
|
|
|
if ((UserType & OB_USER_IWDG_SW) != 0U)
|
|
{
|
|
/* IWDG1_HW option byte should be modified */
|
|
assert_param(IS_OB_USER_IWDG(UserConfig1 & FLASH_OBW1SR_IWDG_HW));
|
|
|
|
/* Set value and mask for IWDG1_HW option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_HW);
|
|
optr_reg_mask |= FLASH_OBW1SR_IWDG_HW;
|
|
}
|
|
|
|
if ((UserType & OB_USER_NRST_STOP) != 0U)
|
|
{
|
|
/* NRST_STOP_D1 option byte should be modified */
|
|
assert_param(IS_OB_USER_STOP(UserConfig1 & FLASH_OBW1SR_NRST_STOP));
|
|
|
|
/* Set value and mask for NRST_STOP_D1 option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STOP);
|
|
optr_reg_mask |= FLASH_OBW1SR_NRST_STOP;
|
|
}
|
|
|
|
if ((UserType & OB_USER_NRST_STDBY) != 0U)
|
|
{
|
|
/* NRST_STBY_D1 option byte should be modified */
|
|
assert_param(IS_OB_USER_STANDBY(UserConfig1 & FLASH_OBW1SR_NRST_STBY));
|
|
|
|
/* Set value and mask for NRST_STBY_D1 option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STBY);
|
|
optr_reg_mask |= FLASH_OBW1SR_NRST_STBY;
|
|
}
|
|
|
|
if ((UserType & OB_USER_XSPI1_HSLV) != 0U)
|
|
{
|
|
/* XSPI1_HSLV option byte should be modified */
|
|
assert_param(IS_OB_USER_XSPI1_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV));
|
|
|
|
/* Set value and mask for XSPI1_HSLV option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV);
|
|
optr_reg_mask |= FLASH_OBW1SR_XSPI1_HSLV;
|
|
}
|
|
|
|
if ((UserType & OB_USER_XSPI2_HSLV) != 0U)
|
|
{
|
|
/* XSPI2_HSLV option byte should be modified */
|
|
assert_param(IS_OB_USER_XSPI2_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV));
|
|
|
|
/* Set value and mask for XSPI2_HSLV option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV);
|
|
optr_reg_mask |= FLASH_OBW1SR_XSPI2_HSLV;
|
|
}
|
|
|
|
if ((UserType & OB_USER_IWDG_STOP) != 0U)
|
|
{
|
|
/* IWDG_FZ_STOP option byte should be modified */
|
|
assert_param(IS_OB_USER_IWDG_STOP(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP));
|
|
|
|
/* Set value and mask for IWDG_FZ_STOP option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP);
|
|
optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STOP;
|
|
}
|
|
|
|
if ((UserType & OB_USER_IWDG_STDBY) != 0U)
|
|
{
|
|
/* IWDG_FZ_SDBY option byte should be modified */
|
|
assert_param(IS_OB_USER_IWDG_STDBY(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY));
|
|
|
|
/* Set value and mask for IWDG_FZ_SDBY option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY);
|
|
optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STBY;
|
|
}
|
|
|
|
if ((UserType & OB_USER_VDDIO_HSLV) != 0U)
|
|
{
|
|
/* VDDIO_HSLV option byte should be modified */
|
|
assert_param(IS_OB_USER_VDDIO_HSLV(UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV));
|
|
|
|
/* Set value and mask for VDDIO_HSLV option byte */
|
|
optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV);
|
|
optr_reg_mask |= FLASH_OBW1SR_VDDIO_HSLV;
|
|
}
|
|
|
|
/* Configure the option bytes register 1 if necessary */
|
|
if (optr_reg_mask != 0U)
|
|
{
|
|
MODIFY_REG(FLASH->OBW1SRP, optr_reg_mask, optr_reg_val);
|
|
}
|
|
|
|
optr_reg_val = 0;
|
|
optr_reg_mask = 0;
|
|
|
|
if ((UserType & OB_USER_ITCM_AXI_SHARE) != 0U)
|
|
{
|
|
/* ITCM_AXI_SHARE option byte should be modified */
|
|
assert_param(IS_OB_USER_ITCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE));
|
|
|
|
/* Set value and mask for ITCM_AXI_SHARE option byte */
|
|
optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE);
|
|
optr_reg_mask |= FLASH_OBW2SR_ITCM_AXI_SHARE;
|
|
}
|
|
|
|
if ((UserType & OB_USER_DTCM_AXI_SHARE) != 0U)
|
|
{
|
|
/* DTCM_AXI_SHARE option byte should be modified */
|
|
assert_param(IS_OB_USER_DTCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE));
|
|
|
|
/* Set value and mask for DTCM_AXI_SHARE option byte */
|
|
optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE);
|
|
optr_reg_mask |= FLASH_OBW2SR_DTCM_AXI_SHARE;
|
|
}
|
|
|
|
if ((UserType & OB_USER_SRAM_ECC) != 0U)
|
|
{
|
|
/* SRAM_ECC option byte should be modified */
|
|
assert_param(IS_OB_USER_AXISRAM_ECC(UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM));
|
|
|
|
/* Set value and mask for SRAM_ECC option byte */
|
|
optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM);
|
|
optr_reg_mask |= FLASH_OBW2SR_ECC_ON_SRAM;
|
|
}
|
|
|
|
if ((UserType & OB_USER_I2C_NI3C) != 0U)
|
|
{
|
|
/* I2C_NI3C option byte should be modified */
|
|
assert_param(IS_OB_USER_I2C_NI3C(UserConfig2 & FLASH_OBW2SR_I2C_NI3C));
|
|
|
|
/* Set value and mask for I2C_NI3C option byte */
|
|
optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_I2C_NI3C);
|
|
optr_reg_mask |= FLASH_OBW2SR_I2C_NI3C;
|
|
}
|
|
|
|
/* Configure the option bytes register 2 if necessary */
|
|
if (optr_reg_mask != 0U)
|
|
{
|
|
MODIFY_REG(FLASH->OBW2SRP, optr_reg_mask, optr_reg_val);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the Hide Protection.
|
|
*
|
|
* @note To configure the HDP options, the option lock bit OPTLOCK must be
|
|
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
|
*
|
|
* @param HDPStartPage
|
|
*
|
|
* @param HDPEndPage
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_OB_HDP_PAGE(HDPStartPage));
|
|
assert_param(IS_OB_HDP_PAGE(HDPEndPage));
|
|
|
|
MODIFY_REG(FLASH->HDPSRP, (FLASH_HDPSRP_HDP_AREA_START | FLASH_HDPSRP_HDP_AREA_END), \
|
|
(HDPStartPage | (HDPEndPage << FLASH_HDPSRP_HDP_AREA_END_Pos)));
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the Non-Volatile state.
|
|
*
|
|
* @note To configure the Non-volatile options, the option lock bit OPTLOCK must be
|
|
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
|
*
|
|
* @param NVState
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_NVConfig(uint32_t NVState)
|
|
{
|
|
/* Check the parameter */
|
|
assert_param(IS_OB_NVSTATE(NVState));
|
|
|
|
MODIFY_REG(FLASH->NVSRP, FLASH_NVSRP_NVSTATE, NVState);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Write Protection Option Bytes value.
|
|
*
|
|
* @param WRPState
|
|
*
|
|
* @param WRPSector
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector)
|
|
{
|
|
if ((FLASH->WRPSR & FLASH_WRPSR_WRPS) == FLASH_WRPSR_WRPS)
|
|
{
|
|
/* All sectors aren't write protected */
|
|
*WRPState = OB_WRPSTATE_DISABLE;
|
|
}
|
|
else
|
|
{
|
|
/* Some sectors are write protected */
|
|
*WRPState = OB_WRPSTATE_ENABLE;
|
|
*WRPSector = ((~(FLASH->WRPSR)) & FLASH_WRPSR_WRPS);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH User Option Byte value.
|
|
*
|
|
* @param UserConfig1 Address to return the FLASH User Option Bytes values configuration 1.
|
|
* The return value can be a combination of
|
|
* @param UserConfig2 Address to return the FLASH User Option Bytes values configuration 2.
|
|
* The return value can be a combination of
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2)
|
|
{
|
|
*UserConfig1 = FLASH->OBW1SR;
|
|
*UserConfig2 = FLASH->OBW2SR;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Hide Protection Option Bytes value.
|
|
*
|
|
* @param HDPStartPage Address to return the FLASH HDP Option Bytes Start Sector.
|
|
* The return value can be a combination of
|
|
* @param HDPEndPage Address to return the FLASH HDP Option Bytes End Sector.
|
|
* The return value can be a combination of
|
|
*
|
|
* @retval None
|
|
*/
|
|
static void FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage)
|
|
{
|
|
*HDPStartPage = (FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_START);
|
|
*HDPEndPage = ((FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_END) >> FLASH_HDPSR_HDP_AREA_END_Pos);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Non-volatile state Option Bytes value.
|
|
*
|
|
* @retval Value of Non-volatile state
|
|
*/
|
|
static uint32_t FLASH_OB_GetNV(void)
|
|
{
|
|
return (FLASH->NVSR & FLASH_NVSR_NVSTATE);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH RoT Option Bytes value.
|
|
*
|
|
* @retval Value of the RoT
|
|
*/
|
|
static uint32_t FLASH_OB_GetRoT(void)
|
|
{
|
|
return (FLASH->ROTSR & (FLASH_ROTSR_OEM_PROVD | FLASH_ROTSR_DBG_AUTH | FLASH_ROTSR_IROT_SELECT));
|
|
}
|
|
|
|
/**
|
|
* @brief Return the FLASH Epoch Option Bytes value.
|
|
*
|
|
* @retval Value of the Epoch
|
|
*/
|
|
static uint32_t FLASH_OB_GetEpoch(void)
|
|
{
|
|
return (FLASH->EPOCHSR & FLASH_EPOCHSR_EPOCH);
|
|
}
|
|
|
|
/**
|
|
* @brief Add a CRC sector to the list of sectors on which the CRC will be calculated
|
|
* @param Sector Specifies the CRC sector number
|
|
* @retval None
|
|
*/
|
|
static void FLASH_CRC_AddSector(uint32_t Sector)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_FLASH_SECTOR(Sector));
|
|
|
|
/* Clear CRC sector */
|
|
MODIFY_REG(FLASH->CRCCR, FLASH_CRCCR_CRC_SECT, Sector);
|
|
|
|
/* Activate ADD_SECT bit */
|
|
SET_BIT(FLASH->CRCCR, 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
|
|
* @retval None
|
|
*/
|
|
static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr)
|
|
{
|
|
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCStartAddr));
|
|
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCEndAddr));
|
|
|
|
/* Write CRC Start and End addresses */
|
|
FLASH->CRCSADDR = (CRCStartAddr - FLASH_BASE);
|
|
FLASH->CRCEADDR = (CRCEndAddr - FLASH_BASE);
|
|
}
|
|
|
|
/**
|
|
* @brief Wait for a FLASH CRC computation to complete.
|
|
* @param Timeout maximum flash operation timeout
|
|
* @retval HAL_StatusTypeDef HAL Status
|
|
*/
|
|
static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout)
|
|
{
|
|
uint32_t tickstart = HAL_GetTick();
|
|
|
|
/* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
|
|
while ((FLASH->SR & FLASH_SR_CRC_BUSY) != 0U)
|
|
{
|
|
if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Check FLASH CRC calculation error flag */
|
|
if ((FLASH->ISR & FLASH_FLAG_CRCERR) != 0U)
|
|
{
|
|
/*Save the error code*/
|
|
pFlash.ErrorCode |= HAL_FLASH_ERROR_CRC;
|
|
|
|
/* Clear CRC error flag */
|
|
FLASH->ICR = FLASH_FLAG_CRCERR;
|
|
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
/* Check FLASH CRC End of Calculation flag */
|
|
if ((FLASH->ISR & FLASH_FLAG_CRCEND) != 0U)
|
|
{
|
|
/* Clear FLASH End of Calculation pending bit */
|
|
FLASH->ICR = FLASH_FLAG_CRCEND;
|
|
}
|
|
|
|
/* If there is no error flag set */
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|