--- /dev/null
+/**\r
+ ******************************************************************************\r
+ * @file stm32l4xx_hal_flash_ex.c\r
+ * @author MCD Application Team\r
+ * @brief Extended FLASH HAL module driver.\r
+ * This file provides firmware functions to manage the following\r
+ * functionalities of the FLASH extended peripheral:\r
+ * + Extended programming operations functions\r
+ *\r
+ @verbatim\r
+ ==============================================================================\r
+ ##### Flash Extended features #####\r
+ ==============================================================================\r
+\r
+ [..] Comparing to other previous devices, the FLASH interface for STM32L4xx\r
+ devices contains the following additional features\r
+\r
+ (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write\r
+ capability (RWW)\r
+ (+) Dual bank memory organization\r
+ (+) PCROP protection for all banks\r
+\r
+ ##### How to use this driver #####\r
+ ==============================================================================\r
+ [..] This driver provides functions to configure and program the FLASH memory\r
+ of all STM32L4xx devices. It includes\r
+ (#) Flash Memory Erase functions:\r
+ (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and\r
+ HAL_FLASH_Lock() functions\r
+ (++) Erase function: Erase page, erase all sectors\r
+ (++) There are two modes of erase :\r
+ (+++) Polling Mode using HAL_FLASHEx_Erase()\r
+ (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()\r
+\r
+ (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :\r
+ (++) Set/Reset the write protection\r
+ (++) Set the Read protection Level\r
+ (++) Program the user Option Bytes\r
+ (++) Configure the PCROP protection\r
+\r
+ (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :\r
+ (++) Get the value of a write protection area\r
+ (++) Know if the read protection is activated\r
+ (++) Get the value of the user Option Bytes\r
+ (++) Get the value of a PCROP area\r
+\r
+ @endverbatim\r
+ ******************************************************************************\r
+ * @attention\r
+ *\r
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.\r
+ * All rights reserved.</center></h2>\r
+ *\r
+ * This software component is licensed by ST under BSD 3-Clause license,\r
+ * the "License"; You may not use this file except in compliance with the\r
+ * License. You may obtain a copy of the License at:\r
+ * opensource.org/licenses/BSD-3-Clause\r
+ *\r
+ ******************************************************************************\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32l4xx_hal.h"\r
+\r
+/** @addtogroup STM32L4xx_HAL_Driver\r
+ * @{\r
+ */\r
+\r
+/** @defgroup FLASHEx FLASHEx\r
+ * @brief FLASH Extended HAL module driver\r
+ * @{\r
+ */\r
+\r
+#ifdef HAL_FLASH_MODULE_ENABLED\r
+\r
+/* Private typedef -----------------------------------------------------------*/\r
+/* Private define ------------------------------------------------------------*/\r
+/* Private macro -------------------------------------------------------------*/\r
+/* Private variables ---------------------------------------------------------*/\r
+/* Private function prototypes -----------------------------------------------*/\r
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions\r
+ * @{\r
+ */\r
+static void FLASH_MassErase(uint32_t Banks);\r
+static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);\r
+static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);\r
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);\r
+static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);\r
+static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset);\r
+static uint32_t FLASH_OB_GetRDP(void);\r
+static uint32_t FLASH_OB_GetUser(void);\r
+static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr);\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Exported functions -------------------------------------------------------*/\r
+/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions\r
+ * @{\r
+ */\r
+\r
+/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions\r
+ * @brief Extended IO operation functions\r
+ *\r
+@verbatim\r
+ ===============================================================================\r
+ ##### Extended programming operation functions #####\r
+ ===============================================================================\r
+ [..]\r
+ This subsection provides a set of functions allowing to manage the Extended FLASH\r
+ programming operations Operations.\r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+/**\r
+ * @brief Perform a mass erase or erase the specified FLASH memory pages.\r
+ * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that\r
+ * contains the configuration information for the erasing.\r
+ *\r
+ * @param[out] PageError : pointer to variable that contains the configuration\r
+ * information on faulty page in case of error (0xFFFFFFFF means that all\r
+ * the pages have been correctly erased)\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)\r
+{\r
+ HAL_StatusTypeDef status;\r
+ uint32_t page_index;\r
+\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if (status == HAL_OK)\r
+ {\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Deactivate the cache if they are activated to avoid data misbehavior */\r
+ if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)\r
+ {\r
+ /* Disable instruction cache */\r
+ __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();\r
+\r
+ if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
+ {\r
+ /* Disable data cache */\r
+ __HAL_FLASH_DATA_CACHE_DISABLE();\r
+ pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;\r
+ }\r
+ else\r
+ {\r
+ pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;\r
+ }\r
+ }\r
+ else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
+ {\r
+ /* Disable data cache */\r
+ __HAL_FLASH_DATA_CACHE_DISABLE();\r
+ pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;\r
+ }\r
+ else\r
+ {\r
+ pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
+ }\r
+\r
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
+ {\r
+ /* Mass erase to be done */\r
+ FLASH_MassErase(pEraseInit->Banks);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ /* If the erase operation is completed, disable the MER1 and MER2 Bits */\r
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));\r
+#else\r
+ /* If the erase operation is completed, disable the MER1 Bit */\r
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));\r
+#endif\r
+ }\r
+ else\r
+ {\r
+ /*Initialization of PageError variable*/\r
+ *PageError = 0xFFFFFFFFU;\r
+\r
+ for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)\r
+ {\r
+ FLASH_PageErase(page_index, pEraseInit->Banks);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the erase operation is completed, disable the PER Bit */\r
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));\r
+\r
+ if (status != HAL_OK)\r
+ {\r
+ /* In case of error, stop erase procedure and return the faulty address */\r
+ *PageError = page_index;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Flush the caches to be sure of the data consistency */\r
+ FLASH_FlushCaches();\r
+ }\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.\r
+ * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that\r
+ * contains the configuration information for the erasing.\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
+\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Deactivate the cache if they are activated to avoid data misbehavior */\r
+ if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)\r
+ {\r
+ /* Disable instruction cache */\r
+ __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();\r
+\r
+ if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
+ {\r
+ /* Disable data cache */\r
+ __HAL_FLASH_DATA_CACHE_DISABLE();\r
+ pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;\r
+ }\r
+ else\r
+ {\r
+ pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;\r
+ }\r
+ }\r
+ else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
+ {\r
+ /* Disable data cache */\r
+ __HAL_FLASH_DATA_CACHE_DISABLE();\r
+ pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;\r
+ }\r
+ else\r
+ {\r
+ pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
+ }\r
+\r
+ /* Enable End of Operation and Error interrupts */\r
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);\r
+\r
+ pFlash.Bank = pEraseInit->Banks;\r
+\r
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
+ {\r
+ /* Mass erase to be done */\r
+ pFlash.ProcedureOnGoing = FLASH_PROC_MASS_ERASE;\r
+ FLASH_MassErase(pEraseInit->Banks);\r
+ }\r
+ else\r
+ {\r
+ /* Erase by page to be done */\r
+ pFlash.ProcedureOnGoing = FLASH_PROC_PAGE_ERASE;\r
+ pFlash.NbPagesToErase = pEraseInit->NbPages;\r
+ pFlash.Page = pEraseInit->Page;\r
+\r
+ /*Erase 1st page and wait for IT */\r
+ FLASH_PageErase(pEraseInit->Page, pEraseInit->Banks);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Program Option bytes.\r
+ * @param pOBInit: pointer to an FLASH_OBInitStruct structure that\r
+ * contains the configuration information for the programming.\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OPTIONBYTE(pOBInit->OptionType));\r
+\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Write protection configuration */\r
+ if((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)\r
+ {\r
+ /* Configure of Write protection on the selected area */\r
+ if(FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset) != HAL_OK)\r
+ {\r
+ status = HAL_ERROR;\r
+ }\r
+\r
+ }\r
+\r
+ /* Read protection configuration */\r
+ if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)\r
+ {\r
+ /* Configure the Read protection level */\r
+ if(FLASH_OB_RDPConfig(pOBInit->RDPLevel) != HAL_OK)\r
+ {\r
+ status = HAL_ERROR;\r
+ }\r
+ }\r
+\r
+ /* User Configuration */\r
+ if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)\r
+ {\r
+ /* Configure the user option bytes */\r
+ if(FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig) != HAL_OK)\r
+ {\r
+ status = HAL_ERROR;\r
+ }\r
+ }\r
+\r
+ /* PCROP Configuration */\r
+ if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)\r
+ {\r
+ if (pOBInit->PCROPStartAddr != pOBInit->PCROPEndAddr)\r
+ {\r
+ /* Configure the Proprietary code readout protection */\r
+ if(FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr) != HAL_OK)\r
+ {\r
+ status = HAL_ERROR;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Get the Option bytes configuration.\r
+ * @param pOBInit: pointer to an FLASH_OBInitStruct structure that contains the\r
+ * configuration information.\r
+ * @note The fields pOBInit->WRPArea and pOBInit->PCROPConfig should indicate\r
+ * which area is requested for the WRP and PCROP, else no information will be returned\r
+ *\r
+ * @retval None\r
+ */\r
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)\r
+{\r
+ pOBInit->OptionType = (OPTIONBYTE_RDP | OPTIONBYTE_USER);\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB) ||\r
+ (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAB))\r
+#else\r
+ if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))\r
+#endif\r
+ {\r
+ pOBInit->OptionType |= OPTIONBYTE_WRP;\r
+ /* Get write protection on the selected area */\r
+ FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));\r
+ }\r
+\r
+ /* Get Read protection level */\r
+ pOBInit->RDPLevel = FLASH_OB_GetRDP();\r
+\r
+ /* Get the user option bytes */\r
+ pOBInit->USERConfig = FLASH_OB_GetUser();\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if((pOBInit->PCROPConfig == FLASH_BANK_1) || (pOBInit->PCROPConfig == FLASH_BANK_2))\r
+#else\r
+ if(pOBInit->PCROPConfig == FLASH_BANK_1)\r
+#endif\r
+ {\r
+ pOBInit->OptionType |= OPTIONBYTE_PCROP;\r
+ /* Get the Proprietary code readout protection */\r
+ FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr));\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#if defined (FLASH_CFGR_LVEN)\r
+/** @defgroup FLASHEx_Exported_Functions_Group2 Extended specific configuration functions\r
+ * @brief Extended specific configuration functions\r
+ *\r
+@verbatim\r
+ ===============================================================================\r
+ ##### Extended specific configuration functions #####\r
+ ===============================================================================\r
+ [..]\r
+ This subsection provides a set of functions allowing to manage the Extended FLASH\r
+ specific configurations.\r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Configuration of the LVE pin of the Flash (managed by power controller\r
+ * or forced to low in order to use an external SMPS)\r
+ * @param ConfigLVE: Configuration of the LVE pin,\r
+ * This parameter can be one of the following values:\r
+ * @arg FLASH_LVE_PIN_CTRL: LVE FLASH pin controlled by power controller\r
+ * @arg FLASH_LVE_PIN_FORCED: LVE FLASH pin enforced to low (external SMPS used)\r
+ *\r
+ * @note Before enforcing the LVE pin to low, the SOC should be in low voltage\r
+ * range 2 and the voltage VDD12 should be higher than 1.08V and SMPS is ON.\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_ConfigLVEPin(uint32_t ConfigLVE)\r
+{\r
+ HAL_StatusTypeDef status;\r
+\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_LVE_PIN(ConfigLVE));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if (status == HAL_OK)\r
+ {\r
+ /* Check that the voltage scaling is range 2 */\r
+ if (HAL_PWREx_GetVoltageRange() == PWR_REGULATOR_VOLTAGE_SCALE2)\r
+ {\r
+ /* Configure the LVEN bit */\r
+ MODIFY_REG(FLASH->CFGR, FLASH_CFGR_LVEN, ConfigLVE);\r
+\r
+ /* Check that the bit has been correctly configured */\r
+ if (READ_BIT(FLASH->CFGR, FLASH_CFGR_LVEN) != ConfigLVE)\r
+ {\r
+ status = HAL_ERROR;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Not allow to force Flash LVE pin if not in voltage range 2 */\r
+ status = HAL_ERROR;\r
+ }\r
+ }\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+#endif /* FLASH_CFGR_LVEN */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Private functions ---------------------------------------------------------*/\r
+\r
+/** @addtogroup FLASHEx_Private_Functions\r
+ * @{\r
+ */\r
+/**\r
+ * @brief Mass erase of FLASH memory.\r
+ * @param Banks: Banks to be erased\r
+ * This parameter can be one of the following values:\r
+ * @arg FLASH_BANK_1: Bank1 to be erased\r
+ * @arg FLASH_BANK_2: Bank2 to be erased\r
+ * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased\r
+ * @retval None\r
+ */\r
+static void FLASH_MassErase(uint32_t Banks)\r
+{\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) != 0U)\r
+#endif\r
+ {\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_BANK(Banks));\r
+\r
+ /* Set the Mass Erase Bit for the bank 1 if requested */\r
+ if((Banks & FLASH_BANK_1) != 0U)\r
+ {\r
+ SET_BIT(FLASH->CR, FLASH_CR_MER1);\r
+ }\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ /* Set the Mass Erase Bit for the bank 2 if requested */\r
+ if((Banks & FLASH_BANK_2) != 0U)\r
+ {\r
+ SET_BIT(FLASH->CR, FLASH_CR_MER2);\r
+ }\r
+#endif\r
+ }\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ else\r
+ {\r
+ SET_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));\r
+ }\r
+#endif\r
+\r
+ /* Proceed to erase all sectors */\r
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);\r
+}\r
+\r
+/**\r
+ * @brief Erase the specified FLASH memory page.\r
+ * @param Page: FLASH page to erase\r
+ * This parameter must be a value between 0 and (max number of pages in the bank - 1)\r
+ * @param Banks: Bank(s) where the page will be erased\r
+ * This parameter can be one of the following values:\r
+ * @arg FLASH_BANK_1: Page in bank 1 to be erased\r
+ * @arg FLASH_BANK_2: Page in bank 2 to be erased\r
+ * @retval None\r
+ */\r
+void FLASH_PageErase(uint32_t Page, uint32_t Banks)\r
+{\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_PAGE(Page));\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if(READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
+ {\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));\r
+\r
+ if((Banks & FLASH_BANK_1) != 0U)\r
+ {\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);\r
+ }\r
+ else\r
+ {\r
+ SET_BIT(FLASH->CR, FLASH_CR_BKER);\r
+ }\r
+ }\r
+#else\r
+ /* Prevent unused argument(s) compilation warning */\r
+ UNUSED(Banks);\r
+#endif\r
+\r
+ /* Proceed to erase the page */\r
+ MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));\r
+ SET_BIT(FLASH->CR, FLASH_CR_PER);\r
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);\r
+}\r
+\r
+/**\r
+ * @brief Flush the instruction and data caches.\r
+ * @retval None\r
+ */\r
+void FLASH_FlushCaches(void)\r
+{\r
+ FLASH_CacheTypeDef cache = pFlash.CacheToReactivate;\r
+\r
+ /* Flush instruction cache */\r
+ if((cache == FLASH_CACHE_ICACHE_ENABLED) ||\r
+ (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))\r
+ {\r
+ /* Reset instruction cache */\r
+ __HAL_FLASH_INSTRUCTION_CACHE_RESET();\r
+ /* Enable instruction cache */\r
+ __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();\r
+ }\r
+\r
+ /* Flush data cache */\r
+ if((cache == FLASH_CACHE_DCACHE_ENABLED) ||\r
+ (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))\r
+ {\r
+ /* Reset data cache */\r
+ __HAL_FLASH_DATA_CACHE_RESET();\r
+ /* Enable data cache */\r
+ __HAL_FLASH_DATA_CACHE_ENABLE();\r
+ }\r
+\r
+ /* Reset internal variable */\r
+ pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
+}\r
+\r
+/**\r
+ * @brief Configure the write protection of the desired pages.\r
+ *\r
+ * @note When the memory read protection level is selected (RDP level = 1),\r
+ * it is not possible to program or erase Flash memory if the CPU debug\r
+ * features are connected (JTAG or single wire) or boot code is being\r
+ * executed from RAM or System flash, even if WRP is not activated.\r
+ * @note To configure the WRP options, the option lock bit OPTLOCK must be\r
+ * cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
+ * @note To validate the WRP options, the option bytes must be reloaded\r
+ * through the call of the HAL_FLASH_OB_Launch() function.\r
+ *\r
+ * @param WRPArea: specifies the area to be configured.\r
+ * This parameter can be one of the following values:\r
+ * @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A\r
+ * @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B\r
+ * @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply for STM32L43x/STM32L44x devices)\r
+ * @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply for STM32L43x/STM32L44x devices)\r
+ *\r
+ * @param WRPStartOffset: specifies the start page of the write protected area\r
+ * This parameter can be page number between 0 and (max number of pages in the bank - 1)\r
+ *\r
+ * @param WRDPEndOffset: specifies the end page of the write protected area\r
+ * This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1)\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)\r
+{\r
+ HAL_StatusTypeDef status;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_WRPAREA(WRPArea));\r
+ assert_param(IS_FLASH_PAGE(WRPStartOffset));\r
+ assert_param(IS_FLASH_PAGE(WRDPEndOffset));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ {\r
+ /* Configure the write protected area */\r
+ if(WRPArea == OB_WRPAREA_BANK1_AREAA)\r
+ {\r
+ MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),\r
+ (WRPStartOffset | (WRDPEndOffset << 16)));\r
+ }\r
+ else if(WRPArea == OB_WRPAREA_BANK1_AREAB)\r
+ {\r
+ MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),\r
+ (WRPStartOffset | (WRDPEndOffset << 16)));\r
+ }\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ else if(WRPArea == OB_WRPAREA_BANK2_AREAA)\r
+ {\r
+ MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END),\r
+ (WRPStartOffset | (WRDPEndOffset << 16)));\r
+ }\r
+ else if(WRPArea == OB_WRPAREA_BANK2_AREAB)\r
+ {\r
+ MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END),\r
+ (WRPStartOffset | (WRDPEndOffset << 16)));\r
+ }\r
+#endif\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+\r
+ /* Set OPTSTRT Bit */\r
+ SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Set the read protection level.\r
+ *\r
+ * @note To configure the RDP level, the option lock bit OPTLOCK must be\r
+ * cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
+ * @note To validate the RDP level, the option bytes must be reloaded\r
+ * through the call of the HAL_FLASH_OB_Launch() function.\r
+ * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible\r
+ * to go back to level 1 or 0 !!!\r
+ *\r
+ * @param RDPLevel: specifies the read protection level.\r
+ * This parameter can be one of the following values:\r
+ * @arg OB_RDP_LEVEL_0: No protection\r
+ * @arg OB_RDP_LEVEL_1: Read protection of the memory\r
+ * @arg OB_RDP_LEVEL_2: Full chip protection\r
+ *\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)\r
+{\r
+ HAL_StatusTypeDef status;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_RDP_LEVEL(RDPLevel));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ {\r
+ /* Configure the RDP level in the option bytes register */\r
+ MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);\r
+\r
+ /* Set OPTSTRT Bit */\r
+ SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Program the FLASH User Option Byte.\r
+ *\r
+ * @note To configure the user option bytes, the option lock bit OPTLOCK must\r
+ * be cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
+ * @note To validate the user option bytes, the option bytes must be reloaded\r
+ * through the call of the HAL_FLASH_OB_Launch() function.\r
+ *\r
+ * @param UserType: The FLASH User Option Bytes to be modified\r
+ * @param UserConfig: The FLASH User Option Bytes values:\r
+ * BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), IWDG_SW(Bit16),\r
+ * IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19), BFB2(Bit20),\r
+ * DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).\r
+ *\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)\r
+{\r
+ uint32_t optr_reg_val = 0;\r
+ uint32_t optr_reg_mask = 0;\r
+ HAL_StatusTypeDef status;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_USER_TYPE(UserType));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ {\r
+ if((UserType & OB_USER_BOR_LEV) != 0U)\r
+ {\r
+ /* BOR level option byte should be modified */\r
+ assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));\r
+\r
+ /* Set value and mask for BOR level option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);\r
+ optr_reg_mask |= FLASH_OPTR_BOR_LEV;\r
+ }\r
+\r
+ if((UserType & OB_USER_nRST_STOP) != 0U)\r
+ {\r
+ /* nRST_STOP option byte should be modified */\r
+ assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));\r
+\r
+ /* Set value and mask for nRST_STOP option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);\r
+ optr_reg_mask |= FLASH_OPTR_nRST_STOP;\r
+ }\r
+\r
+ if((UserType & OB_USER_nRST_STDBY) != 0U)\r
+ {\r
+ /* nRST_STDBY option byte should be modified */\r
+ assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));\r
+\r
+ /* Set value and mask for nRST_STDBY option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);\r
+ optr_reg_mask |= FLASH_OPTR_nRST_STDBY;\r
+ }\r
+\r
+ if((UserType & OB_USER_nRST_SHDW) != 0U)\r
+ {\r
+ /* nRST_SHDW option byte should be modified */\r
+ assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));\r
+\r
+ /* Set value and mask for nRST_SHDW option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);\r
+ optr_reg_mask |= FLASH_OPTR_nRST_SHDW;\r
+ }\r
+\r
+ if((UserType & OB_USER_IWDG_SW) != 0U)\r
+ {\r
+ /* IWDG_SW option byte should be modified */\r
+ assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));\r
+\r
+ /* Set value and mask for IWDG_SW option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);\r
+ optr_reg_mask |= FLASH_OPTR_IWDG_SW;\r
+ }\r
+\r
+ if((UserType & OB_USER_IWDG_STOP) != 0U)\r
+ {\r
+ /* IWDG_STOP option byte should be modified */\r
+ assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));\r
+\r
+ /* Set value and mask for IWDG_STOP option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);\r
+ optr_reg_mask |= FLASH_OPTR_IWDG_STOP;\r
+ }\r
+\r
+ if((UserType & OB_USER_IWDG_STDBY) != 0U)\r
+ {\r
+ /* IWDG_STDBY option byte should be modified */\r
+ assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));\r
+\r
+ /* Set value and mask for IWDG_STDBY option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);\r
+ optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;\r
+ }\r
+\r
+ if((UserType & OB_USER_WWDG_SW) != 0U)\r
+ {\r
+ /* WWDG_SW option byte should be modified */\r
+ assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));\r
+\r
+ /* Set value and mask for WWDG_SW option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);\r
+ optr_reg_mask |= FLASH_OPTR_WWDG_SW;\r
+ }\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if((UserType & OB_USER_BFB2) != 0U)\r
+ {\r
+ /* BFB2 option byte should be modified */\r
+ assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));\r
+\r
+ /* Set value and mask for BFB2 option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);\r
+ optr_reg_mask |= FLASH_OPTR_BFB2;\r
+ }\r
+\r
+ if((UserType & OB_USER_DUALBANK) != 0U)\r
+ {\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ /* DUALBANK option byte should be modified */\r
+ assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DB1M));\r
+\r
+ /* Set value and mask for DUALBANK option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_DB1M);\r
+ optr_reg_mask |= FLASH_OPTR_DB1M;\r
+#else\r
+ /* DUALBANK option byte should be modified */\r
+ assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DUALBANK));\r
+\r
+ /* Set value and mask for DUALBANK option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_DUALBANK);\r
+ optr_reg_mask |= FLASH_OPTR_DUALBANK;\r
+#endif\r
+ }\r
+#endif\r
+\r
+ if((UserType & OB_USER_nBOOT1) != 0U)\r
+ {\r
+ /* nBOOT1 option byte should be modified */\r
+ assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));\r
+\r
+ /* Set value and mask for nBOOT1 option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);\r
+ optr_reg_mask |= FLASH_OPTR_nBOOT1;\r
+ }\r
+\r
+ if((UserType & OB_USER_SRAM2_PE) != 0U)\r
+ {\r
+ /* SRAM2_PE option byte should be modified */\r
+ assert_param(IS_OB_USER_SRAM2_PARITY(UserConfig & FLASH_OPTR_SRAM2_PE));\r
+\r
+ /* Set value and mask for SRAM2_PE option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_PE);\r
+ optr_reg_mask |= FLASH_OPTR_SRAM2_PE;\r
+ }\r
+\r
+ if((UserType & OB_USER_SRAM2_RST) != 0U)\r
+ {\r
+ /* SRAM2_RST option byte should be modified */\r
+ assert_param(IS_OB_USER_SRAM2_RST(UserConfig & FLASH_OPTR_SRAM2_RST));\r
+\r
+ /* Set value and mask for SRAM2_RST option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_RST);\r
+ optr_reg_mask |= FLASH_OPTR_SRAM2_RST;\r
+ }\r
+\r
+#if defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || \\r
+ defined (STM32L442xx) || defined (STM32L443xx) || defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if((UserType & OB_USER_nSWBOOT0) != 0U)\r
+ {\r
+ /* nSWBOOT0 option byte should be modified */\r
+ assert_param(IS_OB_USER_SWBOOT0(UserConfig & FLASH_OPTR_nSWBOOT0));\r
+\r
+ /* Set value and mask for nSWBOOT0 option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nSWBOOT0);\r
+ optr_reg_mask |= FLASH_OPTR_nSWBOOT0;\r
+ }\r
+\r
+ if((UserType & OB_USER_nBOOT0) != 0U)\r
+ {\r
+ /* nBOOT0 option byte should be modified */\r
+ assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));\r
+\r
+ /* Set value and mask for nBOOT0 option byte */\r
+ optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);\r
+ optr_reg_mask |= FLASH_OPTR_nBOOT0;\r
+ }\r
+#endif\r
+\r
+ /* Configure the option bytes register */\r
+ MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);\r
+\r
+ /* Set OPTSTRT Bit */\r
+ SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Configure the Proprietary code readout protection of the desired addresses.\r
+ *\r
+ * @note To configure the PCROP options, the option lock bit OPTLOCK must be\r
+ * cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
+ * @note To validate the PCROP options, the option bytes must be reloaded\r
+ * through the call of the HAL_FLASH_OB_Launch() function.\r
+ *\r
+ * @param PCROPConfig: specifies the configuration (Bank to be configured and PCROP_RDP option).\r
+ * This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2\r
+ * with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE\r
+ *\r
+ * @param PCROPStartAddr: specifies the start address of the Proprietary code readout protection\r
+ * This parameter can be an address between begin and end of the bank\r
+ *\r
+ * @param PCROPEndAddr: specifies the end address of the Proprietary code readout protection\r
+ * This parameter can be an address between PCROPStartAddr and end of the bank\r
+ *\r
+ * @retval HAL Status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)\r
+{\r
+ HAL_StatusTypeDef status;\r
+ uint32_t reg_value;\r
+ uint32_t bank1_addr;\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ uint32_t bank2_addr;\r
+#endif\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));\r
+ assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));\r
+ assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));\r
+ assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ {\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ /* Get the information about the bank swapping */\r
+ if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)\r
+ {\r
+ bank1_addr = FLASH_BASE;\r
+ bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
+ }\r
+ else\r
+ {\r
+ bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
+ bank2_addr = FLASH_BASE;\r
+ }\r
+#else\r
+ bank1_addr = FLASH_BASE;\r
+#endif\r
+\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
+ {\r
+ /* Configure the Proprietary code readout protection */\r
+ if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
+ {\r
+ reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);\r
+ MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);\r
+\r
+ reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);\r
+ MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);\r
+ }\r
+ else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
+ {\r
+ reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);\r
+ MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);\r
+\r
+ reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);\r
+ MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);\r
+ }\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ /* Configure the Proprietary code readout protection */\r
+ if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
+ {\r
+ reg_value = ((PCROPStartAddr - bank1_addr) >> 3);\r
+ MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);\r
+\r
+ reg_value = ((PCROPEndAddr - bank1_addr) >> 3);\r
+ MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);\r
+ }\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
+ {\r
+ reg_value = ((PCROPStartAddr - bank2_addr) >> 3);\r
+ MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);\r
+\r
+ reg_value = ((PCROPEndAddr - bank2_addr) >> 3);\r
+ MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);\r
+ }\r
+#endif\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+ }\r
+\r
+ MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));\r
+\r
+ /* Set OPTSTRT Bit */\r
+ SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Return the FLASH Write Protection Option Bytes value.\r
+ *\r
+ * @param[in] WRPArea: specifies the area to be returned.\r
+ * This parameter can be one of the following values:\r
+ * @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A\r
+ * @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B\r
+ * @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply to STM32L43x/STM32L44x devices)\r
+ * @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply to STM32L43x/STM32L44x devices)\r
+ *\r
+ * @param[out] WRPStartOffset: specifies the address where to copied the start page\r
+ * of the write protected area\r
+ *\r
+ * @param[out] WRDPEndOffset: specifies the address where to copied the end page of\r
+ * the write protected area\r
+ *\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset)\r
+{\r
+ /* Get the configuration of the write protected area */\r
+ if(WRPArea == OB_WRPAREA_BANK1_AREAA)\r
+ {\r
+ *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);\r
+ *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> 16);\r
+ }\r
+ else if(WRPArea == OB_WRPAREA_BANK1_AREAB)\r
+ {\r
+ *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);\r
+ *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> 16);\r
+ }\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ else if(WRPArea == OB_WRPAREA_BANK2_AREAA)\r
+ {\r
+ *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);\r
+ *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> 16);\r
+ }\r
+ else if(WRPArea == OB_WRPAREA_BANK2_AREAB)\r
+ {\r
+ *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);\r
+ *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> 16);\r
+ }\r
+#endif\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Return the FLASH Read Protection level.\r
+ * @retval FLASH ReadOut Protection Status:\r
+ * This return value can be one of the following values:\r
+ * @arg OB_RDP_LEVEL_0: No protection\r
+ * @arg OB_RDP_LEVEL_1: Read protection of the memory\r
+ * @arg OB_RDP_LEVEL_2: Full chip protection\r
+ */\r
+static uint32_t FLASH_OB_GetRDP(void)\r
+{\r
+ uint32_t rdp_level = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);\r
+\r
+ if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))\r
+ {\r
+ return (OB_RDP_LEVEL_1);\r
+ }\r
+ else\r
+ {\r
+ return (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP));\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Return the FLASH User Option Byte value.\r
+ * @retval The FLASH User Option Bytes values:\r
+ * For STM32L47x/STM32L48x devices :\r
+ * BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),\r
+ * IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),\r
+ * BFB2(Bit20), DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).\r
+ * For STM32L43x/STM32L44x devices :\r
+ * BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),\r
+ * IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),\r
+ * nBOOT1(Bit23), SRAM2_PE(Bit24), SRAM2_RST(Bit25), nSWBOOT0(Bit26) and nBOOT0(Bit27).\r
+ */\r
+static uint32_t FLASH_OB_GetUser(void)\r
+{\r
+ uint32_t user_config = READ_REG(FLASH->OPTR);\r
+ CLEAR_BIT(user_config, FLASH_OPTR_RDP);\r
+\r
+ return user_config;\r
+}\r
+\r
+/**\r
+ * @brief Return the FLASH Write Protection Option Bytes value.\r
+ *\r
+ * @param PCROPConfig [inout]: specifies the configuration (Bank to be configured and PCROP_RDP option).\r
+ * This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2\r
+ * with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE\r
+ *\r
+ * @param PCROPStartAddr [out]: specifies the address where to copied the start address\r
+ * of the Proprietary code readout protection\r
+ *\r
+ * @param PCROPEndAddr [out]: specifies the address where to copied the end address of\r
+ * the Proprietary code readout protection\r
+ *\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr)\r
+{\r
+ uint32_t reg_value;\r
+ uint32_t bank1_addr;\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ uint32_t bank2_addr;\r
+#endif\r
+\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ /* Get the information about the bank swapping */\r
+ if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)\r
+ {\r
+ bank1_addr = FLASH_BASE;\r
+ bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
+ }\r
+ else\r
+ {\r
+ bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
+ bank2_addr = FLASH_BASE;\r
+ }\r
+#else\r
+ bank1_addr = FLASH_BASE;\r
+#endif\r
+\r
+#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
+ {\r
+ if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
+ {\r
+ reg_value = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);\r
+ *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;\r
+\r
+ reg_value = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);\r
+ *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;\r
+ }\r
+ else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
+ {\r
+ reg_value = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);\r
+ *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;\r
+\r
+ reg_value = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);\r
+ *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;;\r
+ }\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
+ {\r
+ reg_value = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);\r
+ *PCROPStartAddr = (reg_value << 3) + bank1_addr;\r
+\r
+ reg_value = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);\r
+ *PCROPEndAddr = (reg_value << 3) + bank1_addr + 0x7U;\r
+ }\r
+#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
+ defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
+ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
+ else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
+ {\r
+ reg_value = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);\r
+ *PCROPStartAddr = (reg_value << 3) + bank2_addr;\r
+\r
+ reg_value = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);\r
+ *PCROPEndAddr = (reg_value << 3) + bank2_addr + 0x7U;\r
+ }\r
+#endif\r
+ else\r
+ {\r
+ /* Nothing to do */\r
+ }\r
+ }\r
+\r
+ *PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);\r
+}\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* HAL_FLASH_MODULE_ENABLED */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r