fix LPC812 PWM

Dependents:   IR_LED_Send

Fork of mbed-dev by mbed official

Revision:
124:6a4a5b7d7324
Parent:
0:9b334a45a8ff
--- a/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c	Thu May 05 21:00:11 2016 +0100
+++ b/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c	Mon May 09 18:30:12 2016 +0100
@@ -2,8 +2,8 @@
   ******************************************************************************
   * @file    stm32f1xx_hal_flash_ex.c
   * @author  MCD Application Team
-  * @version V1.0.0
-  * @date    15-December-2014
+  * @version V1.0.4
+  * @date    29-April-2016
   * @brief   Extended FLASH HAL module driver.
   *    
   *          This file provides firmware functions to manage the following 
@@ -30,7 +30,7 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
   *
   * Redistribution and use in source and binary forms, with or without modification,
   * are permitted provided that the following conditions are met:
@@ -82,7 +82,7 @@
   */
   
 /** @defgroup FLASHEx FLASHEx
-  * @brief FLASH Extended HAL module driver
+  * @brief FLASH HAL Extension module driver
   * @{
   */
 
@@ -91,6 +91,9 @@
 /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
  * @{
  */
+#define FLASH_POSITION_IWDGSW_BIT        (uint32_t)POSITION_VAL(FLASH_OBR_IWDG_SW)
+#define FLASH_POSITION_OB_USERDATA0_BIT  (uint32_t)POSITION_VAL(FLASH_OBR_DATA0)
+#define FLASH_POSITION_OB_USERDATA1_BIT  (uint32_t)POSITION_VAL(FLASH_OBR_DATA1)
 /**
   * @}
   */
@@ -118,13 +121,9 @@
 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
 static uint32_t          FLASH_OB_GetWRP(void);
-static FlagStatus        FLASH_OB_GetRDP(void);
+static uint32_t          FLASH_OB_GetRDP(void);
 static uint8_t           FLASH_OB_GetUser(void);
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-/* State operations */
-static HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout);
-#endif
 /**
   * @}
   */
@@ -134,13 +133,25 @@
   * @{
   */
   
-/** @defgroup FLASHEx_Exported_Functions_Group1 Extended Input and Output operation functions
-  * @brief      I/O operation functions
+/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
+ *  @brief   FLASH Memory Erasing functions
   *
 @verbatim   
- ===============================================================================
-                      ##### IO operation functions #####
- ===============================================================================  
+  ==============================================================================
+                ##### FLASH Erasing Programming functions ##### 
+  ==============================================================================
+
+    [..] The FLASH Memory Erasing functions, includes the following functions:
+    (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
+    (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback 
+        is called with parameter 0xFFFFFFFF
+
+    [..] Any operation of erase should follow these steps:
+    (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and 
+        program memory access.
+    (#) Call the desired function to erase page.
+    (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access 
+       (recommended to protect the FLASH memory against possible unwanted operation).
 
 @endverbatim
   * @{
@@ -149,12 +160,14 @@
 
 /**
   * @brief  Perform a mass erase or erase the specified FLASH memory pages
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
-  * @param[in]  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
+  * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
+  *         must be called before.
+  *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access 
+  *         (recommended to protect the FLASH memory against possible unwanted operation)
+  * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
   *         contains the configuration information for the erasing.
   *
-  * @param[out]  PageError: pointer to variable  that
+  * @param[out]  PageError pointer to variable  that
   *         contains the configuration information on faulty page in case of error
   *         (0xFFFFFFFF means that all the pages have been correctly erased)
   *
@@ -173,7 +186,7 @@
 
   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
   {
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
     if (pEraseInit->Banks == FLASH_BANK_BOTH)
     {
       /* Mass Erase requested for Bank1 and Bank2 */
@@ -213,7 +226,7 @@
       }
     }
     else 
-#endif /* STM32F101xG || STM32F103xG */
+#endif /* FLASH_BANK2_END */
     {
       /* Mass Erase requested for Bank1 */
       /* Wait for last operation to be completed */
@@ -237,7 +250,7 @@
     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
     
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
     /* Page Erase requested on address located on bank2 */
     if(pEraseInit->PageAddress > FLASH_BANK1_END)
     {   
@@ -270,47 +283,33 @@
       }
     }
     else
