/**
  ******************************************************************************
  * @file    stm32wbxx_hal_flash_ex.c
  * @author  MCD Application Team
  * @brief   Extended FLASH HAL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the FLASH extended peripheral:
  *           + Extended programming operations functions
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
 @verbatim
 ==============================================================================
                   ##### Flash Extended features #####
  ==============================================================================

  [..] Comparing to other previous devices, the FLASH interface for STM32WBxx
       devices contains the following additional features

       (+) Capacity up to 1 Mbyte with single bank architecture supporting read-while-write
           capability (RWW)
       (+) Single bank memory organization
       (+) PCROP protection
       (+) WRP protection
       (+) CPU2 Security area
       (+) Program Erase Suspend feature

                        ##### How to use this driver #####
 ==============================================================================
  [..] This driver provides functions to configure and program the FLASH memory
       of all STM32WBxx devices. It includes
      (#) Flash Memory Erase functions:
           (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
                HAL_FLASH_Lock() functions
           (++) Erase function: Erase page, erase all sectors
           (++) There are two modes of erase :
             (+++) Polling Mode using HAL_FLASHEx_Erase()
             (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()

      (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
        (++) Set/Reset the write protection (per 4 KByte)
        (++) Set the Read protection Level
        (++) Program the user Option Bytes
        (++) Configure the PCROP protection (per 2 KByte)
        (++) Configure the IPCC Buffer start Address
        (++) Configure the CPU2 boot region and reset vector start Address
        (++) Configure the Flash and SRAM2 secure area

      (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
        (++) Get the value of a write protection area
        (++) Know if the read protection is activated
        (++) Get the value of the user Option Bytes
        (++) Get the value of a PCROP area
        (++) Get the IPCC Buffer start Address
        (++) Get the CPU2 boot region and reset vector start Address
        (++) Get the Flash and SRAM2 secure area

      (#) Flash Suspend, Allow functions:
           (++) Suspend or Allow new program or erase operation request using HAL_FLASHEx_SuspendOperation() and
                HAL_FLASHEx_AllowOperation() functions

      (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck().
          and modify this setting (for flash loader purpose e.g.) using
          HAL_FLASHEx_ForceFlashEmpty().

 @endverbatim
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal.h"

/** @addtogroup STM32WBxx_HAL_Driver
  * @{
  */

/** @defgroup FLASHEx FLASHEx
  * @brief FLASH Extended HAL module driver
  * @{
  */

#ifdef HAL_FLASH_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
  * @{
  */
static void              FLASH_AcknowledgePageErase(void);
static void              FLASH_FlushCaches(void);
static void              FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
static void              FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
static void              FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr,
                                                uint32_t PCROP1AEndAddr);
static void              FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr);
static void              FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr);
static void              FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam);
static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
static uint32_t          FLASH_OB_GetRDP(void);
static uint32_t          FLASH_OB_GetUser(void);
static void              FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr,
                                           uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
static uint32_t          FLASH_OB_GetIPCCBufferAddr(void);
static void              FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr,
                                                        uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode);
static void              FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion);
static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void);
/**
  * @}
  */

/* Exported functions -------------------------------------------------------*/
/** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
  * @{
  */

/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
  *  @brief   Extended IO operation functions
  *
@verbatim
 ===============================================================================
                ##### Extended programming operation functions #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to manage the Extended FLASH
    programming operations Operations.

@endverbatim
  * @{
  */
/**
  * @brief  Perform an erase of the specified FLASH memory pages.
  * @note   Before any operation, it is possible to check there is no operation suspended
  *         by call HAL_FLASHEx_IsOperationSuspended()
  * @param[in]  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
  *         contains the configuration information for the erasing.
  * @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)
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
{
  HAL_StatusTypeDef status;
  uint32_t index;

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Reset error code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  /* Verify that next operation can be proceed */
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

  if (status == HAL_OK)
  {
    if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGES)
    {
      /*Initialization of PageError variable*/
      *PageError = 0xFFFFFFFFU;

      for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
      {
        /* Start erase page */
        FLASH_PageErase(index);

        /* Wait for last operation to be completed */
        status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

        if (status != HAL_OK)
        {
          /* In case of error, stop erase procedure and return the faulty address */
          *PageError = index;
          break;
        }
      }

      /* If operation is completed or interrupted, disable the Page Erase Bit */
      FLASH_AcknowledgePageErase();
    }

    /* Flush the caches to be sure of the data consistency */
    FLASH_FlushCaches();
  }

  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);

  return status;
}

