]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_MPU_M3_NUCLEO_L152RE_GCC/ST_Code/Drivers/STM32L1xx_HAL_Driver/Src/stm32l1xx_hal_flash_ex.c
Add MPU demo project for Nulceo-L152RE which is Coretx-M3.
[freertos] / FreeRTOS / Demo / CORTEX_MPU_M3_NUCLEO_L152RE_GCC / ST_Code / Drivers / STM32L1xx_HAL_Driver / Src / stm32l1xx_hal_flash_ex.c
diff --git a/FreeRTOS/Demo/CORTEX_MPU_M3_NUCLEO_L152RE_GCC/ST_Code/Drivers/STM32L1xx_HAL_Driver/Src/stm32l1xx_hal_flash_ex.c b/FreeRTOS/Demo/CORTEX_MPU_M3_NUCLEO_L152RE_GCC/ST_Code/Drivers/STM32L1xx_HAL_Driver/Src/stm32l1xx_hal_flash_ex.c
new file mode 100644 (file)
index 0000000..03c00a6
--- /dev/null
@@ -0,0 +1,1873 @@
+/**\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>&copy; 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