-#endif /* STM32F101xG || STM32F103xG */
-    {
+#endif /* FLASH_BANK2_END */
+   {
       /* Page Erase requested on address located on bank1 */
       /* Wait for last operation to be completed */
       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
       {
-        if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+        /*Initialization of PageError variable*/
+        *PageError = 0xFFFFFFFF;
+        
+        /* Erase page by page to be done*/
+        for(address = pEraseInit->PageAddress;
+            address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
+            address += FLASH_PAGE_SIZE)
         {
-          /*Mass erase to be done*/
-          FLASH_MassErase(pEraseInit->Banks);
+          FLASH_PageErase(address);
           
           /* Wait for last operation to be completed */
           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
           
-          /* If the erase operation is completed, disable the MER Bit */
-          CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
-        }
-        else
-        {
-          /*Initialization of PageError variable*/
-          *PageError = 0xFFFFFFFF;
+          /* If the erase operation is completed, disable the PER Bit */
+          CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
           
-          /* Erase by page by page to be done*/
-          for(address = pEraseInit->PageAddress;
-              address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
-              address += FLASH_PAGE_SIZE)
+          if (status != HAL_OK)
           {
-            FLASH_PageErase(address);
-            
-            /* Wait for last operation to be completed */
-            status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-            
-            /* If the erase operation is completed, disable the PER Bit */
-            CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
-            
-            if (status != HAL_OK)
-            {
-              /* In case of error, stop erase procedure and return the faulty address */
-              *PageError = address;
-              break;
-            }
+            /* In case of error, stop erase procedure and return the faulty address */
+            *PageError = address;
+            break;
           }
         }
       }
@@ -324,10 +323,12 @@
 }
 
 /**
-  * @brief  Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
-  * @param  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
+  * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
+  * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
+  *         must be called before.
+  *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access 
+  *         (recommended to protect the FLASH memory against possible unwanted operation)
+  * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
   *         contains the configuration information for the erasing.
   *
   * @retval HAL_StatusTypeDef HAL Status
@@ -349,18 +350,18 @@
   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
 
   /* Enable End of FLASH Operation and Error source interrupts */
-  __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR));
+  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
   /* Enable End of FLASH Operation and Error source interrupts */
-  __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2));
+  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+  
 #endif
-  
   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
   {
     /*Mass erase to be done*/
     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
-    FLASH_MassErase(pEraseInit->Banks);
+        FLASH_MassErase(pEraseInit->Banks);
   }
   else
   {
@@ -384,17 +385,17 @@
 /**
   * @}
   */
-    
-/** @defgroup FLASHEx_Exported_Functions_Group2 Extended Peripheral Control functions
-  * @brief      Peripheral Control functions
+
+/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
+ *  @brief   Option Bytes Programming functions
   *
 @verbatim   
- ===============================================================================
-                      ##### Peripheral Control functions #####
- ===============================================================================  
+  ==============================================================================
+                ##### Option Bytes Programming functions ##### 
+  ==============================================================================  
     [..]
     This subsection provides a set of functions allowing to control the FLASH 
-    memory operations.
+    option bytes operations.
 
 @endverbatim
   * @{
@@ -403,9 +404,9 @@
 /**
   * @brief  Erases the FLASH option bytes.
   * @note   This functions erases all option bytes except the Read protection (RDP).
-  *         The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
-  *         The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+  *         The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+  *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+  *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
   *         (system reset will occur)
   * @retval HAL status
   */
@@ -416,10 +417,7 @@
   HAL_StatusTypeDef status = HAL_ERROR;
 
   /* Get the actual read protection Option Byte value */
-  if(FLASH_OB_GetRDP() != RESET)
-  {
-    rdptmp = OB_RDP_LEVEL_1;
-  }
+  rdptmp = FLASH_OB_GetRDP();
 
   /* Wait for last operation to be completed */
   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
@@ -452,12 +450,12 @@
 
 /**
   * @brief  Program option bytes
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
-  *         The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+  * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+  *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+  *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
   *         (system reset will occur)
   *
-  * @param  pOBInit: pointer to an FLASH_OBInitStruct structure that
+  * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
   *         contains the configuration information for the programming.
   *
   * @retval HAL_StatusTypeDef HAL Status
@@ -466,6 +464,9 @@
 {
   HAL_StatusTypeDef status = HAL_ERROR;
 
+  /* Process Locked */
+  __HAL_LOCK(&pFlash);
+
   /* Check the parameters */
   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
 
@@ -483,32 +484,59 @@
       /* Disable of Write protection on the selected page */
       status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
     }
+    if (status != HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(&pFlash);
+      return status;
+    }
   }
 
   /* Read protection configuration */
   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
   {
     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
+    if (status != HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(&pFlash);
+      return status;
+    }
   }
 
   /* USER configuration */
   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
   {
     status = FLASH_OB_UserConfig(pOBInit->USERConfig);
+    if (status != HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(&pFlash);
+      return status;
+    }
   }
 
   /* DATA configuration*/
   if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
   {
     status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
+    if (status != HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(&pFlash);
+      return status;
+    }
   }
 
+  /* Process Unlocked */
+  __HAL_UNLOCK(&pFlash);
+
   return status;
 }
 
 /**
   * @brief  Get the Option byte configuration
-  * @param  pOBInit: pointer to an FLASH_OBInitStruct structure that
+  * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
   *         contains the configuration information for the programming.
   *
   * @retval None
@@ -528,6 +556,32 @@
 }
 
 /**
+  * @brief  Get the Option byte user data
+  * @param  DATAAdress Address of the option byte DATA
+  *          This parameter can be one of the following values:
+  *            @arg @ref OB_DATA_ADDRESS_DATA0
+  *            @arg @ref OB_DATA_ADDRESS_DATA1
+  * @retval Value programmed in USER data
+  */
+uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
+{
+  uint32_t value = 0;
+  
+  if (DATAAdress == OB_DATA_ADDRESS_DATA0)
+  {
+    /* Get value programmed in OB USER Data0 */
+    value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
+  }
+  else
+  {
+    /* Get value programmed in OB USER Data1 */
+    value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
+  }
+  
+  return value;
+}
+
+/**
   * @}
   */
 