/**
  * @brief  Perform an erase of the specified FLASH memory pages with interrupt enabled.
  * @note   Before any operation, it is possible to check there is no operation suspended
  *         by call HAL_FLASHEx_IsOperationSuspended()
  * @param  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
  *         contains the configuration information for the erasing.
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
{
  HAL_StatusTypeDef status;

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Reset error code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  /* save procedure for interrupt treatment */
  pFlash.ProcedureOnGoing = pEraseInit->TypeErase;

  /* Verify that next operation can be proceed */
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

  if (status != HAL_OK)
  {
    /* Process Unlocked */
    __HAL_UNLOCK(&pFlash);
  }
  else
  {
    /* Enable End of Operation and Error interrupts */
    __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);

    if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGES)
    {
      /* Erase by page to be done */
      pFlash.NbPagesToErase = pEraseInit->NbPages;
      pFlash.Page = pEraseInit->Page;

      /*Erase 1st page and wait for IT */
      FLASH_PageErase(pEraseInit->Page);
    }
  }

  /* return status */
  return status;
}

/**
  * @brief  Program Option bytes.
  * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
  *         contains the configuration information for the programming.
  * @note   To configure any option bytes, the option lock bit OPTLOCK must be
  *         cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
  * @note   New option bytes configuration will be taken into account only
  *         - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
  *         - a Power On Reset
  *         - an exit from Standby or Shutdown mode.
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
{
  uint32_t optr;
  HAL_StatusTypeDef status;

  /* Check the parameters */
  assert_param(IS_OPTIONBYTE(pOBInit->OptionType));

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  /* Write protection configuration */
  if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
  {
    /* Configure of Write protection on the selected area */
    FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
  }

  /* Option register */
  if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
  {
    /* Fully modify OPTR register with RDP & user data */
    FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, pOBInit->RDPLevel);
  }
  else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
  {
    /* Only modify RDP so get current user data */
    optr = FLASH_OB_GetUser();

    /* Remove BOR LEVEL User Type*/
    optr &= ~OB_USER_BOR_LEV;

    FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
  }
  else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
  {
    /* Only modify user so get current RDP level */
    optr = FLASH_OB_GetRDP();
    FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, optr);
  }
  else
  {
    /* Do Nothing */
  }

  /* PCROP Configuration */
  if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
  {
    /* Check the parameters */
    assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));

    if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0U)
    {
      /* Configure the Zone 1A Proprietary code readout protection */
      FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
    }

    if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0U)
    {
      /* Configure the Zone 1B Proprietary code readout protection */
      FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
    }
  }

  /*  Secure mode and CPU2 Boot Vector */
  if ((pOBInit->OptionType & (OPTIONBYTE_SECURE_MODE | OPTIONBYTE_C2_BOOT_VECT)) != 0U)
  {
    /* Set the secure flash and SRAM memory start address */
    FLASH_OB_SecureConfig(pOBInit);
  }

  /* IPCC mailbox data buffer address */
  if ((pOBInit->OptionType & OPTIONBYTE_IPCC_BUF_ADDR) != 0U)
  {
    /* Configure the IPCC data buffer address */
    FLASH_OB_IPCCBufferAddrConfig(pOBInit->IPCCdataBufAddr);
  }

  /* Proceed the OB Write Operation */
  status = FLASH_OB_ProceedWriteOperation();

  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);

  /* return status */
  return status;
}

