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