@@ -541,13 +595,19 @@
 
 /**
   * @brief  Full erase of FLASH memory Bank 
-  * @param  Banks: Banks to be erased
+  * @param  Banks Banks to be erased
   *          This parameter can be one of the following values:
-  *            @arg FLASH_BANK_1: Bank1 to be erased
-  *            @arg FLASH_BANK_2: Bank2 to be erased
-  *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
+  *            @arg @ref FLASH_BANK_1 Bank1 to be erased
+  @if STM32F101xG
+  *            @arg @ref FLASH_BANK_2 Bank2 to be erased
+  *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+  @endif
+  @if STM32F103xG
+  *            @arg @ref FLASH_BANK_2 Bank2 to be erased
+  *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+  @endif
   *
-  * @retval HAL Status
+  * @retval None
   */
 static void FLASH_MassErase(uint32_t Banks)
 {
@@ -557,7 +617,7 @@
   /* Clean the error context */
   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
   if(Banks == FLASH_BANK_BOTH)
   {
     /* bank1 & bank2 will be erased*/
@@ -574,22 +634,23 @@
   }
   else
   {
-#endif /* STM32F101xG || STM32F103xG */
-    /*Only bank1 will be erased*/
+#endif /* FLASH_BANK2_END */
+    /* Only bank1 will be erased*/
     SET_BIT(FLASH->CR, FLASH_CR_MER);
     SET_BIT(FLASH->CR, FLASH_CR_STRT);
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
   }
-#endif /* STM32F101xG || STM32F103xG */
+#endif /* FLASH_BANK2_END */
 }
 
 /**
   * @brief  Enable the write protection of the desired pages
+  * @note   An option byte erase is done automatically in this function. 
   * @note   When the memory read protection level is selected (RDP level = 1), 
-  *         it is not possible to program or erase the flash page i if CortexM4  
+  *         it is not possible to program or erase the flash page i if
   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1 
   * 
-  * @param  WriteProtectPage: specifies the page(s) to be write protected.
+  * @param  WriteProtectPage specifies the page(s) to be write protected.
   *         The value of this parameter depend on device used within the same series 
   * @retval HAL status 
   */
@@ -597,61 +658,51 @@
 {
   HAL_StatusTypeDef status = HAL_OK;
   uint16_t WRP0_Data = 0xFFFF;
-#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \
-    defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-    defined(STM32F101xG) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-  uint16_t WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */
-       /* STM32F100xE || STM32F101xE || STM32F103xE || */
-       /* STM32F101xG || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC */
+#if defined(FLASH_WRP1_WRP1)
+  uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+  uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+  uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
   
   /* Check the parameters */
   assert_param(IS_OB_WRP(WriteProtectPage));
     
-  WriteProtectPage = (uint32_t)(~WriteProtectPage);
-  
-  /* Low Density and Medium Density */
-#if  defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || \
-     defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
-  WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
-#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 || */
-       /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
+  /* Get current write protected pages and the new pages to be protected ******/
+  WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
   
-/* Medium Density */
-#if  defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
-  WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
-  WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
-  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); 
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
-  
-/* High Density, XL Density and  Connectivity line devices*/
-#if  defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-     defined(STM32F101xG) || defined(STM32F103xG) || \
-     defined(STM32F105xC) || defined(STM32F107xC)
+#if defined(OB_WRP_PAGES0TO15MASK)
   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
+  WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
+#endif /* OB_WRP_PAGES0TO31MASK */
+  
+#if defined(OB_WRP_PAGES16TO31MASK)
   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+  WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
+#endif /* OB_WRP_PAGES32TO63MASK */
+ 
+#if defined(OB_WRP_PAGES64TO95MASK)
+  WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16);
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
-       /* STM32F101xG || STM32F103xG */
-       /* STM32F105xC || STM32F107xC */
-
-/* High Density */
-#if  defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE)  
-  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); 
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
+#endif /* OB_WRP_PAGES32TO47MASK */
 
-/* XL Density */
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(OB_WRP_PAGES96TO127MASK)
+  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); 
+#elif defined(OB_WRP_PAGES48TO255MASK)
+  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); 
+#elif defined(OB_WRP_PAGES48TO511MASK)
   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24); 
-#endif /* STM32F101xG || STM32F103xG */
-      
-/* Connectivity line devices */
-#if defined(STM32F105xC) || defined(STM32F107xC)
+#elif defined(OB_WRP_PAGES48TO127MASK)
   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24); 
-#endif /* STM32F105xC || STM32F107xC */
-
+#endif /* OB_WRP_PAGES96TO127MASK */
+  
   /* Wait for last operation to be completed */
   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 
@@ -660,51 +711,56 @@
     /* Clean the error context */
     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 