/**
  * @brief  Get the Option bytes configuration.
  * @note   warning: this API only read flash register, it does not reflect any
  *         change that would have been programmed between previous Option byte
  *         loading and current call.
  * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
  *                  configuration information. The fields pOBInit->WRPArea and
  *                  pOBInit->PCROPConfig should indicate which area is requested
  *                  for the WRP and PCROP.
  * @retval None
  */
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
{
  pOBInit->OptionType = OPTIONBYTE_ALL;

  if ((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))
  {
    /* Get write protection on the selected area */
    FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
  }

  /* Get Read protection level */
  pOBInit->RDPLevel = FLASH_OB_GetRDP();

  /* Get the user option bytes */
  pOBInit->UserConfig = FLASH_OB_GetUser();
  pOBInit->UserType = OB_USER_ALL;

  /* Get the Zone 1A and 1B Proprietary code readout protection */
  FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr),
                    &(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
  pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);

  /* Get the IPCC start Address */
  pOBInit->IPCCdataBufAddr = FLASH_OB_GetIPCCBufferAddr();

  /* Get the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the Security Mode, */
  FLASH_OB_GetSecureMemoryConfig(&(pOBInit->SecureFlashStartAddr), &(pOBInit->SecureRAM2aStartAddr),
                                 &(pOBInit->SecureRAM2bStartAddr), &(pOBInit->SecureMode));

  /* Get the M0+ Secure Boot reset vector and Secure Boot memory selection */
  FLASH_OB_GetC2BootResetConfig(&(pOBInit->C2SecureBootVectAddr), &(pOBInit->C2BootRegion));
}

/**
  * @brief  Flash Empty check
  * @note   This API checks if first location in Flash is programmed or not.
  *         This check is done once by Option Byte Loader.
  * @retval Returned value can be one of the following values:
  *         @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
  *         @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
  */
uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
{
  return (READ_BIT(FLASH->ACR, FLASH_ACR_EMPTY));
}


/**
  * @brief  Force Empty check value.
  * @note   Allows to modify program empty check value in order to force this
  *         information in Flash Interface, for all next reset that do not launch
  *         Option Byte Loader.
  * @param  FlashEmpty Specifies the empty check value
  *          This parameter can be one of the following values:
  *            @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
  *            @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
  * @retval None
  */
void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
{
  assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));

  MODIFY_REG(FLASH->ACR, FLASH_ACR_EMPTY, FlashEmpty);
}

/**
  * @brief  Suspend new program or erase operation request.
  * @note   Any new Flash program and erase operation on both CPU side will be suspended
  *         until this bit and the same bit in Flash CPU2 access control register (FLASH_C2ACR) are
  *         cleared. The PESD bit in both the Flash status register (FLASH_SR) and Flash
  *         CPU2 status register (FLASH_C2SR) register will be set when at least one PES
  *         bit in FLASH_ACR or FLASH_C2ACR is set.
  * @retval None
  */
void HAL_FLASHEx_SuspendOperation(void)
{
  SET_BIT(FLASH->ACR, FLASH_ACR_PES);
}

/**
  * @brief  Allow new program or erase operation request.
  * @note   Any new Flash program and erase operation on both CPU side will be allowed
  *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
  *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
  *         CPU2 status register (FLASH_C2SR) register will be clear when both PES
  *         bit in FLASH_ACR or FLASH_C2ACR is cleared.
  * @retval None
  */
void HAL_FLASHEx_AllowOperation(void)
{
  CLEAR_BIT(FLASH->ACR, FLASH_ACR_PES);
}

/**
  * @brief  Check if new program or erase operation request from CPU1 or CPU2 is suspended
  * @note   Any new Flash program and erase operation on both CPU side will be allowed
  *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
  *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
  *         CPU2 status register (FLASH_C2SR) register will be cleared when both PES
  *         bit in FLASH_ACR and FLASH_C2ACR are cleared.
  * @retval Status
  *          - 0 : No suspended flash operation
  *          - 1 : Flash operation is suspended
  */
