tdse-tp2_03-model_integration

Index Commits Files Refs README
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c (35761B)
   1 /**
   2   ******************************************************************************
   3   * @file    stm32f1xx_hal_flash_ex.c
   4   * @author  MCD Application Team
   5   * @brief   Extended FLASH HAL module driver.
   6   *    
   7   *          This file provides firmware functions to manage the following 
   8   *          functionalities of the FLASH peripheral:
   9   *           + Extended Initialization/de-initialization functions
  10   *           + Extended I/O operation functions
  11   *           + Extended Peripheral Control functions 
  12   *         
  13   @verbatim
  14   ==============================================================================
  15                ##### Flash peripheral extended features  #####
  16   ==============================================================================
  17            
  18                       ##### How to use this driver #####
  19   ==============================================================================
  20   [..] This driver provides functions to configure and program the FLASH memory 
  21        of all STM32F1xxx devices. It includes
  22        
  23         (++) Set/Reset the write protection
  24         (++) Program the user Option Bytes
  25         (++) Get the Read protection Level
  26   
  27   @endverbatim
  28   ******************************************************************************
  29   * @attention
  30   *
  31   * Copyright (c) 2016 STMicroelectronics.
  32   * All rights reserved.
  33   *
  34   * This software is licensed under terms that can be found in the LICENSE file in
  35   * the root directory of this software component.
  36   * If no LICENSE file comes with this software, it is provided AS-IS.
  37   ******************************************************************************
  38   */
  39 
  40 /* Includes ------------------------------------------------------------------*/
  41 #include "stm32f1xx_hal.h"
  42 
  43 /** @addtogroup STM32F1xx_HAL_Driver
  44   * @{
  45   */
  46 #ifdef HAL_FLASH_MODULE_ENABLED
  47 
  48 /** @addtogroup FLASH
  49   * @{
  50   */
  51 /** @addtogroup FLASH_Private_Variables
  52  * @{
  53  */
  54 /* Variables used for Erase pages under interruption*/
  55 extern FLASH_ProcessTypeDef pFlash;
  56 /**
  57   * @}
  58   */
  59 
  60 /**
  61   * @}
  62   */
  63   
  64 /** @defgroup FLASHEx FLASHEx
  65   * @brief FLASH HAL Extension module driver
  66   * @{
  67   */
  68 
  69 /* Private typedef -----------------------------------------------------------*/
  70 /* Private define ------------------------------------------------------------*/
  71 /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
  72  * @{
  73  */
  74 #define FLASH_POSITION_IWDGSW_BIT        FLASH_OBR_IWDG_SW_Pos
  75 #define FLASH_POSITION_OB_USERDATA0_BIT  FLASH_OBR_DATA0_Pos
  76 #define FLASH_POSITION_OB_USERDATA1_BIT  FLASH_OBR_DATA1_Pos
  77 /**
  78   * @}
  79   */
  80 
  81 /* Private macro -------------------------------------------------------------*/
  82 /** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
  83   * @{
  84   */
  85 /**
  86   * @}
  87   */ 
  88 
  89 /* Private variables ---------------------------------------------------------*/
  90 /* Private function prototypes -----------------------------------------------*/
  91 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
  92  * @{
  93  */
  94 /* Erase operations */
  95 static void              FLASH_MassErase(uint32_t Banks);
  96 void    FLASH_PageErase(uint32_t PageAddress);
  97 
  98 /* Option bytes control */
  99 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
 100 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
 101 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
 102 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
 103 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
 104 static uint32_t          FLASH_OB_GetWRP(void);
 105 static uint32_t          FLASH_OB_GetRDP(void);
 106 static uint8_t           FLASH_OB_GetUser(void);
 107 
 108 /**
 109   * @}
 110   */
 111 
 112 /* Exported functions ---------------------------------------------------------*/
 113 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
 114   * @{
 115   */
 116   
 117 /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
 118  *  @brief   FLASH Memory Erasing functions
 119   *
 120 @verbatim   
 121   ==============================================================================
 122                 ##### FLASH Erasing Programming functions ##### 
 123   ==============================================================================
 124 
 125     [..] The FLASH Memory Erasing functions, includes the following functions:
 126     (+) HAL_FLASHEx_Erase: return only when erase has been done
 127     (+) HAL_FLASHEx_Erase_IT: end of erase is done when HAL_FLASH_EndOfOperationCallback 
 128         is called with parameter 0xFFFFFFFF
 129 
 130     [..] Any operation of erase should follow these steps:
 131     (#) Call the HAL_FLASH_Unlock() function to enable the flash control register and 
 132         program memory access.
 133     (#) Call the desired function to erase page.
 134     (#) Call the HAL_FLASH_Lock() to disable the flash program memory access 
 135        (recommended to protect the FLASH memory against possible unwanted operation).
 136 
 137 @endverbatim
 138   * @{
 139   */
 140   
 141 
 142 /**
 143   * @brief  Perform a mass erase or erase the specified FLASH memory pages
 144   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
 145   *         must be called before.
 146   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access 
 147   *         (recommended to protect the FLASH memory against possible unwanted operation)
 148   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
 149   *         contains the configuration information for the erasing.
 150   *
 151   * @param[out]  PageError pointer to variable  that
 152   *         contains the configuration information on faulty page in case of error
 153   *         (0xFFFFFFFF means that all the pages have been correctly erased)
 154   *
 155   * @retval HAL_StatusTypeDef HAL Status
 156   */
 157 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
 158 {
 159   HAL_StatusTypeDef status = HAL_ERROR;
 160   uint32_t address = 0U;
 161 
 162   /* Process Locked */
 163   __HAL_LOCK(&pFlash);
 164 
 165   /* Check the parameters */
 166   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
 167 
 168   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
 169   {
 170 #if defined(FLASH_BANK2_END)
 171     if (pEraseInit->Banks == FLASH_BANK_BOTH)
 172     {
 173       /* Mass Erase requested for Bank1 and Bank2 */
 174       /* Wait for last operation to be completed */
 175       if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
 176           (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
 177       {
 178         /*Mass erase to be done*/
 179         FLASH_MassErase(FLASH_BANK_BOTH);
 180         
 181         /* Wait for last operation to be completed */
 182         if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
 183             (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
 184         {
 185           status = HAL_OK;
 186         }
 187         
 188         /* If the erase operation is completed, disable the MER Bit */
 189         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
 190         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
 191       }
 192     }
 193     else if (pEraseInit->Banks == FLASH_BANK_2)
 194     {
 195       /* Mass Erase requested for Bank2 */
 196       /* Wait for last operation to be completed */
 197       if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
 198       {
 199         /*Mass erase to be done*/
 200         FLASH_MassErase(FLASH_BANK_2);
 201         
 202         /* Wait for last operation to be completed */
 203         status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
 204         
 205         /* If the erase operation is completed, disable the MER Bit */
 206         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
 207       }
 208     }
 209     else 
 210 #endif /* FLASH_BANK2_END */
 211     {
 212       /* Mass Erase requested for Bank1 */
 213       /* Wait for last operation to be completed */
 214       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
 215       {
 216         /*Mass erase to be done*/
 217         FLASH_MassErase(FLASH_BANK_1);
 218         
 219         /* Wait for last operation to be completed */
 220         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 221         
 222         /* If the erase operation is completed, disable the MER Bit */
 223         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
 224       }
 225     }
 226   }
 227   else
 228   {
 229     /* Page Erase is requested */
 230     /* Check the parameters */
 231     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
 232     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
 233     
 234 #if defined(FLASH_BANK2_END)
 235     /* Page Erase requested on address located on bank2 */
 236     if(pEraseInit->PageAddress > FLASH_BANK1_END)
 237     {   
 238       /* Wait for last operation to be completed */
 239       if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
 240       {
 241         /*Initialization of PageError variable*/
 242         *PageError = 0xFFFFFFFFU;
 243         
 244         /* Erase by page by page to be done*/
 245         for(address = pEraseInit->PageAddress;
 246             address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
 247             address += FLASH_PAGE_SIZE)
 248         {
 249           FLASH_PageErase(address);
 250           
 251           /* Wait for last operation to be completed */
 252           status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
 253           
 254           /* If the erase operation is completed, disable the PER Bit */
 255           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
 256           
 257           if (status != HAL_OK)
 258           {
 259             /* In case of error, stop erase procedure and return the faulty address */
 260             *PageError = address;
 261             break;
 262           }
 263         }
 264       }
 265     }
 266     else
 267 #endif /* FLASH_BANK2_END */
 268    {
 269       /* Page Erase requested on address located on bank1 */
 270       /* Wait for last operation to be completed */
 271       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
 272       {
 273         /*Initialization of PageError variable*/
 274         *PageError = 0xFFFFFFFFU;
 275         
 276         /* Erase page by page to be done*/
 277         for(address = pEraseInit->PageAddress;
 278             address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
 279             address += FLASH_PAGE_SIZE)
 280         {
 281           FLASH_PageErase(address);
 282           
 283           /* Wait for last operation to be completed */
 284           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 285           
 286           /* If the erase operation is completed, disable the PER Bit */
 287           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
 288           
 289           if (status != HAL_OK)
 290           {
 291             /* In case of error, stop erase procedure and return the faulty address */
 292             *PageError = address;
 293             break;
 294           }
 295         }
 296       }
 297     }
 298   }
 299 
 300   /* Process Unlocked */
 301   __HAL_UNLOCK(&pFlash);
 302 
 303   return status;
 304 }
 305 
 306 /**
 307   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
 308   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
 309   *         must be called before.
 310   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access 
 311   *         (recommended to protect the FLASH memory against possible unwanted operation)
 312   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
 313   *         contains the configuration information for the erasing.
 314   *
 315   * @retval HAL_StatusTypeDef HAL Status
 316   */
 317 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
 318 {
 319   HAL_StatusTypeDef status = HAL_OK;
 320 
 321   /* If procedure already ongoing, reject the next one */
 322   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
 323   {
 324     return HAL_ERROR;
 325   }
 326   
 327   /* Check the parameters */
 328   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
 329 
 330   /* Enable End of FLASH Operation and Error source interrupts */
 331   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
 332 
 333 #if defined(FLASH_BANK2_END)
 334   /* Enable End of FLASH Operation and Error source interrupts */
 335   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
 336   
 337 #endif
 338   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
 339   {
 340     /*Mass erase to be done*/
 341     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
 342         FLASH_MassErase(pEraseInit->Banks);
 343   }
 344   else
 345   {
 346     /* Erase by page to be done*/
 347 
 348     /* Check the parameters */
 349     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
 350     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
 351 
 352     pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
 353     pFlash.DataRemaining = pEraseInit->NbPages;
 354     pFlash.Address = pEraseInit->PageAddress;
 355 
 356     /*Erase 1st page and wait for IT*/
 357     FLASH_PageErase(pEraseInit->PageAddress);
 358   }
 359 
 360   return status;
 361 }
 362 
 363 /**
 364   * @}
 365   */
 366 
 367 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
 368  *  @brief   Option Bytes Programming functions
 369   *
 370 @verbatim   
 371   ==============================================================================
 372                 ##### Option Bytes Programming functions ##### 
 373   ==============================================================================  
 374     [..]
 375     This subsection provides a set of functions allowing to control the FLASH 
 376     option bytes operations.
 377 
 378 @endverbatim
 379   * @{
 380   */
 381 
 382 /**
 383   * @brief  Erases the FLASH option bytes.
 384   * @note   This functions erases all option bytes except the Read protection (RDP).
 385   *         The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
 386   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
 387   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
 388   *         (system reset will occur)
 389   * @retval HAL status
 390   */
 391 
 392 HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
 393 {
 394   uint8_t rdptmp = OB_RDP_LEVEL_0;
 395   HAL_StatusTypeDef status = HAL_ERROR;
 396 
 397   /* Get the actual read protection Option Byte value */
 398   rdptmp = FLASH_OB_GetRDP();
 399 
 400   /* Wait for last operation to be completed */
 401   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 402 
 403   if(status == HAL_OK)
 404   {
 405     /* Clean the error context */
 406     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 407 
 408     /* If the previous operation is completed, proceed to erase the option bytes */
 409     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
 410     SET_BIT(FLASH->CR, FLASH_CR_STRT);
 411 
 412     /* Wait for last operation to be completed */
 413     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 414 
 415     /* If the erase operation is completed, disable the OPTER Bit */
 416     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
 417 
 418     if(status == HAL_OK)
 419     {
 420       /* Restore the last read protection Option Byte value */
 421       status = FLASH_OB_RDP_LevelConfig(rdptmp);
 422     }
 423   }
 424 
 425   /* Return the erase status */
 426   return status;
 427 }
 428 
 429 /**
 430   * @brief  Program option bytes
 431   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
 432   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
 433   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
 434   *         (system reset will occur)
 435   *
 436   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
 437   *         contains the configuration information for the programming.
 438   *
 439   * @retval HAL_StatusTypeDef HAL Status
 440   */
 441 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
 442 {
 443   HAL_StatusTypeDef status = HAL_ERROR;
 444 
 445   /* Process Locked */
 446   __HAL_LOCK(&pFlash);
 447 
 448   /* Check the parameters */
 449   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
 450 
 451   /* Write protection configuration */
 452   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
 453   {
 454     assert_param(IS_WRPSTATE(pOBInit->WRPState));
 455     if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
 456     {
 457       /* Enable of Write protection on the selected page */
 458       status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
 459     }
 460     else
 461     {
 462       /* Disable of Write protection on the selected page */
 463       status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
 464     }
 465     if (status != HAL_OK)
 466     {
 467       /* Process Unlocked */
 468       __HAL_UNLOCK(&pFlash);
 469       return status;
 470     }
 471   }
 472 
 473   /* Read protection configuration */
 474   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
 475   {
 476     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
 477     if (status != HAL_OK)
 478     {
 479       /* Process Unlocked */
 480       __HAL_UNLOCK(&pFlash);
 481       return status;
 482     }
 483   }
 484 
 485   /* USER configuration */
 486   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
 487   {
 488     status = FLASH_OB_UserConfig(pOBInit->USERConfig);
 489     if (status != HAL_OK)
 490     {
 491       /* Process Unlocked */
 492       __HAL_UNLOCK(&pFlash);
 493       return status;
 494     }
 495   }
 496 
 497   /* DATA configuration*/
 498   if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
 499   {
 500     status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
 501     if (status != HAL_OK)
 502     {
 503       /* Process Unlocked */
 504       __HAL_UNLOCK(&pFlash);
 505       return status;
 506     }
 507   }
 508 
 509   /* Process Unlocked */
 510   __HAL_UNLOCK(&pFlash);
 511 
 512   return status;
 513 }
 514 
 515 /**
 516   * @brief  Get the Option byte configuration
 517   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
 518   *         contains the configuration information for the programming.
 519   *
 520   * @retval None
 521   */
 522 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
 523 {
 524   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
 525 
 526   /*Get WRP*/
 527   pOBInit->WRPPage = FLASH_OB_GetWRP();
 528 
 529   /*Get RDP Level*/
 530   pOBInit->RDPLevel = FLASH_OB_GetRDP();
 531 
 532   /*Get USER*/
 533   pOBInit->USERConfig = FLASH_OB_GetUser();
 534 }
 535 
 536 /**
 537   * @brief  Get the Option byte user data
 538   * @param  DATAAdress Address of the option byte DATA
 539   *          This parameter can be one of the following values:
 540   *            @arg @ref OB_DATA_ADDRESS_DATA0
 541   *            @arg @ref OB_DATA_ADDRESS_DATA1
 542   * @retval Value programmed in USER data
 543   */
 544 uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
 545 {
 546   uint32_t value = 0;
 547   
 548   if (DATAAdress == OB_DATA_ADDRESS_DATA0)
 549   {
 550     /* Get value programmed in OB USER Data0 */
 551     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
 552   }
 553   else
 554   {
 555     /* Get value programmed in OB USER Data1 */
 556     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
 557   }
 558   
 559   return value;
 560 }
 561 
 562 /**
 563   * @}
 564   */
 565 
 566 /**
 567   * @}
 568   */
 569 
 570 /** @addtogroup FLASHEx_Private_Functions
 571  * @{
 572  */
 573 
 574 /**
 575   * @brief  Full erase of FLASH memory Bank 
 576   * @param  Banks Banks to be erased
 577   *          This parameter can be one of the following values:
 578   *            @arg @ref FLASH_BANK_1 Bank1 to be erased
 579   @if STM32F101xG
 580   *            @arg @ref FLASH_BANK_2 Bank2 to be erased
 581   *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
 582   @endif
 583   @if STM32F103xG
 584   *            @arg @ref FLASH_BANK_2 Bank2 to be erased
 585   *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
 586   @endif
 587   *
 588   * @retval None
 589   */
 590 static void FLASH_MassErase(uint32_t Banks)
 591 {
 592   /* Check the parameters */
 593   assert_param(IS_FLASH_BANK(Banks));
 594 
 595   /* Clean the error context */
 596   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 597 
 598 #if defined(FLASH_BANK2_END)
 599   if(Banks == FLASH_BANK_BOTH)
 600   {
 601     /* bank1 & bank2 will be erased*/
 602     SET_BIT(FLASH->CR, FLASH_CR_MER);
 603     SET_BIT(FLASH->CR2, FLASH_CR2_MER);
 604     SET_BIT(FLASH->CR, FLASH_CR_STRT);
 605     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
 606   }
 607   else if(Banks == FLASH_BANK_2)
 608   {
 609     /*Only bank2 will be erased*/
 610     SET_BIT(FLASH->CR2, FLASH_CR2_MER);
 611     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
 612   }
 613   else
 614   {
 615 #endif /* FLASH_BANK2_END */
 616 #if !defined(FLASH_BANK2_END)
 617   /* Prevent unused argument(s) compilation warning */
 618   UNUSED(Banks);
 619 #endif /* FLASH_BANK2_END */  
 620     /* Only bank1 will be erased*/
 621     SET_BIT(FLASH->CR, FLASH_CR_MER);
 622     SET_BIT(FLASH->CR, FLASH_CR_STRT);
 623 #if defined(FLASH_BANK2_END)
 624   }
 625 #endif /* FLASH_BANK2_END */
 626 }
 627 
 628 /**
 629   * @brief  Enable the write protection of the desired pages
 630   * @note   An option byte erase is done automatically in this function. 
 631   * @note   When the memory read protection level is selected (RDP level = 1), 
 632   *         it is not possible to program or erase the flash page i if
 633   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1 
 634   * 
 635   * @param  WriteProtectPage specifies the page(s) to be write protected.
 636   *         The value of this parameter depend on device used within the same series 
 637   * @retval HAL status 
 638   */
 639 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
 640 {
 641   HAL_StatusTypeDef status = HAL_OK;
 642   uint16_t WRP0_Data = 0xFFFF;
 643 #if defined(FLASH_WRP1_WRP1)
 644   uint16_t WRP1_Data = 0xFFFF;
 645 #endif /* FLASH_WRP1_WRP1 */
 646 #if defined(FLASH_WRP2_WRP2)
 647   uint16_t WRP2_Data = 0xFFFF;
 648 #endif /* FLASH_WRP2_WRP2 */
 649 #if defined(FLASH_WRP3_WRP3)
 650   uint16_t WRP3_Data = 0xFFFF;
 651 #endif /* FLASH_WRP3_WRP3 */
 652   
 653   /* Check the parameters */
 654   assert_param(IS_OB_WRP(WriteProtectPage));
 655     
 656   /* Get current write protected pages and the new pages to be protected ******/
 657   WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
 658   
 659 #if defined(OB_WRP_PAGES0TO15MASK)
 660   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
 661 #elif defined(OB_WRP_PAGES0TO31MASK)
 662   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
 663 #endif /* OB_WRP_PAGES0TO31MASK */
 664   
 665 #if defined(OB_WRP_PAGES16TO31MASK)
 666   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
 667 #elif defined(OB_WRP_PAGES32TO63MASK)
 668   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
 669 #endif /* OB_WRP_PAGES32TO63MASK */
 670  
 671 #if defined(OB_WRP_PAGES64TO95MASK)
 672   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
 673 #endif /* OB_WRP_PAGES64TO95MASK */
 674 #if defined(OB_WRP_PAGES32TO47MASK)
 675   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
 676 #endif /* OB_WRP_PAGES32TO47MASK */
 677 
 678 #if defined(OB_WRP_PAGES96TO127MASK)
 679   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U); 
 680 #elif defined(OB_WRP_PAGES48TO255MASK)
 681   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U); 
 682 #elif defined(OB_WRP_PAGES48TO511MASK)
 683   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U); 
 684 #elif defined(OB_WRP_PAGES48TO127MASK)
 685   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); 
 686 #endif /* OB_WRP_PAGES96TO127MASK */
 687   
 688   /* Wait for last operation to be completed */
 689   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 690 
 691   if(status == HAL_OK)
 692   { 
 693     /* Clean the error context */
 694     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 695 
 696     /* To be able to write again option byte, need to perform a option byte erase */
 697     status = HAL_FLASHEx_OBErase();
 698     if (status == HAL_OK)  
 699     {
 700       /* Enable write protection */
 701       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
 702 
 703 #if defined(FLASH_WRP0_WRP0)
 704       if(WRP0_Data != 0xFFU)
 705       {
 706         OB->WRP0 &= WRP0_Data;
 707         
 708         /* Wait for last operation to be completed */
 709         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 710       }
 711 #endif /* FLASH_WRP0_WRP0 */
 712 
 713 #if defined(FLASH_WRP1_WRP1)
 714       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
 715       {
 716         OB->WRP1 &= WRP1_Data;
 717         
 718         /* Wait for last operation to be completed */
 719         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 720       }
 721 #endif /* FLASH_WRP1_WRP1 */
 722 
 723 #if defined(FLASH_WRP2_WRP2)
 724       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
 725       {
 726         OB->WRP2 &= WRP2_Data;
 727         
 728         /* Wait for last operation to be completed */
 729         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 730       }
 731 #endif /* FLASH_WRP2_WRP2 */
 732 
 733 #if defined(FLASH_WRP3_WRP3)
 734       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
 735       {
 736         OB->WRP3 &= WRP3_Data;
 737         
 738         /* Wait for last operation to be completed */
 739         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 740       }
 741 #endif /* FLASH_WRP3_WRP3 */
 742 
 743       /* if the program operation is completed, disable the OPTPG Bit */
 744       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
 745     }
 746   }
 747   
 748   return status;
 749 }
 750 
 751 /**
 752   * @brief  Disable the write protection of the desired pages
 753   * @note   An option byte erase is done automatically in this function. 
 754   * @note   When the memory read protection level is selected (RDP level = 1), 
 755   *         it is not possible to program or erase the flash page i if   
 756   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1 
 757   * 
 758   * @param  WriteProtectPage specifies the page(s) to be write unprotected.
 759   *         The value of this parameter depend on device used within the same series 
 760   * @retval HAL status 
 761   */
 762 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
 763 {
 764   HAL_StatusTypeDef status = HAL_OK;
 765   uint16_t WRP0_Data = 0xFFFF;
 766 #if defined(FLASH_WRP1_WRP1)
 767   uint16_t WRP1_Data = 0xFFFF;
 768 #endif /* FLASH_WRP1_WRP1 */
 769 #if defined(FLASH_WRP2_WRP2)
 770   uint16_t WRP2_Data = 0xFFFF;
 771 #endif /* FLASH_WRP2_WRP2 */
 772 #if defined(FLASH_WRP3_WRP3)
 773   uint16_t WRP3_Data = 0xFFFF;
 774 #endif /* FLASH_WRP3_WRP3 */
 775   
 776   /* Check the parameters */
 777   assert_param(IS_OB_WRP(WriteProtectPage));
 778 
 779   /* Get current write protected pages and the new pages to be unprotected ******/
 780   WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
 781 
 782 #if defined(OB_WRP_PAGES0TO15MASK)
 783   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
 784 #elif defined(OB_WRP_PAGES0TO31MASK)
 785   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
 786 #endif /* OB_WRP_PAGES0TO31MASK */
 787   
 788 #if defined(OB_WRP_PAGES16TO31MASK)
 789   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
 790 #elif defined(OB_WRP_PAGES32TO63MASK)
 791   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
 792 #endif /* OB_WRP_PAGES32TO63MASK */
 793  
 794 #if defined(OB_WRP_PAGES64TO95MASK)
 795   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
 796 #endif /* OB_WRP_PAGES64TO95MASK */
 797 #if defined(OB_WRP_PAGES32TO47MASK)
 798   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
 799 #endif /* OB_WRP_PAGES32TO47MASK */
 800 
 801 #if defined(OB_WRP_PAGES96TO127MASK)
 802   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U); 
 803 #elif defined(OB_WRP_PAGES48TO255MASK)
 804   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U); 
 805 #elif defined(OB_WRP_PAGES48TO511MASK)
 806   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U); 
 807 #elif defined(OB_WRP_PAGES48TO127MASK)
 808   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); 
 809 #endif /* OB_WRP_PAGES96TO127MASK */
 810 
 811     
 812   /* Wait for last operation to be completed */
 813   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 814 
 815   if(status == HAL_OK)
 816   { 
 817     /* Clean the error context */
 818     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 819 
 820     /* To be able to write again option byte, need to perform a option byte erase */
 821     status = HAL_FLASHEx_OBErase();
 822     if (status == HAL_OK)  
 823     {
 824       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
 825 
 826 #if defined(FLASH_WRP0_WRP0)
 827       if(WRP0_Data != 0xFFU)
 828       {
 829         OB->WRP0 |= WRP0_Data;
 830         
 831         /* Wait for last operation to be completed */
 832         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 833       }
 834 #endif /* FLASH_WRP0_WRP0 */
 835 
 836 #if defined(FLASH_WRP1_WRP1)
 837       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
 838       {
 839         OB->WRP1 |= WRP1_Data;
 840         
 841         /* Wait for last operation to be completed */
 842         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 843       }
 844 #endif /* FLASH_WRP1_WRP1 */
 845 
 846 #if defined(FLASH_WRP2_WRP2)
 847       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
 848       {
 849         OB->WRP2 |= WRP2_Data;
 850         
 851         /* Wait for last operation to be completed */
 852         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 853       }
 854 #endif /* FLASH_WRP2_WRP2 */
 855 
 856 #if defined(FLASH_WRP3_WRP3)
 857       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
 858       {
 859         OB->WRP3 |= WRP3_Data;
 860         
 861         /* Wait for last operation to be completed */
 862         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 863       }
 864 #endif /* FLASH_WRP3_WRP3 */
 865 
 866       /* if the program operation is completed, disable the OPTPG Bit */
 867       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
 868     }
 869   }
 870   return status;
 871 }
 872 
 873 /**
 874   * @brief  Set the read protection level.
 875   * @param  ReadProtectLevel specifies the read protection level.
 876   *         This parameter can be one of the following values:
 877   *            @arg @ref OB_RDP_LEVEL_0 No protection
 878   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
 879   * @retval HAL status
 880   */
 881 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
 882 {
 883   HAL_StatusTypeDef status = HAL_OK;
 884   
 885   /* Check the parameters */
 886   assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
 887   
 888   /* Wait for last operation to be completed */
 889   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 890   
 891   if(status == HAL_OK)
 892   { 
 893     /* Clean the error context */
 894     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 895     
 896     /* If the previous operation is completed, proceed to erase the option bytes */
 897     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
 898     SET_BIT(FLASH->CR, FLASH_CR_STRT);
 899 
 900     /* Wait for last operation to be completed */
 901     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 902 
 903     /* If the erase operation is completed, disable the OPTER Bit */
 904     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
 905 
 906     if(status == HAL_OK)
 907     {
 908       /* Enable the Option Bytes Programming operation */
 909       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
 910       
 911       WRITE_REG(OB->RDP, ReadProtectLevel);
 912       
 913       /* Wait for last operation to be completed */
 914       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 
 915       
 916       /* if the program operation is completed, disable the OPTPG Bit */
 917       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
 918     }
 919   }
 920   
 921   return status;
 922 }
 923 
 924 /**
 925   * @brief  Program the FLASH User Option Byte.    
 926   * @note   Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
 927   * @param  UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2), 
 928   *         FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
 929   *         And BFBF2(Bit5) for STM32F101xG and STM32F103xG . 
 930   * @retval HAL status
 931   */
 932 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
 933 {
 934   HAL_StatusTypeDef status = HAL_OK;
 935 
 936   /* Check the parameters */
 937   assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
 938   assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
 939   assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
 940 #if defined(FLASH_BANK2_END)
 941   assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
 942 #endif /* FLASH_BANK2_END */
 943 
 944   /* Wait for last operation to be completed */
 945   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 946   
 947   if(status == HAL_OK)
 948   {     
 949     /* Clean the error context */
 950     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 951 
 952     /* Enable the Option Bytes Programming operation */
 953     SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 
 954  
 955 #if defined(FLASH_BANK2_END)
 956     OB->USER = (UserConfig | 0xF0U);
 957 #else
 958     OB->USER = (UserConfig | 0x88U);
 959 #endif /* FLASH_BANK2_END */
 960 
 961     /* Wait for last operation to be completed */
 962     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 963 
 964     /* if the program operation is completed, disable the OPTPG Bit */
 965     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
 966   }
 967   
 968   return status; 
 969 }
 970 
 971 /**
 972   * @brief  Programs a half word at a specified Option Byte Data address.
 973   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
 974   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
 975   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 
 976   *         (system reset will occur)
 977   *         Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
 978   * @param  Address specifies the address to be programmed.
 979   *         This parameter can be 0x1FFFF804 or 0x1FFFF806. 
 980   * @param  Data specifies the data to be programmed.
 981   * @retval HAL status
 982   */
 983 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
 984 {
 985   HAL_StatusTypeDef status = HAL_ERROR;
 986   
 987   /* Check the parameters */
 988   assert_param(IS_OB_DATA_ADDRESS(Address));
 989   
 990   /* Wait for last operation to be completed */
 991   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
 992   
 993   if(status == HAL_OK)
 994   {
 995     /* Clean the error context */
 996     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 997 
 998     /* Enables the Option Bytes Programming operation */
 999     SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 
1000     *(__IO uint16_t*)Address = Data;
1001     
1002     /* Wait for last operation to be completed */
1003     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1004     
1005     /* If the program operation is completed, disable the OPTPG Bit */
1006     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
1007   }
1008   /* Return the Option Byte Data Program Status */
1009   return status;
1010 }
1011 
1012 /**
1013   * @brief  Return the FLASH Write Protection Option Bytes value.
1014   * @retval The FLASH Write Protection Option Bytes value
1015   */
1016 static uint32_t FLASH_OB_GetWRP(void)
1017 {
1018   /* Return the FLASH write protection Register value */
1019   return (uint32_t)(READ_REG(FLASH->WRPR));
1020 }
1021 
1022 /**
1023   * @brief  Returns the FLASH Read Protection level.
1024   * @retval FLASH RDP level
1025   *         This parameter can be one of the following values:
1026   *            @arg @ref OB_RDP_LEVEL_0 No protection
1027   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
1028   */
1029 static uint32_t FLASH_OB_GetRDP(void)
1030 {
1031   uint32_t readstatus = OB_RDP_LEVEL_0;
1032   uint32_t tmp_reg = 0U;
1033   
1034   /* Read RDP level bits */
1035   tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
1036 
1037   if (tmp_reg == FLASH_OBR_RDPRT)
1038   {
1039     readstatus = OB_RDP_LEVEL_1;
1040   }
1041   else 
1042   {
1043     readstatus = OB_RDP_LEVEL_0;
1044   }
1045 
1046   return readstatus;
1047 }
1048 
1049 /**
1050   * @brief  Return the FLASH User Option Byte value.
1051   * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2), 
1052   *         FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
1053   *         And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG . 
1054   */
1055 static uint8_t FLASH_OB_GetUser(void)
1056 {
1057   /* Return the User Option Byte */
1058   return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
1059 }
1060 
1061 /**
1062   * @}
1063   */
1064 
1065 /**
1066   * @}
1067   */
1068 
1069 /** @addtogroup FLASH
1070   * @{
1071   */
1072 
1073 /** @addtogroup FLASH_Private_Functions
1074  * @{
1075  */
1076 
1077 /**
1078   * @brief  Erase the specified FLASH memory page
1079   * @param  PageAddress FLASH page to erase
1080   *         The value of this parameter depend on device used within the same series      
1081   * 
1082   * @retval None
1083   */
1084 void FLASH_PageErase(uint32_t PageAddress)
1085 {
1086   /* Clean the error context */
1087   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1088 
1089 #if defined(FLASH_BANK2_END)
1090   if(PageAddress > FLASH_BANK1_END)
1091   { 
1092     /* Proceed to erase the page */
1093     SET_BIT(FLASH->CR2, FLASH_CR2_PER);
1094     WRITE_REG(FLASH->AR2, PageAddress);
1095     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
1096   }
1097   else
1098   {
1099 #endif /* FLASH_BANK2_END */
1100     /* Proceed to erase the page */
1101     SET_BIT(FLASH->CR, FLASH_CR_PER);
1102     WRITE_REG(FLASH->AR, PageAddress);
1103     SET_BIT(FLASH->CR, FLASH_CR_STRT);
1104 #if defined(FLASH_BANK2_END)
1105   }
1106 #endif /* FLASH_BANK2_END */
1107 }
1108 
1109 /**
1110   * @}
1111   */
1112 
1113 /**
1114   * @}
1115   */
1116 
1117 #endif /* HAL_FLASH_MODULE_ENABLED */
1118 /**
1119   * @}
1120   */
1121