-    SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
-    if(WRP0_Data != 0xFF)
+    /* To be able to write again option byte, need to perform a option byte erase */
+    status = HAL_FLASHEx_OBErase();
+    if (status == HAL_OK)  
     {
-      OB->WRP0 &= WRP0_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
+      /* Enable write protection */
+      SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
 
-#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \
-    defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-    defined(STM32F101xG) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)    
-
-    if((status == HAL_OK) && (WRP1_Data != 0xFF))
-    {
-      OB->WRP1 &= WRP1_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
+#if defined(FLASH_WRP0_WRP0)
+      if(WRP0_Data != 0xFF)
+      {
+        OB->WRP0 &= WRP0_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP0_WRP0 */
 
-    if((status == HAL_OK) && (WRP2_Data != 0xFF))
-    {
-      OB->WRP2 &= WRP2_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
+#if defined(FLASH_WRP1_WRP1)
+      if((status == HAL_OK) && (WRP1_Data != 0xFF))
+      {
+        OB->WRP1 &= WRP1_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP1_WRP1 */
 
-    if((status == HAL_OK) && (WRP3_Data != 0xFF))
-    {
-      OB->WRP3 &= WRP3_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+#if defined(FLASH_WRP2_WRP2)
+      if((status == HAL_OK) && (WRP2_Data != 0xFF))
+      {
+        OB->WRP2 &= WRP2_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+      if((status == HAL_OK) && (WRP3_Data != 0xFF))
+      {
+        OB->WRP3 &= WRP3_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP3_WRP3 */
+
+      /* if the program operation is completed, disable the OPTPG Bit */
+      CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
     }
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */
-       /* STM32F100xE || STM32F101xE || STM32F103xE || */
-       /* STM32F101xG || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC */
-
-    /* if the program operation is completed, disable the OPTPG Bit */
-    CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
   }
   
   return status;
@@ -712,11 +768,12 @@
 
 /**
   * @brief  Disable the write protection of the desired pages
+  * @note   An option byte erase is done automatically in this function. 
   * @note   When the memory read protection level is selected (RDP level = 1), 
-  *         it is not possible to program or erase the flash page i if CortexM4  
+  *         it is not possible to program or erase the flash page i if   
   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1 
   * 
-  * @param  WriteProtectPage: specifies the page(s) to be write unprotected.
+  * @param  WriteProtectPage specifies the page(s) to be write unprotected.
   *         The value of this parameter depend on device used within the same series 
   * @retval HAL status 
   */
@@ -724,58 +781,51 @@
 {
   HAL_StatusTypeDef status = HAL_OK;
   uint16_t WRP0_Data = 0xFFFF;
-#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \
-    defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-    defined(STM32F101xG) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-  uint16_t WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */
-       /* STM32F100xE || STM32F101xE || STM32F103xE || */
-       /* STM32F101xG || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC */
+#if defined(FLASH_WRP1_WRP1)
+  uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+  uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+  uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
   
   /* Check the parameters */
   assert_param(IS_OB_WRP(WriteProtectPage));
 
-  /* Low Density and Medium Density */
-#if  defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || \
-     defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
+  /* Get current write protected pages and the new pages to be unprotected ******/
+  WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
+
+#if defined(OB_WRP_PAGES0TO15MASK)
+  WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
-#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 || */
-       /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
+#endif /* OB_WRP_PAGES0TO31MASK */
   
-/* Medium Density */
-#if  defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
-  WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
-  WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
-  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); 
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
-  
-/* High Density, XL Density and  Connectivity line devices*/
-#if  defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-     defined(STM32F101xG) || defined(STM32F103xG) || \
-     defined(STM32F105xC) || defined(STM32F107xC)
-  WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#if defined(OB_WRP_PAGES16TO31MASK)
   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+  WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
+#endif /* OB_WRP_PAGES32TO63MASK */
+ 
+#if defined(OB_WRP_PAGES64TO95MASK)
+  WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16);
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
-       /* STM32F101xG || STM32F103xG */
-       /* STM32F105xC || STM32F107xC */
-
-/* High Density */
-#if  defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE)  
-  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); 
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
+#endif /* OB_WRP_PAGES32TO47MASK */
 
-/* XL Density */
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(OB_WRP_PAGES96TO127MASK)
+  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); 
+#elif defined(OB_WRP_PAGES48TO255MASK)
+  WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); 
+#elif defined(OB_WRP_PAGES48TO511MASK)
   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24); 
-#endif /* STM32F101xG || STM32F103xG */
-      
-/* Connectivity line devices */
-#if defined(STM32F105xC) || defined(STM32F107xC)
+#elif defined(OB_WRP_PAGES48TO127MASK)
   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24); 
-#endif /* STM32F105xC || STM32F107xC */
+#endif /* OB_WRP_PAGES96TO127MASK */
+
     
   /* Wait for last operation to be completed */
   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
@@ -785,61 +835,65 @@
     /* Clean the error context */
     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 