uint32_t HAL_FLASHEx_IsOperationSuspended(void)
{
  uint32_t status = 0U;

  if (READ_BIT(FLASH->SR, FLASH_SR_PESD) == FLASH_SR_PESD)
  {
    status = 1U;
  }

  return status;
}

/**
  * @}
  */

/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/
/** @addtogroup FLASHEx_Private_Functions
  * @{
  */

/**
  * @brief  Erase the specified FLASH memory page.
  * @param  Page FLASH page to erase
  *         This parameter must be a value between 0 and (max number of pages in Flash - 1)
  * @retval None
  */
void FLASH_PageErase(uint32_t Page)
{
  /* Check the parameters */
  assert_param(IS_FLASH_PAGE(Page));

  /* Proceed to erase the page */
  MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT));
}

/**
  * @brief  Flush the instruction and data caches.
  * @retval None
  */
static void FLASH_FlushCaches(void)
{
  /* Flush instruction cache  */
  if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == FLASH_ACR_ICEN)
  {
    /* Disable instruction cache  */
    __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
    /* Reset instruction cache */
    __HAL_FLASH_INSTRUCTION_CACHE_RESET();
    /* Enable instruction cache */
    __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  }

  /* Flush data cache */
  if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == FLASH_ACR_DCEN)
  {
    /* Disable data cache  */
    __HAL_FLASH_DATA_CACHE_DISABLE();
    /* Reset data cache */
    __HAL_FLASH_DATA_CACHE_RESET();
    /* Enable data cache */
    __HAL_FLASH_DATA_CACHE_ENABLE();
  }
}

/**
  * @brief  Acknlowldge the page erase operation.
  * @retval None
  */
static void FLASH_AcknowledgePageErase(void)
{
  CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
}

/**
  * @brief  Configure the write protection of the desired pages.
  * @note   When WRP is active in a zone, it cannot be erased or programmed.
  *         Consequently, a software mass erase cannot be performed if one zone
  *         is write-protected.
  * @note   When the memory read protection level is selected (RDP level = 1),
  *         it is not possible to program or erase Flash memory if the CPU debug
  *         features are connected (JTAG or single wire) or boot code is being
  *         executed from RAM or System flash, even if WRP is not activated.
  * @note   To configure the WRP options, the option lock bit OPTLOCK must be
  *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
  * @note   To validate the WRP options, the option bytes must be reloaded
  *         through the call of the @ref HAL_FLASH_OB_Launch() function.
  * @param  WRPArea Specifies the area to be configured.
  *          This parameter can be one of the following values:
  *            @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
  *            @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
  * @param  WRPStartOffset Specifies the start page of the write protected area
  *          This parameter can be page number between 0 and (max number of pages in the Flash - 1)
  * @param  WRDPEndOffset Specifies the end page of the write protected area
  *          This parameter can be page number between WRPStartOffset and (max number of pages in the Flash - 1)
  * @retval None
  */
