--- /dev/null
+/**\r
+ ******************************************************************************\r
+ * @file stm32l1xx_hal_flash_ex.c\r
+ * @author MCD Application Team\r
+ * @brief Extended FLASH HAL module driver.\r
+ * \r
+ * This file provides firmware functions to manage the following \r
+ * functionalities of the internal FLASH memory:\r
+ * + FLASH Interface configuration\r
+ * + FLASH Memory Erasing\r
+ * + DATA EEPROM Programming/Erasing\r
+ * + Option Bytes Programming\r
+ * + Interrupts management\r
+ * \r
+ @verbatim\r
+ ==============================================================================\r
+ ##### Flash peripheral Extended features #####\r
+ ==============================================================================\r
+ \r
+ [..] Comparing to other products, the FLASH interface for STM32L1xx\r
+ devices contains the following additional features \r
+ (+) Erase functions\r
+ (+) DATA_EEPROM memory management\r
+ (+) BOOT option bit configuration \r
+ (+) PCROP protection for all sectors\r
+ \r
+ ##### How to use this driver #####\r
+ ==============================================================================\r
+ [..] This driver provides functions to configure and program the FLASH memory \r
+ of all STM32L1xx. It includes:\r
+ (+) Full DATA_EEPROM erase and program management\r
+ (+) Boot activation\r
+ (+) PCROP protection configuration and control for all pages\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 "stm32l1xx_hal.h"\r
+\r
+/** @addtogroup STM32L1xx_HAL_Driver\r
+ * @{\r
+ */\r
+#ifdef HAL_FLASH_MODULE_ENABLED\r
+\r
+/** @addtogroup FLASH\r
+ * @{\r
+ */\r
+/** @addtogroup FLASH_Private_Variables\r
+ * @{\r
+ */\r
+/* Variables used for Erase pages under interruption*/\r
+extern FLASH_ProcessTypeDef pFlash;\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+ \r
+/** @defgroup FLASHEx FLASHEx\r
+ * @brief FLASH HAL Extension module driver\r
+ * @{\r
+ */\r
+\r
+/* Private typedef -----------------------------------------------------------*/\r
+/* Private define ------------------------------------------------------------*/\r
+/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants\r
+ * @{\r
+ */\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Private macro -------------------------------------------------------------*/\r
+/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros\r
+ * @{\r
+ */\r
+/**\r
+ * @}\r
+ */ \r
+\r
+/* Private variables ---------------------------------------------------------*/\r
+/* Private function prototypes -----------------------------------------------*/\r
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions\r
+ * @{\r
+ */\r
+void FLASH_PageErase(uint32_t PageAddress);\r
+static HAL_StatusTypeDef FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState);\r
+static void FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState);\r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC) \\r
+ || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \\r
+ || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD) \\r
+ || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)\r
+static void FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState);\r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */\r
+#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \\r
+ || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) \\r
+ || defined(STM32L162xE)\r
+static void FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState);\r
+#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */\r
+#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \\r
+ || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+static void FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState);\r
+#endif /* STM32L151xE || STM32L152xE || STM32L151xDX || ... */\r
+#if defined(FLASH_OBR_SPRMOD)\r
+static HAL_StatusTypeDef FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState);\r
+#endif /* FLASH_OBR_SPRMOD */\r
+#if defined(FLASH_OBR_nRST_BFB2)\r
+static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT);\r
+#endif /* FLASH_OBR_nRST_BFB2 */\r
+static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP);\r
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);\r
+static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR);\r
+static uint8_t FLASH_OB_GetRDP(void);\r
+static uint8_t FLASH_OB_GetUser(void);\r
+static uint8_t FLASH_OB_GetBOR(void);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data);\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data);\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Exported functions ---------------------------------------------------------*/\r
+/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions\r
+ * @{\r
+ */\r
+\r
+/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions\r
+ * @brief FLASH Memory Erasing functions\r
+ *\r
+@verbatim \r
+ ==============================================================================\r
+ ##### FLASH Erasing Programming functions ##### \r
+ ==============================================================================\r
+\r
+ [..] The FLASH Memory Erasing functions, includes the following functions:\r
+ (+) @ref HAL_FLASHEx_Erase: return only when erase has been done\r
+ (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback \r
+ is called with parameter 0xFFFFFFFF\r
+\r
+ [..] Any operation of erase should follow these steps:\r
+ (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and \r
+ program memory access.\r
+ (#) Call the desired function to erase page.\r
+ (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access \r
+ (recommended to protect the FLASH memory against possible unwanted operation).\r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+ \r
+/**\r
+ * @brief Erase the specified FLASH memory Pages \r
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function\r
+ * must be called before.\r
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access \r
+ * (recommended to protect the FLASH memory against possible unwanted operation)\r
+ * @note For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between\r
+ * 2 banks, user should perform pages erase by bank only.\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\r
+ * contains the configuration information on faulty page in case of error\r
+ * (0xFFFFFFFF means that all the pages have been correctly erased)\r
+ * \r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)\r
+{\r
+ HAL_StatusTypeDef status = HAL_ERROR;\r
+ uint32_t address = 0U;\r
+ \r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+\r
+ if (status == HAL_OK)\r
+ {\r
+ /*Initialization of PageError variable*/\r
+ *PageError = 0xFFFFFFFFU;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_NBPAGES(pEraseInit->NbPages));\r
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));\r
+ assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));\r
+\r
+#if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+ /* Check on which bank belongs the 1st address to erase */\r
+ if (pEraseInit->PageAddress < FLASH_BANK2_BASE)\r
+ {\r
+ /* BANK1 */\r
+ /* Check that last page to erase still belongs to BANK1 */\r
+ if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)\r
+ {\r
+ /* Last page does not belong to BANK1, erase procedure cannot be performed because memory is not\r
+ continuous */\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return HAL_ERROR;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* BANK2 */\r
+ /* Check that last page to erase still belongs to BANK2 */\r
+ if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)\r
+ {\r
+ /* Last page does not belong to BANK2, erase procedure cannot be performed because memory is not\r
+ continuous */\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return HAL_ERROR;\r
+ }\r
+ }\r
+#endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */\r
+\r
+ /* Erase page by page to be done*/\r
+ for(address = pEraseInit->PageAddress; \r
+ address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);\r
+ address += FLASH_PAGE_SIZE)\r
+ {\r
+ FLASH_PageErase(address);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+\r
+ /* If the erase operation is completed, disable the ERASE Bit */\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);\r
+\r
+ if (status != HAL_OK) \r
+ {\r
+ /* In case of error, stop erase procedure and return the faulty address */\r
+ *PageError = address;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Perform a page erase of the specified FLASH memory pages with interrupt enabled\r
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function\r
+ * must be called before.\r
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access \r
+ * (recommended to protect the FLASH memory against possible unwanted operation)\r
+ * End of erase is done when @ref HAL_FLASH_EndOfOperationCallback is called with parameter\r
+ * 0xFFFFFFFF\r
+ * @note For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between\r
+ * 2 banks, user should perform pages erase by bank only.\r
+ * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that\r
+ * contains the configuration information for the erasing.\r
+ * \r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)\r
+{\r
+ HAL_StatusTypeDef status = HAL_ERROR;\r
+\r
+ /* If procedure already ongoing, reject the next one */\r
+ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)\r
+ {\r
+ return HAL_ERROR;\r
+ }\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_NBPAGES(pEraseInit->NbPages));\r
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));\r
+ assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));\r
+\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+#if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+ /* Check on which bank belongs the 1st address to erase */\r
+ if (pEraseInit->PageAddress < FLASH_BANK2_BASE)\r
+ {\r
+ /* BANK1 */\r
+ /* Check that last page to erase still belongs to BANK1 */\r
+ if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)\r
+ {\r
+ /* Last page does not belong to BANK1, erase procedure cannot be performed because memory is not\r
+ continuous */\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return HAL_ERROR;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* BANK2 */\r
+ /* Check that last page to erase still belongs to BANK2 */\r
+ if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)\r
+ {\r
+ /* Last page does not belong to BANK2, erase procedure cannot be performed because memory is not\r
+ continuous */\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return HAL_ERROR;\r
+ }\r
+ }\r
+#endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if (status == HAL_OK)\r
+ {\r
+ /* Enable End of FLASH Operation and Error source interrupts */\r
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);\r
+ \r
+ pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;\r
+ pFlash.NbPagesToErase = pEraseInit->NbPages;\r
+ pFlash.Page = pEraseInit->PageAddress;\r
+\r
+ /*Erase 1st page and wait for IT*/\r
+ FLASH_PageErase(pEraseInit->PageAddress);\r
+ }\r
+ else\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions\r
+ * @brief Option Bytes Programming functions\r
+ *\r
+@verbatim \r
+ ==============================================================================\r
+ ##### Option Bytes Programming functions ##### \r
+ ============================================================================== \r
+\r
+ [..] Any operation of erase or program should follow these steps:\r
+ (#) Call the @ref HAL_FLASH_OB_Unlock() function to enable the Flash option control \r
+ register access.\r
+ (#) Call following function to program the desired option bytes.\r
+ (++) @ref HAL_FLASHEx_OBProgram:\r
+ - To Enable/Disable the desired sector write protection.\r
+ - To set the desired read Protection Level.\r
+ - To configure the user option Bytes: IWDG, STOP and the Standby.\r
+ - To Set the BOR level.\r
+ (#) Once all needed option bytes to be programmed are correctly written, call the\r
+ @ref HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process.\r
+ (#) Call the @ref HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended\r
+ to protect the option Bytes against possible unwanted operations).\r
+\r
+ [..] Proprietary code Read Out Protection (PcROP):\r
+ (#) The PcROP sector is selected by using the same option bytes as the Write\r
+ protection (nWRPi bits). As a result, these 2 options are exclusive each other.\r
+ (#) In order to activate the PcROP (change the function of the nWRPi option bits), \r
+ the SPRMOD option bit must be activated.\r
+ (#) The active value of nWRPi bits is inverted when PCROP mode is active, this\r
+ means: if SPRMOD = 1 and nWRPi = 1 (default value), then the user sector "i"\r
+ is read/write protected.\r
+ (#) To activate PCROP mode for Flash sector(s), you need to call the following function:\r
+ (++) @ref HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected\r
+ (++) @ref HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection\r
+ (#) PcROP is available only in STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices.\r
+\r
+@endverbatim\r
+ * @{\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_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)\r
+{\r
+ HAL_StatusTypeDef status = HAL_ERROR;\r
+ \r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OPTIONBYTE(pOBInit->OptionType));\r
+\r
+ /*Write protection configuration*/\r
+ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)\r
+ {\r
+ assert_param(IS_WRPSTATE(pOBInit->WRPState));\r
+ if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)\r
+ {\r
+ /* Enable of Write protection on the selected Sector*/\r
+ status = FLASH_OB_WRPConfig(pOBInit, ENABLE);\r
+ }\r
+ else\r
+ {\r
+ /* Disable of Write protection on the selected Sector*/\r
+ status = FLASH_OB_WRPConfig(pOBInit, DISABLE);\r
+ }\r
+ if (status != HAL_OK)\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return status;\r
+ }\r
+ }\r
+ \r
+ /* Read protection configuration*/\r
+ if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)\r
+ {\r
+ status = FLASH_OB_RDPConfig(pOBInit->RDPLevel);\r
+ if (status != HAL_OK)\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return status;\r
+ }\r
+ }\r
+ \r
+ /* USER configuration*/\r
+ if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)\r
+ {\r
+ status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW, \r
+ pOBInit->USERConfig & OB_STOP_NORST,\r
+ pOBInit->USERConfig & OB_STDBY_NORST);\r
+ if (status != HAL_OK)\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return status;\r
+ }\r
+ }\r
+\r
+ /* BOR Level configuration*/\r
+ if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)\r
+ {\r
+ status = FLASH_OB_BORConfig(pOBInit->BORLevel);\r
+ if (status != HAL_OK)\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ return status;\r
+ }\r
+ }\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Get the Option byte configuration\r
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that\r
+ * contains the configuration information for the programming.\r
+ * \r
+ * @retval None\r
+ */\r
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)\r
+{\r
+ pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;\r
+\r
+ /*Get WRP1*/\r
+ pOBInit->WRPSector0To31 = (uint32_t)(FLASH->WRPR1);\r
+\r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC) \\r
+ || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \\r
+ || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD) \\r
+ || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)\r
+ \r
+ /*Get WRP2*/\r
+ pOBInit->WRPSector32To63 = (uint32_t)(FLASH->WRPR2);\r
+\r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */\r
+ \r
+#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \\r
+ || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) \\r
+ || defined(STM32L162xE)\r
+ \r
+ /*Get WRP3*/\r
+ pOBInit->WRPSector64To95 = (uint32_t)(FLASH->WRPR3);\r
+\r
+#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */\r
+ \r
+#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \\r
+ || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+\r
+ /*Get WRP4*/\r
+ pOBInit->WRPSector96To127 = (uint32_t)(FLASH->WRPR4);\r
+\r
+#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */\r
+\r
+ /*Get RDP Level*/\r
+ pOBInit->RDPLevel = FLASH_OB_GetRDP();\r
+\r
+ /*Get USER*/\r
+ pOBInit->USERConfig = FLASH_OB_GetUser();\r
+\r
+ /*Get BOR Level*/\r
+ pOBInit->BORLevel = FLASH_OB_GetBOR();\r
+}\r
+\r
+#if defined(FLASH_OBR_SPRMOD) || defined(FLASH_OBR_nRST_BFB2)\r
+ \r
+/**\r
+ * @brief Program option bytes\r
+ * @note This function can be used only for Cat2 & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.\r
+ * @param pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that\r
+ * contains the configuration information for the programming.\r
+ * \r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)\r
+{\r
+ HAL_StatusTypeDef status = HAL_ERROR;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OBEX(pAdvOBInit->OptionType));\r
+\r
+#if defined(FLASH_OBR_SPRMOD)\r
+ \r
+ /* Program PCROP option byte*/\r
+ if ((pAdvOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)\r
+ {\r
+ /* Check the parameters */\r
+ assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState));\r
+ if (pAdvOBInit->PCROPState == OB_PCROP_STATE_ENABLE)\r
+ {\r
+ /*Enable of Write protection on the selected Sector*/\r
+ status = FLASH_OB_PCROPConfig(pAdvOBInit, ENABLE);\r
+ if (status != HAL_OK)\r
+ {\r
+ return status;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Disable of Write protection on the selected Sector*/ \r
+ status = FLASH_OB_PCROPConfig(pAdvOBInit, DISABLE);\r
+ if (status != HAL_OK)\r
+ {\r
+ return status;\r
+ }\r
+ }\r
+ }\r
+ \r
+#endif /* FLASH_OBR_SPRMOD */\r
+\r
+#if defined(FLASH_OBR_nRST_BFB2)\r
+ \r
+ /* Program BOOT config option byte */\r
+ if ((pAdvOBInit->OptionType & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG)\r
+ {\r
+ status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig);\r
+ }\r
+ \r
+#endif /* FLASH_OBR_nRST_BFB2 */\r
+\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Get the OBEX byte configuration\r
+ * @note This function can be used only for Cat2 & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.\r
+ * @param pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that\r
+ * contains the configuration information for the programming.\r
+ * \r
+ * @retval None\r
+ */\r
+void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)\r
+{\r
+ pAdvOBInit->OptionType = 0U;\r
+ \r
+#if defined(FLASH_OBR_SPRMOD)\r
+ \r
+ pAdvOBInit->OptionType |= OPTIONBYTE_PCROP;\r
+\r
+ /*Get PCROP state */\r
+ pAdvOBInit->PCROPState = (FLASH->OBR & FLASH_OBR_SPRMOD) >> POSITION_VAL(FLASH_OBR_SPRMOD);\r
+ \r
+ /*Get PCROP protected sector from 0 to 31 */\r
+ pAdvOBInit->PCROPSector0To31 = FLASH->WRPR1;\r
+ \r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)\r
+\r
+ /*Get PCROP protected sector from 32 to 63 */\r
+ pAdvOBInit->PCROPSector32To63 = FLASH->WRPR2;\r
+\r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC */\r
+#endif /* FLASH_OBR_SPRMOD */\r
+\r
+#if defined(FLASH_OBR_nRST_BFB2)\r
+ \r
+ pAdvOBInit->OptionType |= OPTIONBYTE_BOOTCONFIG;\r
+\r
+ /* Get Boot config OB */\r
+ pAdvOBInit->BootConfig = (FLASH->OBR & FLASH_OBR_nRST_BFB2) >> 16U;\r
+\r
+#endif /* FLASH_OBR_nRST_BFB2 */\r
+}\r
+\r
+#endif /* FLASH_OBR_SPRMOD || FLASH_OBR_nRST_BFB2 */\r
+\r
+#if defined(FLASH_OBR_SPRMOD)\r
+\r
+/**\r
+ * @brief Select the Protection Mode (SPRMOD).\r
+ * @note This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices\r
+ * @note Once SPRMOD bit is active, unprotection of a protected sector is not possible \r
+ * @note Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag\r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ uint16_t tmp1 = 0U;\r
+ uint32_t tmp2 = 0U;\r
+ uint8_t optiontmp = 0U;\r
+ uint16_t optiontmp2 = 0U;\r
+ \r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ /* Mask RDP Byte */\r
+ optiontmp = (uint8_t)(*(__IO uint8_t *)(OB_BASE)); \r
+ \r
+ /* Update Option Byte */\r
+ optiontmp2 = (uint16_t)(OB_PCROP_SELECTED | optiontmp); \r
+ \r
+ /* calculate the option byte to write */\r
+ tmp1 = (uint16_t)(~(optiontmp2 ));\r
+ tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));\r
+ \r
+ if(status == HAL_OK)\r
+ { \r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* program PCRop */\r
+ OB->RDP = tmp2;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ \r
+ /* Return the Read protection operation Status */\r
+ return status; \r
+}\r
+\r
+/**\r
+ * @brief Deselect the Protection Mode (SPRMOD).\r
+ * @note This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices\r
+ * @note Once SPRMOD bit is active, unprotection of a protected sector is not possible \r
+ * @note Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag\r
+ * @retval HAL status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ uint16_t tmp1 = 0U;\r
+ uint32_t tmp2 = 0U;\r
+ uint8_t optiontmp = 0U;\r
+ uint16_t optiontmp2 = 0U;\r
+ \r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ /* Mask RDP Byte */\r
+ optiontmp = (uint8_t)(*(__IO uint8_t *)(OB_BASE)); \r
+ \r
+ /* Update Option Byte */\r
+ optiontmp2 = (uint16_t)(OB_PCROP_DESELECTED | optiontmp); \r
+ \r
+ /* calculate the option byte to write */\r
+ tmp1 = (uint16_t)(~(optiontmp2 ));\r
+ tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));\r
+ \r
+ if(status == HAL_OK)\r
+ { \r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* program PCRop */\r
+ OB->RDP = tmp2;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ \r
+ /* Return the Read protection operation Status */\r
+ return status; \r
+}\r
+\r
+#endif /* FLASH_OBR_SPRMOD */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions\r
+ * @brief DATA EEPROM Programming functions\r
+ *\r
+@verbatim \r
+ ===============================================================================\r
+ ##### DATA EEPROM Programming functions ##### \r
+ =============================================================================== \r
+ \r
+ [..] Any operation of erase or program should follow these steps:\r
+ (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function to enable the data EEPROM access\r
+ and Flash program erase control register access.\r
+ (#) Call the desired function to erase or program data.\r
+ (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to disable the data EEPROM access\r
+ and Flash program erase control register access(recommended\r
+ to protect the DATA_EEPROM against possible unwanted operation).\r
+\r
+@endverbatim\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Unlocks the data memory and FLASH_PECR register access.\r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void)\r
+{\r
+ if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET)\r
+ { \r
+ /* Unlocking the Data memory and FLASH_PECR register access*/\r
+ FLASH->PEKEYR = FLASH_PEKEY1;\r
+ FLASH->PEKEYR = FLASH_PEKEY2;\r
+ }\r
+ else\r
+ {\r
+ return HAL_ERROR;\r
+ }\r
+ return HAL_OK; \r
+}\r
+\r
+/**\r
+ * @brief Locks the Data memory and FLASH_PECR register access.\r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void)\r
+{\r
+ /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */\r
+ SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);\r
+ \r
+ return HAL_OK;\r
+}\r
+\r
+/**\r
+ * @brief Erase a word in data memory.\r
+ * @param Address specifies the address to be erased.\r
+ * @param TypeErase Indicate the way to erase at a specified address.\r
+ * This parameter can be a value of @ref FLASH_Type_Program\r
+ * @note To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function\r
+ * must be called before.\r
+ * Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access\r
+ * and Flash program erase control register access(recommended to protect \r
+ * the DATA_EEPROM against possible unwanted operation).\r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t TypeErase, uint32_t Address)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_TYPEPROGRAMDATA(TypeErase));\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address));\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ if(TypeErase == FLASH_TYPEERASEDATA_WORD)\r
+ {\r
+ /* Write 00000000h to valid address in the data memory */\r
+ *(__IO uint32_t *) Address = 0x00000000U;\r
+ }\r
+\r
+ if(TypeErase == FLASH_TYPEERASEDATA_HALFWORD)\r
+ {\r
+ /* Write 0000h to valid address in the data memory */\r
+ *(__IO uint16_t *) Address = (uint16_t)0x0000;\r
+ }\r
+\r
+ if(TypeErase == FLASH_TYPEERASEDATA_BYTE)\r
+ {\r
+ /* Write 00h to valid address in the data memory */\r
+ *(__IO uint8_t *) Address = (uint8_t)0x00;\r
+ }\r
+\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ \r
+ /* Return the erase status */\r
+ return status;\r
+} \r
+\r
+/**\r
+ * @brief Program word at a specified address\r
+ * @note To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function\r
+ * must be called before.\r
+ * Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() to he data EEPROM access\r
+ * and Flash program erase control register access(recommended to protect \r
+ * the DATA_EEPROM against possible unwanted operation).\r
+ * @note The function @ref HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram() can be called before \r
+ * this function to configure the Fixed Time Programming.\r
+ * @param TypeProgram Indicate the way to program at a specified address.\r
+ * This parameter can be a value of @ref FLASHEx_Type_Program_Data\r
+ * @param Address specifie the address to be programmed.\r
+ * @param Data specifie the data to be programmed\r
+ * \r
+ * @retval HAL_StatusTypeDef HAL Status\r
+ */\r
+\r
+HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_ERROR;\r
+ \r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_TYPEPROGRAMDATA(TypeProgram));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ if(TypeProgram == FLASH_TYPEPROGRAMDATA_WORD)\r
+ {\r
+ /* Program word (32-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_ProgramWord(Address, (uint32_t) Data);\r
+ }\r
+ else if(TypeProgram == FLASH_TYPEPROGRAMDATA_HALFWORD)\r
+ {\r
+ /* Program halfword (16-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_ProgramHalfWord(Address, (uint16_t) Data);\r
+ }\r
+ else if(TypeProgram == FLASH_TYPEPROGRAMDATA_BYTE)\r
+ {\r
+ /* Program byte (8-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_ProgramByte(Address, (uint8_t) Data);\r
+ }\r
+ else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTBYTE)\r
+ {\r
+ /*Program word (8-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_FastProgramByte(Address, (uint8_t) Data);\r
+ }\r
+ else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTHALFWORD)\r
+ {\r
+ /* Program halfword (16-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_FastProgramHalfWord(Address, (uint16_t) Data);\r
+ } \r
+ else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTWORD)\r
+ {\r
+ /* Program word (32-bit) at a specified address.*/\r
+ status = FLASH_DATAEEPROM_FastProgramWord(Address, (uint32_t) Data);\r
+ }\r
+ else\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 Enable DATA EEPROM fixed Time programming (2*Tprog).\r
+ * @retval None\r
+ */\r
+void HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)\r
+{\r
+ SET_BIT(FLASH->PECR, FLASH_PECR_FTDW);\r
+}\r
+\r
+/**\r
+ * @brief Disables DATA EEPROM fixed Time programming (2*Tprog).\r
+ * @retval None\r
+ */\r
+void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)\r
+{\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup FLASHEx_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/*\r
+==============================================================================\r
+ OPTIONS BYTES\r
+==============================================================================\r
+*/\r
+/**\r
+ * @brief Enables or disables the read out protection.\r
+ * @note To correctly run this function, the @ref HAL_FLASH_OB_Unlock() function\r
+ * must be called before.\r
+ * @param OB_RDP specifies the read protection level. \r
+ * This parameter can be:\r
+ * @arg @ref OB_RDP_LEVEL_0 No protection\r
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory\r
+ * @arg @ref OB_RDP_LEVEL_2 Chip protection\r
+ * \r
+ * !!!Warning!!! When enabling OB_RDP_LEVEL_2 it's no more possible to go back to level 1 or 0\r
+ * \r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OB_RDP(OB_RDP));\r
+ \r
+ tmp1 = (uint32_t)(OB->RDP & FLASH_OBR_RDPRT);\r
+ \r
+ /* According to errata sheet, DocID022054 Rev 5, par2.1.5\r
+ Before setting Level0 in the RDP register, check that the current level is not equal to Level0.\r
+ If the current level is not equal to Level0, Level0 can be activated.\r
+ If the current level is Level0 then the RDP register must not be written again with Level0. */\r
+ \r
+ if ((tmp1 == OB_RDP_LEVEL_0) && (OB_RDP == OB_RDP_LEVEL_0))\r
+ {\r
+ /*current level is Level0 then the RDP register must not be written again with Level0. */\r
+ status = HAL_ERROR;\r
+ }\r
+ else \r
+ {\r
+#if defined(FLASH_OBR_SPRMOD)\r
+ /* Mask SPRMOD bit */\r
+ tmp3 = (uint32_t)(OB->RDP & FLASH_OBR_SPRMOD);\r
+#endif\r
+\r
+ /* calculate the option byte to write */\r
+ tmp1 = (~((uint32_t)(OB_RDP | tmp3)));\r
+ tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)(OB_RDP | tmp3)));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* program read protection level */\r
+ OB->RDP = tmp2;\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ }\r
+\r
+ /* Return the Read protection operation Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Programs the FLASH brownout reset threshold level Option Byte.\r
+ * @param OB_BOR Selects the brownout reset threshold level.\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_BOR_OFF BOR is disabled at power down, the reset is asserted when the VDD \r
+ * power supply reaches the PDR(Power Down Reset) threshold (1.5V)\r
+ * @arg @ref OB_BOR_LEVEL1 BOR Reset threshold levels for 1.7V - 1.8V VDD power supply\r
+ * @arg @ref OB_BOR_LEVEL2 BOR Reset threshold levels for 1.9V - 2.0V VDD power supply\r
+ * @arg @ref OB_BOR_LEVEL3 BOR Reset threshold levels for 2.3V - 2.4V VDD power supply\r
+ * @arg @ref OB_BOR_LEVEL4 BOR Reset threshold levels for 2.55V - 2.65V VDD power supply\r
+ * @arg @ref OB_BOR_LEVEL5 BOR Reset threshold levels for 2.8V - 2.9V VDD power supply\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ uint32_t tmp = 0U, tmp1 = 0U;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_BOR_LEVEL(OB_BOR));\r
+\r
+ /* Get the User Option byte register */\r
+ tmp1 = OB->USER & ((~FLASH_OBR_BOR_LEV) >> 16U);\r
+\r
+ /* Calculate the option byte to write - [0xFFU | nUSER | 0x00U | USER]*/\r
+ tmp = (uint32_t)~((OB_BOR | tmp1)) << 16U;\r
+ tmp |= (OB_BOR | tmp1);\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ { \r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Write the BOR Option Byte */ \r
+ OB->USER = tmp;\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ \r
+ /* Return the Option Byte BOR Programming Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Returns the FLASH User Option Bytes values.\r
+ * @retval The FLASH User Option Bytes.\r
+ */\r
+static uint8_t FLASH_OB_GetUser(void)\r
+{\r
+ /* Return the User Option Byte */\r
+ return (uint8_t)((FLASH->OBR & (FLASH_OBR_IWDG_SW | FLASH_OBR_nRST_STOP | FLASH_OBR_nRST_STDBY)) >> 16U);\r
+}\r
+\r
+/**\r
+ * @brief Returns the FLASH Read Protection level.\r
+ * @retval FLASH RDP level\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_RDP_LEVEL_0 No protection\r
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory\r
+ * @arg @ref OB_RDP_LEVEL_2 Full chip protection\r
+ */\r
+static uint8_t FLASH_OB_GetRDP(void)\r
+{\r
+ uint8_t rdp_level = (uint8_t)(FLASH->OBR & FLASH_OBR_RDPRT);\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 (rdp_level);\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Returns the FLASH BOR level.\r
+ * @retval The BOR level Option Bytes.\r
+ */\r
+static uint8_t FLASH_OB_GetBOR(void)\r
+{\r
+ /* Return the BOR level */\r
+ return (uint8_t)((FLASH->OBR & (uint32_t)FLASH_OBR_BOR_LEV) >> 16U);\r
+}\r
+\r
+/**\r
+ * @brief Write protects the desired pages of the first 64KB of the Flash.\r
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that\r
+ * contains WRP parameters.\r
+ * @param NewState new state of the specified FLASH Pages Wtite protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval HAL_StatusTypeDef\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* WRP for sector between 0 to 31 */\r
+ if (pOBInit->WRPSector0To31 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP1OrPCROP1(pOBInit->WRPSector0To31, NewState);\r
+ }\r
+ \r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC) \\r
+ || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \\r
+ || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD) \\r
+ || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)\r
+ \r
+ /* Pages for Cat3, Cat4 & Cat5 devices*/\r
+ /* WRP for sector between 32 to 63 */\r
+ if (pOBInit->WRPSector32To63 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP2OrPCROP2(pOBInit->WRPSector32To63, NewState);\r
+ }\r
+ \r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */\r
+\r
+#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \\r
+ || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) \\r
+ || defined(STM32L162xE)\r
+ \r
+ /* Pages for devices with FLASH >= 256KB*/\r
+ /* WRP for sector between 64 to 95 */\r
+ if (pOBInit->WRPSector64To95 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP3(pOBInit->WRPSector64To95, NewState);\r
+ }\r
+ \r
+#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */\r
+\r
+#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \\r
+ || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+\r
+ /* Pages for Cat5 devices*/\r
+ /* WRP for sector between 96 to 127 */\r
+ if (pOBInit->WRPSector96To127 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP4(pOBInit->WRPSector96To127, NewState);\r
+ }\r
+ \r
+#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+\r
+ /* Return the write protection operation Status */\r
+ return status; \r
+}\r
+\r
+#if defined(STM32L151xBA) || defined(STM32L152xBA) || defined(STM32L151xC) || defined(STM32L152xC) \\r
+ || defined(STM32L162xC)\r
+/**\r
+ * @brief Enables the read/write protection (PCROP) of the desired \r
+ * sectors.\r
+ * @note This function can be used only for Cat2 & Cat3 devices\r
+ * @param pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that\r
+ * contains PCROP parameters.\r
+ * @param NewState new state of the specified FLASH Pages read/Write protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ FunctionalState pcropstate = DISABLE;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ /* Invert state to use same function of WRP */\r
+ if (NewState == DISABLE)\r
+ {\r
+ pcropstate = ENABLE;\r
+ }\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Pages for Cat2 devices*/\r
+ /* PCROP for sector between 0 to 31 */\r
+ if (pAdvOBInit->PCROPSector0To31 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP1OrPCROP1(pAdvOBInit->PCROPSector0To31, pcropstate);\r
+ }\r
+ \r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)\r
+\r
+ /* Pages for Cat3 devices*/\r
+ /* WRP for sector between 32 to 63 */\r
+ if (pAdvOBInit->PCROPSector32To63 != 0U)\r
+ {\r
+ FLASH_OB_WRPConfigWRP2OrPCROP2(pAdvOBInit->PCROPSector32To63, pcropstate);\r
+ }\r
+ \r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC */\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+\r
+ /* Return the write protection operation Status */\r
+ return status; \r
+}\r
+#endif /* STM32L151xBA || STM32L152xBA || STM32L151xC || STM32L152xC || STM32L162xC */\r
+\r
+/**\r
+ * @brief Write protects the desired pages of the first 128KB of the Flash.\r
+ * @param WRP1OrPCROP1 specifies the address of the pages to be write protected.\r
+ * This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection1\r
+ * @param NewState new state of the specified FLASH Pages Write protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState)\r
+{\r
+ uint32_t wrp01data = 0U, wrp23data = 0U;\r
+ \r
+ uint32_t tmp1 = 0U, tmp2 = 0U;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OB_WRP(WRP1OrPCROP1));\r
+ assert_param(IS_FUNCTIONAL_STATE(NewState));\r
+\r
+ if (NewState != DISABLE)\r
+ {\r
+ wrp01data = (uint16_t)(((WRP1OrPCROP1 & WRP_MASK_LOW) | OB->WRP01));\r
+ wrp23data = (uint16_t)((((WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U | OB->WRP23))); \r
+ tmp1 = (uint32_t)(~(wrp01data) << 16U)|(wrp01data);\r
+ OB->WRP01 = tmp1;\r
+\r
+ tmp2 = (uint32_t)(~(wrp23data) << 16U)|(wrp23data);\r
+ OB->WRP23 = tmp2; \r
+ }\r
+ else\r
+ {\r
+ wrp01data = (uint16_t)(~WRP1OrPCROP1 & (WRP_MASK_LOW & OB->WRP01));\r
+ wrp23data = (uint16_t)((((~WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U & OB->WRP23))); \r
+\r
+ tmp1 = (uint32_t)((~wrp01data) << 16U)|(wrp01data);\r
+ OB->WRP01 = tmp1;\r
+ \r
+ tmp2 = (uint32_t)((~wrp23data) << 16U)|(wrp23data);\r
+ OB->WRP23 = tmp2;\r
+ }\r
+}\r
+\r
+#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC) \\r
+ || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \\r
+ || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD) \\r
+ || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)\r
+/**\r
+ * @brief Enable Write protects the desired pages of the second 128KB of the Flash.\r
+ * @note This function can be used only for Cat3, Cat4 & Cat5 devices.\r
+ * @param WRP2OrPCROP2 specifies the address of the pages to be write protected.\r
+ * This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection2\r
+ * @param NewState new state of the specified FLASH Pages Wtite protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState)\r
+{\r
+ uint32_t wrp45data = 0U, wrp67data = 0U;\r
+ \r
+ uint32_t tmp1 = 0U, tmp2 = 0U;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OB_WRP(WRP2OrPCROP2));\r
+ assert_param(IS_FUNCTIONAL_STATE(NewState));\r
+\r
+ if (NewState != DISABLE)\r
+ {\r
+ wrp45data = (uint16_t)(((WRP2OrPCROP2 & WRP_MASK_LOW) | OB->WRP45));\r
+ wrp67data = (uint16_t)((((WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U | OB->WRP67))); \r
+ tmp1 = (uint32_t)(~(wrp45data) << 16U)|(wrp45data);\r
+ OB->WRP45 = tmp1;\r
+ \r
+ tmp2 = (uint32_t)(~(wrp67data) << 16U)|(wrp67data);\r
+ OB->WRP67 = tmp2;\r
+ }\r
+ else\r
+ {\r
+ wrp45data = (uint16_t)(~WRP2OrPCROP2 & (WRP_MASK_LOW & OB->WRP45));\r
+ wrp67data = (uint16_t)((((~WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U & OB->WRP67))); \r
+ \r
+ tmp1 = (uint32_t)((~wrp45data) << 16U)|(wrp45data);\r
+ OB->WRP45 = tmp1;\r
+ \r
+ tmp2 = (uint32_t)((~wrp67data) << 16U)|(wrp67data);\r
+ OB->WRP67 = tmp2;\r
+ }\r
+}\r
+#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */\r
+\r
+#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \\r
+ || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) \\r
+ || defined(STM32L162xE)\r
+/**\r
+ * @brief Enable Write protects the desired pages of the third 128KB of the Flash.\r
+ * @note This function can be used only for STM32L151xD, STM32L152xD, STM32L162xD & Cat5 devices.\r
+ * @param WRP3 specifies the address of the pages to be write protected.\r
+ * This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection3\r
+ * @param NewState new state of the specified FLASH Pages Wtite protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState)\r
+{\r
+ uint32_t wrp89data = 0U, wrp1011data = 0U;\r
+ \r
+ uint32_t tmp1 = 0U, tmp2 = 0U;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OB_WRP(WRP3));\r
+ assert_param(IS_FUNCTIONAL_STATE(NewState));\r
+\r
+ if (NewState != DISABLE)\r
+ {\r
+ wrp89data = (uint16_t)(((WRP3 & WRP_MASK_LOW) | OB->WRP89));\r
+ wrp1011data = (uint16_t)((((WRP3 & WRP_MASK_HIGH)>>16U | OB->WRP1011))); \r
+ tmp1 = (uint32_t)(~(wrp89data) << 16U)|(wrp89data);\r
+ OB->WRP89 = tmp1;\r
+\r
+ tmp2 = (uint32_t)(~(wrp1011data) << 16U)|(wrp1011data);\r
+ OB->WRP1011 = tmp2; \r
+ }\r
+ else\r
+ {\r
+ wrp89data = (uint16_t)(~WRP3 & (WRP_MASK_LOW & OB->WRP89));\r
+ wrp1011data = (uint16_t)((((~WRP3 & WRP_MASK_HIGH)>>16U & OB->WRP1011))); \r
+\r
+ tmp1 = (uint32_t)((~wrp89data) << 16U)|(wrp89data);\r
+ OB->WRP89 = tmp1;\r
+\r
+ tmp2 = (uint32_t)((~wrp1011data) << 16U)|(wrp1011data);\r
+ OB->WRP1011 = tmp2;\r
+ }\r
+}\r
+#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */\r
+\r
+#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \\r
+ || defined(STM32L152xDX) || defined(STM32L162xDX)\r
+/**\r
+ * @brief Enable Write protects the desired pages of the Fourth 128KB of the Flash.\r
+ * @note This function can be used only for Cat5 & STM32L1xxDX devices.\r
+ * @param WRP4 specifies the address of the pages to be write protected.\r
+ * This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection4\r
+ * @param NewState new state of the specified FLASH Pages Wtite protection.\r
+ * This parameter can be: ENABLE or DISABLE.\r
+ * @retval None\r
+ */\r
+static void FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState)\r
+{\r
+ uint32_t wrp1213data = 0U, wrp1415data = 0U;\r
+ \r
+ uint32_t tmp1 = 0U, tmp2 = 0U;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_OB_WRP(WRP4));\r
+ assert_param(IS_FUNCTIONAL_STATE(NewState));\r
+\r
+ if (NewState != DISABLE)\r
+ {\r
+ wrp1213data = (uint16_t)(((WRP4 & WRP_MASK_LOW) | OB->WRP1213));\r
+ wrp1415data = (uint16_t)((((WRP4 & WRP_MASK_HIGH)>>16U | OB->WRP1415))); \r
+ tmp1 = (uint32_t)(~(wrp1213data) << 16U)|(wrp1213data);\r
+ OB->WRP1213 = tmp1;\r
+\r
+ tmp2 = (uint32_t)(~(wrp1415data) << 16U)|(wrp1415data);\r
+ OB->WRP1415 = tmp2; \r
+ }\r
+ else\r
+ {\r
+ wrp1213data = (uint16_t)(~WRP4 & (WRP_MASK_LOW & OB->WRP1213));\r
+ wrp1415data = (uint16_t)((((~WRP4 & WRP_MASK_HIGH)>>16U & OB->WRP1415))); \r
+\r
+ tmp1 = (uint32_t)((~wrp1213data) << 16U)|(wrp1213data);\r
+ OB->WRP1213 = tmp1;\r
+\r
+ tmp2 = (uint32_t)((~wrp1415data) << 16U)|(wrp1415data);\r
+ OB->WRP1415 = tmp2;\r
+ }\r
+}\r
+#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */\r
+\r
+/**\r
+ * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.\r
+ * @param OB_IWDG Selects the WDG mode.\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_IWDG_SW Software WDG selected\r
+ * @arg @ref OB_IWDG_HW Hardware WDG selected\r
+ * @param OB_STOP Reset event when entering STOP mode.\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_STOP_NORST No reset generated when entering in STOP\r
+ * @arg @ref OB_STOP_RST Reset generated when entering in STOP\r
+ * @param OB_STDBY Reset event when entering Standby mode.\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_STDBY_NORST No reset generated when entering in STANDBY\r
+ * @arg @ref OB_STDBY_RST Reset generated when entering in STANDBY\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK; \r
+ uint32_t tmp = 0U, tmp1 = 0U;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));\r
+ assert_param(IS_OB_STOP_SOURCE(OB_STOP));\r
+ assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));\r
+\r
+ /* Get the User Option byte register */\r
+ tmp1 = OB->USER & ((~(FLASH_OBR_IWDG_SW | FLASH_OBR_nRST_STOP | FLASH_OBR_nRST_STDBY)) >> 16U);\r
+\r
+ /* Calculate the user option byte to write */ \r
+ tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << 16U);\r
+ tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1);\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ { \r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Write the User Option Byte */\r
+ OB->USER = tmp;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+\r
+ /* Return the Option Byte program Status */\r
+ return status;\r
+}\r
+\r
+#if defined(FLASH_OBR_nRST_BFB2)\r
+/**\r
+ * @brief Configures to boot from Bank1 or Bank2.\r
+ * @param OB_BOOT select the FLASH Bank to boot from.\r
+ * This parameter can be one of the following values:\r
+ * @arg @ref OB_BOOT_BANK2 At startup, if boot pins are set in boot from user Flash\r
+ * position and this parameter is selected the device will boot from Bank2 or Bank1,\r
+ * depending on the activation of the bank. The active banks are checked in\r
+ * the following order: Bank2, followed by Bank1.\r
+ * The active bank is recognized by the value programmed at the base address\r
+ * of the respective bank (corresponding to the initial stack pointer value\r
+ * in the interrupt vector table).\r
+ * @arg @ref OB_BOOT_BANK1 At startup, if boot pins are set in boot from user Flash\r
+ * position and this parameter is selected the device will boot from Bank1(Default).\r
+ * For more information, please refer to AN2606 from www.st.com. \r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK; \r
+ uint32_t tmp = 0U, tmp1 = 0U;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_OB_BOOT_BANK(OB_BOOT));\r
+\r
+ /* Get the User Option byte register and BOR Level*/\r
+ tmp1 = OB->USER & ((~FLASH_OBR_nRST_BFB2) >> 16U);\r
+\r
+ /* Calculate the option byte to write */\r
+ tmp = (uint32_t)~(OB_BOOT | tmp1) << 16U;\r
+ tmp |= (OB_BOOT | tmp1);\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+\r
+ if(status == HAL_OK)\r
+ { \r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Write the BOOT Option Byte */\r
+ OB->USER = tmp;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+\r
+ /* Return the Option Byte program Status */\r
+ return status;\r
+}\r
+\r
+#endif /* FLASH_OBR_nRST_BFB2 */\r
+\r
+/*\r
+==============================================================================\r
+ DATA\r
+==============================================================================\r
+*/\r
+\r
+/**\r
+ * @brief Write a Byte at a specified address in data memory.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @note This function assumes that the is data word is already erased.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ uint32_t tmp = 0U, tmpaddr = 0U;\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address)); \r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clear the FTDW bit */\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);\r
+\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ /* Possible only on Cat1 devices */\r
+ if(Data != (uint8_t)0x00U) \r
+ {\r
+ /* If the previous operation is completed, proceed to write the new Data */\r
+ *(__IO uint8_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ else\r
+ {\r
+ tmpaddr = Address & 0xFFFFFFFCU;\r
+ tmp = * (__IO uint32_t *) tmpaddr;\r
+ tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));\r
+ tmp &= ~tmpaddr;\r
+ status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+ }\r
+#else /*!Cat1*/ \r
+ /* If the previous operation is completed, proceed to write the new Data */\r
+ *(__IO uint8_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Writes a half word at a specified address in data memory.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @note This function assumes that the is data word is already erased.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ uint32_t tmp = 0U, tmpaddr = 0U;\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clear the FTDW bit */\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);\r
+\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ /* Possible only on Cat1 devices */\r
+ if(Data != (uint16_t)0x0000U) \r
+ {\r
+ /* If the previous operation is completed, proceed to write the new data */\r
+ *(__IO uint16_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ else\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ if((Address & 0x3U) != 0x3U)\r
+ {\r
+ tmpaddr = Address & 0xFFFFFFFCU;\r
+ tmp = * (__IO uint32_t *) tmpaddr;\r
+ tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));\r
+ tmp &= ~tmpaddr; \r
+ status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);\r
+ status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);\r
+ }\r
+ else\r
+ {\r
+ HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);\r
+ HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);\r
+ }\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+ }\r
+#else /* !Cat1 */\r
+ /* If the previous operation is completed, proceed to write the new data */\r
+ *(__IO uint16_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Programs a word at a specified address in data memory.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @note This function assumes that the is data word is already erased.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+\r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address));\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ /* Clear the FTDW bit */\r
+ CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);\r
+ \r
+ /* If the previous operation is completed, proceed to program the new data */ \r
+ *(__IO uint32_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); \r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Write a Byte at a specified address in data memory without erase.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ uint32_t tmp = 0U, tmpaddr = 0U;\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address)); \r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ if(Data != (uint8_t) 0x00U)\r
+ { \r
+ *(__IO uint8_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+\r
+ }\r
+ else\r
+ {\r
+ tmpaddr = Address & 0xFFFFFFFCU;\r
+ tmp = * (__IO uint32_t *) tmpaddr;\r
+ tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));\r
+ tmp &= ~tmpaddr; \r
+ status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+ }\r
+#else /* Not Cat1*/\r
+ *(__IO uint8_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Writes a half word at a specified address in data memory without erase.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ uint32_t tmp = 0U, tmpaddr = 0U;\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address));\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)\r
+ if(Data != (uint16_t)0x0000U)\r
+ {\r
+ *(__IO uint16_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ else\r
+ {\r
+ /* Process Unlocked */\r
+ __HAL_UNLOCK(&pFlash);\r
+ if((Address & 0x3U) != 0x3U)\r
+ {\r
+ tmpaddr = Address & 0xFFFFFFFCU;\r
+ tmp = * (__IO uint32_t *) tmpaddr;\r
+ tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));\r
+ tmp &= ~tmpaddr; \r
+ status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);\r
+ status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);\r
+ }\r
+ else\r
+ {\r
+ HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);\r
+ HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);\r
+ }\r
+ /* Process Locked */\r
+ __HAL_LOCK(&pFlash);\r
+ }\r
+#else /* Not Cat1*/\r
+ *(__IO uint16_t *)Address = Data;\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+#endif /* STM32L100xB || STM32L151xB || STM32L152xB */\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @brief Programs a word at a specified address in data memory without erase.\r
+ * @param Address specifies the address to be written.\r
+ * @param Data specifies the data to be written.\r
+ * @retval HAL status\r
+ */\r
+static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data)\r
+{\r
+ HAL_StatusTypeDef status = HAL_OK;\r
+ \r
+ /* Check the parameters */\r
+ assert_param(IS_FLASH_DATA_ADDRESS(Address));\r
+ \r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ \r
+ if(status == HAL_OK)\r
+ {\r
+ *(__IO uint32_t *)Address = Data;\r
+\r
+ /* Wait for last operation to be completed */\r
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);\r
+ }\r
+ /* Return the Write Status */\r
+ return status;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @addtogroup FLASH\r
+ * @{\r
+ */\r
+\r
+\r
+/** @addtogroup FLASH_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Erases a specified page in program memory.\r
+ * @param PageAddress The page address in program memory to be erased.\r
+ * @note A Page is erased in the Program memory only if the address to load \r
+ * is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes).\r
+ * @retval None\r
+ */\r
+void FLASH_PageErase(uint32_t PageAddress)\r
+{\r
+ /* Clean the error context */\r
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
+\r
+ /* Set the ERASE bit */\r
+ SET_BIT(FLASH->PECR, FLASH_PECR_ERASE);\r
+\r
+ /* Set PROG bit */\r
+ SET_BIT(FLASH->PECR, FLASH_PECR_PROG);\r
+\r
+ /* Write 00000000h to the first word of the program page to erase */\r
+ *(__IO uint32_t *)(uint32_t)(PageAddress & ~(FLASH_PAGE_SIZE - 1)) = 0x00000000;\r
+}\r
+ \r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* HAL_FLASH_MODULE_ENABLED */\r
+/**\r
+ * @}\r
+ */\r
+\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r