-    SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
-    if(WRP0_Data != 0xFF)
+    /* To be able to write again option byte, need to perform a option byte erase */
+    status = HAL_FLASHEx_OBErase();
+    if (status == HAL_OK)  
     {
-      OB->WRP0 |= WRP0_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
-#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \
-    defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \
-    defined(STM32F101xG) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)  
-      
-    if((status == HAL_OK) && (WRP1_Data != 0xFF))
-    {
-      OB->WRP1 |= WRP1_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
+      SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_WRP0_WRP0)
+      if(WRP0_Data != 0xFF)
+      {
+        OB->WRP0 |= WRP0_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP0_WRP0 */
 
-    if((status == HAL_OK) && (WRP2_Data != 0xFF))
-    {
-      OB->WRP2 |= WRP2_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-    }
+#if defined(FLASH_WRP1_WRP1)
+      if((status == HAL_OK) && (WRP1_Data != 0xFF))
+      {
+        OB->WRP1 |= WRP1_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP1_WRP1 */
 
-    if((status == HAL_OK) && (WRP3_Data != 0xFF))
-    {
-      OB->WRP3 |= WRP3_Data;
-      
-      /* Wait for last operation to be completed */
-      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+#if defined(FLASH_WRP2_WRP2)
+      if((status == HAL_OK) && (WRP2_Data != 0xFF))
+      {
+        OB->WRP2 |= WRP2_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+      if((status == HAL_OK) && (WRP3_Data != 0xFF))
+      {
+        OB->WRP3 |= WRP3_Data;
+        
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+      }
+#endif /* FLASH_WRP3_WRP3 */
+
+      /* if the program operation is completed, disable the OPTPG Bit */
+      CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
     }
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB ||*/
-       /* STM32F100xE || STM32F101xE || STM32F103xE ||*/
-       /* STM32F101xG || STM32F103xG ||*/
-       /* STM32F105xC || STM32F107xC */
-
-    /* if the program operation is completed, disable the OPTPG Bit */
-    CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
   }
   return status;
 }
 
 /**
   * @brief  Set the read protection level.
-  * @param  ReadProtectLevel: specifies the read protection level.
+  * @param  ReadProtectLevel specifies the read protection level.
   *         This parameter can be one of the following values:
-  *            @arg OB_RDP_LEVEL_0: No protection
-  *            @arg OB_RDP_LEVEL_1: Read protection of the memory
-  *    
+  *            @arg @ref OB_RDP_LEVEL_0 No protection
+  *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
   * @retval HAL status
   */
 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
@@ -857,16 +911,29 @@
     /* Clean the error context */
     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
     
-    /* Enable the Option Bytes Programming operation */
-    SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-    
-    WRITE_REG(OB->RDP, ReadProtectLevel);
-    
+    /* If the previous operation is completed, proceed to erase the option bytes */
+    SET_BIT(FLASH->CR, FLASH_CR_OPTER);
+    SET_BIT(FLASH->CR, FLASH_CR_STRT);
+
     /* Wait for last operation to be completed */
-    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 
-    
-    /* if the program operation is completed, disable the OPTPG Bit */
-    CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+    /* If the erase operation is completed, disable the OPTER Bit */
+    CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
+
+    if(status == HAL_OK)
+    {
+      /* Enable the Option Bytes Programming operation */
+      SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+      
+      WRITE_REG(OB->RDP, ReadProtectLevel);
+      
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 
+      
+      /* if the program operation is completed, disable the OPTPG Bit */
+      CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+    }
   }
   
   return status;
@@ -875,7 +942,7 @@
 /**
   * @brief  Program the FLASH User Option Byte.    
   * @note   Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
-  * @param  UserConfig: The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2), 
+  * @param  UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2), 
   *         FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
   *         And BFBF2(Bit5) for STM32F101xG and STM32F103xG . 
   * @retval HAL status
@@ -888,9 +955,9 @@
   assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
   assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
   assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
   assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
-#endif /* STM32F101xG || STM32F103xG */
+#endif /* FLASH_BANK2_END */
 
   /* Wait for last operation to be completed */
   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
@@ -903,11 +970,11 @@
     /* Enable the Option Bytes Programming operation */
     SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 
  
-#if  defined(STM32F101xG) || defined(STM32F103xG)
+#if defined(FLASH_BANK2_END)
     OB->USER = (UserConfig | 0xF0);
 #else
-    OB->USER = (UserConfig | 0xF8);
-#endif /* STM32F101xG || STM32F103xG */
+    OB->USER = (UserConfig | 0x88);
+#endif /* FLASH_BANK2_END */
 
     /* Wait for last operation to be completed */
     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
@@ -921,14 +988,14 @@
 
 /**
   * @brief  Programs a half word at a specified Option Byte Data address.
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
-  *         The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 
+  * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+  *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+  *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 
   *         (system reset will occur)
   *         Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
-  * @param  Address: specifies the address to be programmed.
+  * @param  Address specifies the address to be programmed.
   *         This parameter can be 0x1FFFF804 or 0x1FFFF806. 
-  * @param  Data: specifies the data to be programmed.
+  * @param  Data specifies the data to be programmed.
   * @retval HAL status
   */
 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
@@ -973,21 +1040,27 @@
 /**
   * @brief  Returns the FLASH Read Protection level.
   * @retval FLASH ReadOut Protection Status:
-  *           - SET, when OB_RDP_LEVEL_1 is set
-  *           - RESET, when OB_RDP_LEVEL_0 is set
+  *         This parameter can be one of the following values:
+  *            @arg @ref OB_RDP_LEVEL_0 No protection
+  *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
   */