static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
{
  /* Check the parameters */
  assert_param(IS_OB_WRPAREA(WRPArea));
  assert_param(IS_FLASH_PAGE(WRPStartOffset));
  assert_param(IS_FLASH_PAGE(WRDPEndOffset));

  /* Configure the write protected area */
  if (WRPArea == OB_WRPAREA_BANK1_AREAA)
  {
    MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
               (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
  }
  else /* OB_WRPAREA_BANK1_AREAB */
  {
    MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
               (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
  }
}

/**
  * @brief  Set user & RDP configuration
  * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
  *         to go back to level 1 or 0 !!!
  * @param  UserType The FLASH User Option Bytes to be modified
  *         This parameter can be a combination of all the following values:
  *         @arg @ref OB_USER_BOR_LEV or @ref OB_USER_nRST_STOP or @ref OB_USER_nRST_STDBY or
  *         @arg @ref OB_USER_nRST_SHDW or @ref OB_USER_IWDG_SW or @ref OB_USER_IWDG_STOP or
  *         @arg @ref OB_USER_IWDG_STDBY or @ref OB_USER_WWDG_SW or @ref OB_USER_nBOOT1 or
  *         @arg @ref OB_USER_SRAM2PE or @ref OB_USER_SRAM2RST or @ref OB_USER_nSWBOOT0 or
  *         @arg @ref OB_USER_nBOOT0 or @ref OB_USER_AGC_TRIM or @ref OB_USER_ALL
  * @param  UserConfig The FLASH User Option Bytes values.
  *         This parameter can be a combination of all the following values:
  *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
  *         @arg @ref OB_STOP_RST or @ref OB_STOP_NORST
  *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
  *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
  *         @arg @ref OB_IRH_ENABLE or @ref OB_IRH_DISABLE (*)
  *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
  *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
  *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
  *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
  *         @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM
  *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
  *         @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE
  *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
  *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
  *         @arg @ref OB_RESET_MODE_INPUT_ONLY or @ref OB_RESET_MODE_GPIO or @ref OB_RESET_MODE_INPUT_OUTPUT (*)
  *         @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7
  * @param  RDPLevel: specifies the read protection level.
  *         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
  *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
  * @retval None
  */
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
{
  uint32_t optr;

  /* Check the parameters */
  assert_param(IS_OB_USER_TYPE(UserType));
  assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
  assert_param(IS_OB_RDP_LEVEL(RDPLevel));

  /* Configure the RDP level in the option bytes register */
  optr = FLASH->OPTR;
  optr &= ~(UserType | FLASH_OPTR_RDP);
  FLASH->OPTR = (optr | UserConfig | RDPLevel);
}

/**
  * @brief  Configure the Zone 1A Proprietary code readout protection of the desired addresses,
  *         and erase configuration on RDP regression.
  * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
  *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
  * @note   To validate the PCROP options, the option bytes must be reloaded
  *         through the call of the @ref HAL_FLASH_OB_Launch() function.
  * @param  PCROPConfig: specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
  *         on RDP level 1 regression.
  * @param  PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
  *         This parameter can be an address between begin and end of the flash
  * @param  PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
  *         This parameter can be an address between PCROP1AStartAddr and end of the flash
  * @retval None
  */
static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
{
  uint32_t startoffset;
  uint32_t endoffset;
  uint32_t pcrop1aend;

  /* Check the parameters */
  assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
  assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AStartAddr));
  assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AEndAddr));

  /* get pcrop 1A end register */
  pcrop1aend = FLASH->PCROP1AER;

  /* Configure the Proprietary code readout protection offset */
  if ((PCROPConfig & OB_PCROP_ZONE_A) != 0U)
  {
    /* Compute offset depending on pcrop granularity */
    startoffset = ((PCROP1AStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
    endoffset = ((PCROP1AEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */

    /* Set Zone A start offset */
    WRITE_REG(FLASH->PCROP1ASR, startoffset);

    /* Set Zone A end offset */
    pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
    pcrop1aend |= endoffset;
  }

  /* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
  if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0U)
  {
    pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
  }

  /* set 1A End register */
  WRITE_REG(FLASH->PCROP1AER, pcrop1aend);
}

/**
  * @brief  Configure the Zone 1B Proprietary code readout protection of the desired addresses.
  * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
  *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
  * @note   To validate the PCROP options, the option bytes must be reloaded
  *         through the call of the @ref HAL_FLASH_OB_Launch() function.
  * @param  PCROP1BStartAddr Specifies the Zone 1BStart address of the Proprietary code readout protection
  *         This parameter can be an address between begin and end of the flash
  * @param  PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
  *         This parameter can be an address between PCROP1BStartAddr and end of the flash
  * @retval None
  */
static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
{
  uint32_t startoffset;
  uint32_t endoffset;

  /* Check the parameters */
  assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BStartAddr));
  assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BEndAddr));

  /* Compute offset depending on pcrop granularity */
  startoffset = ((PCROP1BStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
  endoffset = ((PCROP1BEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */

  /* Configure the Proprietary code readout protection start address */
  WRITE_REG(FLASH->PCROP1BSR, startoffset);

  /* Configure the Proprietary code readout protection end address */
  WRITE_REG(FLASH->PCROP1BER, endoffset);
}

/**
  * @brief  Program the FLASH IPCC data buffer address.
  * @note   To configure the extra user option bytes, the option lock bit OPTLOCK must
  *         be cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
  * @note   To validate the extra user option bytes, the option bytes must be reloaded
  *         through the call of the @ref HAL_FLASH_OB_Launch() function.
  * @param  IPCCDataBufAddr IPCC data buffer start address area in SRAM2
  *         This parameter must be the double-word aligned
  * @retval None
  */
static void FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr)
{
  assert_param(IS_OB_IPCC_BUF_ADDR(IPCCDataBufAddr));

  /* Configure the option bytes register */
  WRITE_REG(FLASH->IPCCBR, (uint32_t)((IPCCDataBufAddr - SRAM2A_BASE) >> 4));
}

/**
  * @brief  Configure the secure start address of the different memories (FLASH and SRAM2),
  *         the secure mode and the CPU2 Secure Boot reset vector
  * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
  *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
  * @param  pOBParam Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
  *         contains the configuration information for the programming
  * @retval void
  */
static void FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam)
{
  uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
  uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);

  if ((pOBParam->OptionType & OPTIONBYTE_SECURE_MODE) != 0U)
  {
    assert_param(IS_OB_SFSA_START_ADDR(pOBParam->SecureFlashStartAddr));
    assert_param(IS_OB_SBRSA_START_ADDR(pOBParam->SecureRAM2aStartAddr));
    assert_param(IS_OB_SNBRSA_START_ADDR(pOBParam->SecureRAM2bStartAddr));
    assert_param(IS_OB_SECURE_MODE(pOBParam->SecureMode));

    /* Configure SFR register content with start PAGE index to secure */
    MODIFY_REG(sfr_reg_val, FLASH_SFR_SFSA, (((pOBParam->SecureFlashStartAddr - FLASH_BASE) / FLASH_PAGE_SIZE) << FLASH_SFR_SFSA_Pos));

    /* Configure SRRVR register */
#if defined(FLASH_SRRVR_SBRSA_A)
    MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA_A | FLASH_SRRVR_SBRSA_B), \
               (((((pOBParam->SecureRAM2aStartAddr - SRAM2A_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_A_Pos)) | \
                ((((pOBParam->SecureRAM2bStartAddr - SRAM2B_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_B_Pos))));
#else
    MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA | FLASH_SRRVR_SNBRSA), \
               (((((pOBParam->SecureRAM2aStartAddr - SRAM2A_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_Pos)) | \
                ((((pOBParam->SecureRAM2bStartAddr - SRAM2B_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SNBRSA_Pos))));
#endif /* FLASH_SRRVR_SBRSA_A */

    /* If Full System Secure mode is requested, clear all the corresponding bit */
    /* Else set the corresponding bit */
    if (pOBParam->SecureMode == SYSTEM_IN_SECURE_MODE)
    {
      CLEAR_BIT(sfr_reg_val, FLASH_SFR_FSD);
#if defined(FLASH_SRRVR_BRSD_A)
      CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD_A | FLASH_SRRVR_BRSD_B));
#else
      CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
#endif /* FLASH_SRRVR_BRSD_A */
    }
    else
    {
      SET_BIT(sfr_reg_val, FLASH_SFR_FSD);
#if defined(FLASH_SRRVR_BRSD_A)
      SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD_A | FLASH_SRRVR_BRSD_B));
#else
      SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
#endif /* FLASH_SRRVR_BRSD_A */
    }

    /* Update Flash registers */
    WRITE_REG(FLASH->SFR, sfr_reg_val);
  }

  /* Boot vector */
  if ((pOBParam->OptionType & OPTIONBYTE_C2_BOOT_VECT) != 0U)
  {
    /* Check the parameters */
    assert_param(IS_OB_BOOT_VECTOR_ADDR(pOBParam->C2SecureBootVectAddr));
    assert_param(IS_OB_BOOT_REGION(pOBParam->C2BootRegion));

    /* Set the boot vector */
    if (pOBParam->C2BootRegion == OB_C2_BOOT_FROM_FLASH)
    {
      MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT),
                 (((pOBParam->C2SecureBootVectAddr - FLASH_BASE) >> 2) | pOBParam->C2BootRegion));
    }
    else
    {
      MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT),
                 (((pOBParam->C2SecureBootVectAddr - SRAM1_BASE) >> 2) | pOBParam->C2BootRegion));
    }
  }

  /* Update Flash registers */
  WRITE_REG(FLASH->SRRVR, srrvr_reg_val);
}