-static FlagStatus FLASH_OB_GetRDP(void)
+static uint32_t FLASH_OB_GetRDP(void)
 {
-  FlagStatus readstatus = RESET;
+  uint32_t readstatus = OB_RDP_LEVEL_0;
+  uint32_t tmp_reg = 0;
+  
+  /* Read RDP level bits */
+  tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
 
-  if (HAL_IS_BIT_SET(FLASH->OBR, FLASH_OBR_RDPRT))
+  if (tmp_reg == FLASH_OBR_RDPRT)
   {
-    readstatus = SET;
+    readstatus = OB_RDP_LEVEL_1;
   }
-  else
+  else 
   {
-    readstatus = RESET;
+    readstatus = OB_RDP_LEVEL_0;
   }
+
   return readstatus;
 }
 
@@ -1000,54 +1073,9 @@
 static uint8_t FLASH_OB_GetUser(void)
 {
   /* Return the User Option Byte */
-  return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> 2);
+  return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
 }
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-/**
-  * @brief  Wait for a FLASH BANK2 operation to complete.
-  * @param  Timeout: maximum flash operationtimeout
-  * @retval HAL_StatusTypeDef HAL Status
-  */
-static HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
-{ 
-  /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
-     Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
-     flag will be set */
-     
-  uint32_t tickstart = HAL_GetTick();
-     
-  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2)) 
-  { 
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-  
-  /* Check FLASH End of Operation flag  */
-  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
-  {
-    /* Clear FLASH End of Operation pending bit */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
-  }
-
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
-  {
-    /*Save the error code*/
-    FLASH_SetErrorCode();
-    return HAL_ERROR;
-  }
-
-  /* If there is an error flag set */
-  return HAL_OK;
-  
-}
-#endif /* STM32F101xG || STM32F103xG */
-
 /**
   * @}
   */