/**
  * @brief  Return the FLASH Write Protection Option Bytes value.
  * @param[in]   WRPArea Specifies the area to be returned.
  *              This parameter can be one of the following values:
  *              @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
  *              @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
  * @param[out]  WRPStartOffset Specifies the address where to copied the start page
  *                             of the write protected area
  * @param[out]  WRDPEndOffset Specifies the address where to copied the end page of
  *                            the write protected area
  * @retval None
  */
static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
{
  /* Check the parameters */
  assert_param(IS_OB_WRPAREA(WRPArea));

  /* Get the configuration of the write protected area */
  if (WRPArea == OB_WRPAREA_BANK1_AREAA)
  {
    *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
    *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
  }
  else /* OB_WRPAREA_BANK1_AREAB */
  {
    *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
    *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
  }
}

/**
  * @brief  Return the FLASH Read Protection level.
  * @retval FLASH ReadOut Protection Status:
  *         This return value 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
  *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
  */
static uint32_t FLASH_OB_GetRDP(void)
{
  uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);

  if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
  {
    return (OB_RDP_LEVEL_1);
  }
  else
  {
    return rdplvl;
  }
}

/**
  * @brief  Return the FLASH User Option Byte value.
  * @retval This return value can be a combination of all the following values:
  *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
  *         @arg @ref OB_STOP_RST or @ref OB_STOP_RST
  *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
  *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
  *         @arg @ref OB_IRH_ENABLE or @ref OB_IRH_DISABLE (*)
  *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
  *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
  *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
  *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
  *         @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM
  *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
  *         @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE
  *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
  *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
  *         @arg @ref OB_RESET_MODE_INPUT_ONLY or @ref OB_RESET_MODE_GPIO or @ref OB_RESET_MODE_INPUT_OUTPUT (*)
  *         @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7
  */