@@ -1060,549 +1088,13 @@
   * @{
   */
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-/** @addtogroup FLASH_Exported_Functions
-  * @{
-  */
-
-/** @addtogroup FLASH_Exported_Functions_Group2
-  * @{
-  */
-
-/**
-  * @brief  Unlock the FLASH control register access
-  * @retval HAL Status
-  */
-HAL_StatusTypeDef HAL_FLASH_Unlock(void)
-{
-  if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
-  {
-    /* Authorize the FLASH BANK1 Registers access */
-    WRITE_REG(FLASH->KEYR, FLASH_KEY1);
-    WRITE_REG(FLASH->KEYR, FLASH_KEY2);
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-
-  if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK))
-  {
-    /* Authorize the FLASH BANK2 Registers access */
-    WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
-    WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  return HAL_OK; 
-}
-
-/**
-  * @brief  Locks the FLASH control register access
-  * @retval HAL Status
-  */
-HAL_StatusTypeDef HAL_FLASH_Lock(void)
-{
-  /* Set the LOCK Bit to lock the FLASH BANK1 Registers access */
-  SET_BIT(FLASH->CR, FLASH_CR_LOCK);
-
-  /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
-  SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
-  
-  return HAL_OK;  
-}
-/**
-  * @}
-  */
-
-/** @addtogroup FLASH_Exported_Functions_Group1
-  * @{
-  */
-
-/**
-  * @brief  Program halfword, word or double word at a specified address
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
-  *
-  * @note   If an erase and a program operations are requested simultaneously,    
-  *         the erase operation is performed before the program one.
-  *  
-  * @note   FLASH should be previously erased before new programmation (only exception to this 
-  *         is when 0x0000 is programmed)
-  *  
-  * @param  TypeProgram:  Indicate the way to program at a specified address.
-  *                       This parameter can be a value of @ref FLASH_Type_Program
-  * @param  Address:      Specifies the address to be programmed.
-  * @param  Data:         Specifies the data to be programmed
-  * 
-  * @retval HAL_StatusTypeDef HAL Status
-  */
-HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
-{
-  HAL_StatusTypeDef status = HAL_ERROR;
-  uint8_t index = 0;
-  uint8_t nbiterations = 0;
-  
-  /* Process Locked */
-  __HAL_LOCK(&pFlash);
-  
-  /* Check the parameters */
-  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
-  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
-  
-  if(Address <= FLASH_BANK1_END)
-  {
-    /* Wait for last operation to be completed */
-    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-  }
-  else
-  {
-    /* Wait for last operation to be completed */
-    status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
-  }
-  
-  if(status == HAL_OK)
-  {
-    if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
-    {
-      /* Program halfword (16-bit) at a specified address. */
-      nbiterations = 1;
-    }
-    else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
-    {
-      /* Program word (32-bit = 2*16-bit) at a specified address. */
-      nbiterations = 2;
-    }
-    else
-    {
-      /* Program double word (64-bit = 4*16-bit) at a specified address. */
-      nbiterations = 4;
-    }
-    
-    for (index = 0; index < nbiterations; index++)
-    {
-      FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
-      
-      if(Address <= FLASH_BANK1_END)
-      {
-        /* Wait for last operation to be completed */
-        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-        
-        /* If the program operation is completed, disable the PG Bit */
-        CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
-      }
-      else
-      {
-        /* Wait for last operation to be completed */
-        status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
-        
-        /* If the program operation is completed, disable the PG Bit */
-        CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
-      }
-      /* In case of error, stop programation procedure */
-      if (status != HAL_OK)
-      {
-        break;
-      }
-    }
-  }
-  
-  /* Process Unlocked */
-  __HAL_UNLOCK(&pFlash);
-  
-  return status;
-}
-
-/**
-  * @brief  Program halfword, word or double word at a specified address  with interrupt enabled.
-  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
-  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
-  *
-  * @note   If an erase and a program operations are requested simultaneously,    
-  *         the erase operation is performed before the program one.
-  *  
-  * @param  TypeProgram: Indicate the way to program at a specified address.
-  *                      This parameter can be a value of @ref FLASH_Type_Program
-  * @param  Address:     Specifies the address to be programmed.
-  * @param  Data:        Specifies the data to be programmed
-  * 
-  * @retval HAL_StatusTypeDef HAL Status
-  */
-HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  
-  /* Process Locked */
-  __HAL_LOCK(&pFlash);
-
-  /* If procedure already ongoing, reject the next one */
-  if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
-  {
-    return HAL_ERROR;
-  }
-  
-  /* Check the parameters */
-  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
-  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
-
-  if(Address <= FLASH_BANK1_END)
-  {
-    /* Enable End of FLASH Operation and Error source interrupts */
-    __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1));
-  }else
-  {
-    /* Enable End of FLASH Operation and Error source interrupts */
-    __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2));
-  }
-
-  pFlash.Address = Address;
-  pFlash.Data = Data;
-
-  if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
-  {
-    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
-    /*Program halfword (16-bit) at a specified address.*/
-    pFlash.DataRemaining = 1;
-  }
-  else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
-  {
-    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
-    /*Program word (32-bit : 2*16-bit) at a specified address.*/
-    pFlash.DataRemaining = 2;
-  }
-  else
-  {
-    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
-    /*Program double word (64-bit : 4*16-bit) at a specified address.*/
-    pFlash.DataRemaining = 4;
-  }
-
-  /*Program halfword (16-bit) at a specified address.*/
-  FLASH_Program_HalfWord(Address, (uint16_t)Data);
-
-  return status;
-}
-
-/**
-  * @brief This function handles FLASH interrupt request.
-  * @retval None
-  */
-void HAL_FLASH_IRQHandler(void)
-{
-  uint32_t addresstmp = 0;
- 
-  /* Check FLASH operation error flags */
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
-    (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
-  {
-    /*Save the Error code*/
-    FLASH_SetErrorCode();
-    
-    /* FLASH error interrupt user callback */
-    HAL_FLASH_OperationErrorCallback(pFlash.Address);
-    
-    /* Reset address and stop the procedure ongoing*/
-    pFlash.Address = 0xFFFFFFFF;
-    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-  }
-
-  /* Check FLASH End of Operation flag  */
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
-  {
-    /* Clear FLASH End of Operation pending bit */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
-    
-    /* Process can continue only if no error detected */
-    if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
-    {
-      if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
-      {
-        /* Nb of pages to erased can be decreased */
-        pFlash.DataRemaining--;
-        
-        /* Indicate user which page address has been erased*/
-        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
-        
-        /* Check if there are still pages to erase*/
-        if(pFlash.DataRemaining != 0)
-        {
-          /* Increment page address to next page */
-          pFlash.Address += FLASH_PAGE_SIZE;
-          addresstmp = pFlash.Address;
-
-          /* Operation is completed, disable the PER Bit */
-          CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
-
-          FLASH_PageErase(addresstmp);
-        }
-        else
-        {
-          /*No more pages to Erase*/
-          
-          /*Reset Address and stop Erase pages procedure*/
-          pFlash.Address = 0xFFFFFFFF;
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-      else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
-      {
-        /* Operation is completed, disable the MER Bit */
-        CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
-
-        /* Stop Mass Erase procedure if no pending mass erase on other bank */
-        if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
-        {
-          /* MassErase ended. Return the selected bank*/
-          /* FLASH EOP interrupt user callback */
-          HAL_FLASH_EndOfOperationCallback(0);
-        
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-      else
-      {
-        /* Nb of 16-bit data to program can be decreased */
-        pFlash.DataRemaining--;
-        
-        /* Check if there are still 16-bit data to program */
-        if(pFlash.DataRemaining != 0)
-        {
-          /* Increment address to 16-bit */
-          pFlash.Address += 2;
-          addresstmp = pFlash.Address;
-          
-          /* Shift to have next 16-bit data */
-          pFlash.Data = (pFlash.Data >> 16);
-          
-          /* Operation is completed, disable the PG Bit */
-          CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
-
-          /*Program halfword (16-bit) at a specified address.*/
-          FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
-        }
-        else
-        {
-          /*Program ended. Return the selected address*/
-          /* FLASH EOP interrupt user callback */
-          if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address);
-          }
-          else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2);
-          }
-          else 
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6);
-          }
-          
-          /* Reset Address and stop Program procedure*/
-          pFlash.Address = 0xFFFFFFFF;
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-    }
-  }
-  
-  /* Check FLASH End of Operation flag  */
-  if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
-  {
-    /* Clear FLASH End of Operation pending bit */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
-    
-    /* Process can continue only if no error detected */
-    if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
-    {
-      if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
-      {
-        /* Nb of pages to erased can be decreased */
-        pFlash.DataRemaining--;
-        
-        /* Indicate user which page address has been erased*/
-        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
-        
-        /* Check if there are still pages to erase*/
-        if(pFlash.DataRemaining != 0)
-        {
-          /* Increment page address to next page */
-          pFlash.Address += FLASH_PAGE_SIZE;
-          addresstmp = pFlash.Address;
-
-          /* Operation is completed, disable the PER Bit */
-          CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
-
-          FLASH_PageErase(addresstmp);
-        }
-        else
-        {
-          /*No more pages to Erase*/
-          
-          /*Reset Address and stop Erase pages procedure*/
-          pFlash.Address = 0xFFFFFFFF;
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-      else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
-      {
-        /* Operation is completed, disable the MER Bit */
-        CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
-
-        if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
-        {
-          /* MassErase ended. Return the selected bank*/
-          /* FLASH EOP interrupt user callback */
-          HAL_FLASH_EndOfOperationCallback(0);
-        
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-      else
-      {
-        /* Nb of 16-bit data to program can be decreased */
-        pFlash.DataRemaining--;
-        
-        /* Check if there are still 16-bit data to program */
-        if(pFlash.DataRemaining != 0)
-        {
-          /* Increment address to 16-bit */
-          pFlash.Address += 2;
-          addresstmp = pFlash.Address;
-          
-          /* Shift to have next 16-bit data */
-          pFlash.Data = (pFlash.Data >> 16);
-          
-          /* Operation is completed, disable the PG Bit */
-          CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
-
-          /*Program halfword (16-bit) at a specified address.*/
-          FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
-        }
-        else
-        {
-          /*Program ended. Return the selected address*/
-          /* FLASH EOP interrupt user callback */
-          if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address);
-          }
-          else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
-          }
-          else 
-          {
-            HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
-          }
-          
-          /* Reset Address and stop Program procedure*/
-          pFlash.Address = 0xFFFFFFFF;
-          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-        }
-      }
-    }
-  }
-  
-  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
-  {
-    /* Operation is completed, disable the PG, PER and MER Bits for both bank */
-    CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
-    CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));  
-  
-    /* Disable End of FLASH Operation and Error source interrupts for both banks */
-    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
-    
-    /* Process Unlocked */
-    __HAL_UNLOCK(&pFlash);
-  }
-}
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-#endif /* STM32F101xG || STM32F103xG */
-
 /** @addtogroup FLASH_Private_Functions
  * @{
  */
 
 /**
-  * @brief  Program a half-word (16-bit) at a specified address.
-  * @param  Address: specifies the address to be programmed.
-  * @param  Data: specifies the data to be programmed.
-  * @retval None
-  */
-void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
-{
-  /* Clean the error context */
-  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-  
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-  if(Address <= FLASH_BANK1_END)
-  {
-#endif /* STM32F101xG || STM32F103xG */
-    /* Proceed to program the new data */
-    SET_BIT(FLASH->CR, FLASH_CR_PG);
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-  }
-  else
-  {
-    /* Proceed to program the new data */
-    SET_BIT(FLASH->CR2, FLASH_CR2_PG);
-  }
-#endif /* STM32F101xG || STM32F103xG */
-
-  /* Write data in the address */
-  *(__IO uint16_t*)Address = Data;
-}
-
-/**
-  * @brief  Set the specific FLASH error flag.
-  * @retval None
-  */
-void FLASH_SetErrorCode(void)
-{ 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
-#else
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
-#endif /* STM32F101xG || STM32F103xG */
-  {
-    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
-  }
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
-#else
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
-#endif /* STM32F101xG || STM32F103xG */
-  {
-     pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
-  }
-
-  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
-  {
-     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
-     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
-  }
-
-  /* Clear FLASH error pending bits */
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
-  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2);
-#else
-  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
-#endif /* STM32F101xG || STM32F103xG */
-}  
-
-/**
   * @brief  Erase the specified FLASH memory page
-  * @param  PageAddress: FLASH page to erase
+  * @param  PageAddress FLASH page to erase
   *         The value of this parameter depend on device used within the same series      
   * 
   * @retval None
@@ -1612,7 +1104,7 @@
   /* Clean the error context */
   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 
-#if  defined(STM32F101xG) || defined(STM32F103xG) 
+#if defined(FLASH_BANK2_END)
   if(PageAddress > FLASH_BANK1_END)
   { 
     /* Proceed to erase the page */
@@ -1621,13 +1113,15 @@
     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
   }
   else
-#endif /* STM32F101xG || STM32F103xG */
   {
+#endif /* FLASH_BANK2_END */
     /* Proceed to erase the page */
     SET_BIT(FLASH->CR, FLASH_CR_PER);
     WRITE_REG(FLASH->AR, PageAddress);
     SET_BIT(FLASH->CR, FLASH_CR_STRT);
+#if defined(FLASH_BANK2_END)
   }
+#endif /* FLASH_BANK2_END */
 }
 
 /**
@@ -1638,10 +1132,6 @@
   * @}
   */
 
-/**
-  * @}
-  */
-
 #endif /* HAL_FLASH_MODULE_ENABLED */
 /**
   * @}