static uint32_t FLASH_OB_GetUser(void)
{
  uint32_t user_config = (READ_REG(FLASH->OPTR) & OB_USER_ALL);
  CLEAR_BIT(user_config, (FLASH_OPTR_RDP | FLASH_OPTR_ESE));

  return user_config;
}

/**
  * @brief  Return the FLASH Write Protection Option Bytes value.
  * @param PCROPConfig [out] Specifies the address where to copied the configuration of PCROP_RDP option
  * @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
  *                         of the Zone 1A Proprietary code readout protection
  * @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
  *                       the Zone 1A Proprietary code readout protection
  * @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
  *                         of the Zone 1B Proprietary code readout protection
  * @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
  *                       the Zone 1B Proprietary code readout protection
  * @retval None
  */
static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr,
                              uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
{
  uint32_t pcrop;

  pcrop             = (READ_BIT(FLASH->PCROP1BSR, FLASH_PCROP1BSR_PCROP1B_STRT));
  *PCROP1BStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);

  pcrop             = (READ_BIT(FLASH->PCROP1BER, FLASH_PCROP1BER_PCROP1B_END));
  *PCROP1BEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);

  pcrop             = (READ_BIT(FLASH->PCROP1ASR, FLASH_PCROP1ASR_PCROP1A_STRT));
  *PCROP1AStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);

  pcrop             = (READ_BIT(FLASH->PCROP1AER, FLASH_PCROP1AER_PCROP1A_END));
  *PCROP1AEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);

  *PCROPConfig      = (READ_REG(FLASH->PCROP1AER) & FLASH_PCROP1AER_PCROP_RDP);
}

/**
  * @brief  Return the FLASH IPCC data buffer base address Option Byte value.
  * @retval Returned value is the IPCC data buffer start address area in SRAM2.
  */
static uint32_t FLASH_OB_GetIPCCBufferAddr(void)
{
  return (uint32_t)((READ_BIT(FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA) << 4) + SRAM2A_BASE);
}

/**
  * @brief  Return the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the SecureMode
  * @param  SecureFlashStartAddr Specifies the address where to copied the Secure Flash start address
  * @param  SecureRAM2aStartAddr Specifies the address where to copied the Secure Backup RAM2a start address
  * @param  SecureRAM2bStartAddr Specifies the address where to copied the Secure non-Backup RAM2b start address
  * @param  SecureMode           Specifies the address where to copied the Secure Mode.
  *                              This return value can be one of the following values:
  *                              @arg @ref SYSTEM_IN_SECURE_MODE : Security enabled
  *                              @arg @ref SYSTEM_NOT_IN_SECURE_MODE : Security disabled
  * @retval None
  */
static void FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr,
                                           uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode)
{
  uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
  uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);

  /* Get Secure Flash start address */
  uint32_t user_config = (READ_BIT(sfr_reg_val, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos);

  *SecureFlashStartAddr = ((user_config * FLASH_PAGE_SIZE) + FLASH_BASE);

  /* Get Secure SRAM2a start address */
#if defined(FLASH_SRRVR_SBRSA_A)
  user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA_A) >> FLASH_SRRVR_SBRSA_A_Pos);
#else
  user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA) >> FLASH_SRRVR_SBRSA_Pos);
#endif /* FLASH_SRRVR_SBRSA_A */

  *SecureRAM2aStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2A_BASE);

  /* Get Secure SRAM2b start address */
#if defined(FLASH_SRRVR_SBRSA_B)
  user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA_B) >> FLASH_SRRVR_SBRSA_B_Pos);
#else
  user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SNBRSA) >> FLASH_SRRVR_SNBRSA_Pos);
#endif /* FLASH_SRRVR_SBRSA_B */

  *SecureRAM2bStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2B_BASE);

  /* Get Secure Area mode */
  *SecureMode = (READ_BIT(FLASH->OPTR, FLASH_OPTR_ESE));
}

/**
  * @brief  Return the CPU2 Secure Boot reset vector address and the CPU2 Secure Boot Region
  * @param  C2BootResetVectAddr Specifies the address where to copied the CPU2 Secure Boot reset vector address
  * @param  C2BootResetRegion   Specifies the Secure Boot reset memory region
  * @retval None
  */
static void FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion)
{
  *C2BootResetRegion = (READ_BIT(FLASH->SRRVR, FLASH_SRRVR_C2OPT));

  if (*C2BootResetRegion == OB_C2_BOOT_FROM_FLASH)
  {
    *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + FLASH_BASE);
  }
  else
  {
    *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + SRAM1_BASE);
  }
}

/**
  * @brief  Proceed the OB Write Operation.
  * @retval HAL Status
  */
static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void)
{
  HAL_StatusTypeDef status;

  /* Verify that next operation can be proceed */
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

  if (status == HAL_OK)
  {
    /* Set OPTSTRT Bit */
    SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  }

  return status;
}

/**
  * @}
  */

/**
  * @}
  */

#endif /* HAL_FLASH_MODULE_ENABLED */

/**
  * @}
  */

/**
  * @}
  */
