text: /**
    ******************************************************************************
    * @file    stm32u5xx_hal_ramcfg.c
    * @author  MCD Application Team
    * @brief   RAMCFG HAL module driver.
    *          This file provides firmware functions to manage the following
    *          functionalities of the RAMs configuration controller peripheral:
    *           + RAMCFG Initialization and De-initialization Functions.
    *           + RAMCFG ECC Operation Functions.
    *           + RAMCFG Configure Wait State Functions.
    *           + RAMCFG Write Protection Functions.
    *           + RAMCFG Erase Operation Functions.
    *           + RAMCFG Handle Interrupt and Callbacks Functions.
    *           + RAMCFG State and Error Functions.
    ******************************************************************************
    * @attention
    *
    * Copyright (c) 2021 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
    ==============================================================================
                      ##### RAMCFG Peripheral features #####
    ==============================================================================
    [..]
      (+) Each SRAM is managed by a RAMCFG instance.
  
      (+) Each SRAM can be erased independently through its RAMCFG instance.
  
      (+) The wait state value for each SRAM can be configured independently
          through its RAMCFG instance.
  
      (+) SRAM2 is divided to 64 pages with 1 kB granularity. Each page can be
          write protected independently through its RAMCFG instance.
  
      (+) SRAM2, SRAM3 and BKPRAM support ECC correction feature. This mechanism
          adopts the Single Error Correction Double Error Detection (SECDED)
          algorithm. This feature provides the following information:
               (++) Single error address.
               (++) Double error address.
    ==============================================================================
                          ##### How to use this driver #####
    ==============================================================================
    [..]
     (#) Call HAL_RAMCFG_Init() to initialize the RAMCFG peripheral before using
         any feature. Call HAL_RAMCFG_DeInit() to de-initialize the RAMCFG when
         using this peripheral is no more needed or a hardware issue has occurred.
  
       *** ECC feature ***
       ===================
      [..]
            (+) Call HAL_RAMCFG_StartECC() and HAL_RAMCFG_StopECC() to enable and
                disable ECC hardware process.
  
            (+) Call HAL_RAMCFG_EnableNotification() and HAL_RAMCFG_DisableNotification()
                to enable and disable ECC interrupts. Interrupts can be :
                      (++) Single error interrupt.
                      (++) Double error interrupt.
                      (++) Double error interrupt redirected to Non masKable
                            interrupt (NMI).
  
            (+) Call HAL_RAMCFG_GetSingleErrorAddress() to get the address of the
                last fail RAM word detected (only for single error)  and
                call HAL_RAMCFG_GetDoubleErrorAddress() to get the address of the
                last fail RAM word detected (only for double error).
  
            (+) Call HAL_RAMCFG_IsECCErrorDetected() to check if an ECC single/double
                error was detected. This API is used in silent mode (No ECC interrupt
                is enabled).
  
       *** Wait State feature ***
       ==========================
      [..]
            (+) Call HAL_RAMCFG_ConfigWaitState() to configure the wait state value
                for a given SRAM according to the HCLK frequency and voltage range
                scaling.
  
            (+) Call HAL_RAMCFG_GetWaitState() to get the current configured wait
                state value.
  
       *** Write protection feature ***
       ================================
      [..]
            (+) Call HAL_RAMCFG_EnableWriteProtection() to enable the write
                protection for the given SRAM2 page(s).
  
            (+) There is no API to disable write protection as this feature can
                be disabled only by a global peripheral reset or system reset.
  
            (+) Any write access to a write protected area of SRAM2 causes a
                HardFault interrupt.
  
       *** Erase feature ***
       =====================
      [..]
            (+) Call HAL_RAMCFG_Erase() to launch a hardware erase for the given
                SRAM.
  
            (+) The erase value is equal to 0 when launching erase hardware through
                RAMCFG.
  
            (+) SRAM2 write protected pages are erased when performing an erase
                through RAMCFG.
  
       *** RAMCFG HAL driver macros list ***
       =====================================
       [..]
         Below the list of used macros in RAMCFG HAL driver.
  
        (+) __HAL_RAMCFG_ENABLE_IT     : Enable the specified RAMCFG interrupts.
        (+) __HAL_RAMCFG_DISABLE_IT    : Disable the specified RAMCFG interrupts.
        (+) __HAL_RAMCFG_GET_FLAG      : Get the RAMCFG pending flags.
        (+) __HAL_RAMCFG_CLEAR_FLAG    : Clear the RAMCFG pending flags.
        (+) __HAL_RAMCFG_GET_IT_SOURCE : Check whether the specified RAMCFG
                                         interrupt source is enabled or not.
    @endverbatim
    */
  
  /* Includes ------------------------------------------------------------------*/
  #include "stm32u5xx_hal.h"
  
  /** @addtogroup STM32U5xx_HAL_Driver
    * @{
    */
  
  /** @defgroup RAMCFG RAMCFG
    * @brief RAMCFG HAL module driver
    * @{
    */
  
  #ifdef HAL_RAMCFG_MODULE_ENABLED
  
  /* Private types -------------------------------------------------------------*/
  /* Private variables ---------------------------------------------------------*/
  /* Private constants ---------------------------------------------------------*/
  
  /** @addtogroup RAMCFG_Private_Constants
    * @{
    */
  #define RAMCFG_TIMEOUT_VALUE 50000U
  /**
    * @}
    */
  
  /* Private macros ------------------------------------------------------------*/
  /* Private functions ---------------------------------------------------------*/
  /* Exported functions --------------------------------------------------------*/
  
  /** @addtogroup RAMCFG_Exported_Functions
    * @{
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group1
    *
  @verbatim
   ===============================================================================
               ##### Initialization and de-initialization Functions  #####
   ===============================================================================
      [..]
      This section provides functions allowing to initialize and de-initialize the
      RAMCFG instance.
      [..]
      The HAL_RAMCFG_Init() function follows the RAMCFG instance configuration
      procedures as described in the reference manual.
      The HAL_RAMCFG_DeInit() function allows to deinitialize the RAMCFG instance.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Initialize the RAMCFG by clearing flags and disabling interrupts.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG
    *                   instance.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_Init(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the RAMCFG peripheral handle */
    if (hramcfg == NULL)
    {
      return HAL_ERROR;
    }
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Update RAMCFG peripheral state */
    hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
  #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
    /* Check if a valid MSP API was registered */
    if (hramcfg->MspInitCallback == NULL)
    {
      /* Init the low level hardware */
      hramcfg->MspInitCallback = HAL_RAMCFG_MspInit;
    }
  
    /* Init the low level hardware */
    hramcfg->MspInitCallback(hramcfg);
  #else
    HAL_RAMCFG_MspInit(hramcfg);
  #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
  
    /* Unlock the SRAM ECC enable bit and disable the ECC feature */
    WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY1);
    WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY2);
    hramcfg->Instance->CR &= ~(RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
  
    /* Disable all RAMCFG interrupts */
    __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL);
  
    /* Clear RAMCFG monitor flags */
    __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL);
  
    /* Initialise the RAMCFG error code */
    hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE;
  
    /* Initialize the RAMCFG state */
    hramcfg->State = HAL_RAMCFG_STATE_READY;
  
    return HAL_OK;
  }
  
  /**
    * @brief  DeInitialize the RAMCFG peripheral.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG
    *                   instance.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_DeInit(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the RAMCFG peripheral handle */
    if (hramcfg == NULL)
    {
      return HAL_ERROR;
    }
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Unlock the SRAM ECC enable bit and disable the ECC feature */
    WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY1);
    WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY2);
    hramcfg->Instance->CR &= ~(RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
  
    /* Disable all RAMCFG interrupts */
    __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL);
  
    /* Clear RAMCFG monitor flags */
    __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL);
  
  #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
    /* Check if a valid MSP API was registered */
    if (hramcfg->MspDeInitCallback != NULL)
    {
      /* Init the low level hardware */
      hramcfg->MspDeInitCallback(hramcfg);
    }
  
    /* Clean callbacks */
    hramcfg->DetectSingleErrorCallback = NULL;
    hramcfg->DetectDoubleErrorCallback = NULL;
  #else
    HAL_RAMCFG_MspDeInit(hramcfg);
  #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
  
    /* Reset the RAMCFG error code */
    hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE;
  
    /* Reset the RAMCFG state */
    hramcfg->State = HAL_RAMCFG_STATE_RESET;
  
    return HAL_OK;
  }
  
  /**
    * @brief Initialize the RAMCFG MSP.
    * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                  the configuration information for the specified RAMCFG.
    * @retval None.
    */
  __weak void HAL_RAMCFG_MspInit(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Prevent unused argument(s) compilation warning */
    UNUSED(hramcfg);
  
    /* NOTE : This function should not be modified, when the callback is needed,
              the HAL_RAMCFG_MspInit can be implemented in the user file      */
  }
  
  /**
    * @brief DeInitialize the RAMCFG MSP.
    * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                  the configuration information for the specified RAMCFG.
    * @retval None.
    */
  __weak void HAL_RAMCFG_MspDeInit(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Prevent unused argument(s) compilation warning */
    UNUSED(hramcfg);
  
    /* NOTE : This function should not be modified, when the callback is needed,
              the HAL_RAMCFG_MspDeInit can be implemented in the user file    */
  }
  /**
    * @}
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group2
    *
  @verbatim
   ===============================================================================
                        ##### ECC Operations Functions  #####
   ===============================================================================
      [..]
      This section provides functions allowing to manage ECC feature provided by
      the RAMCFG peripheral.
      [..]
      The HAL_RAMCFG_StartECC() function allows enabling and starting the ECC
      mechanism for the selected RAMCFG instance.
      The HAL_RAMCFG_StopECC() function allows disabling and stopping the ECC
      mechanism for the selected RAMCFG instance.
      The HAL_RAMCFG_EnableNotification() function allows enabling interrupts
      for single ECC error, double ECC error and NMI error.
      The HAL_RAMCFG_DisableNotification() function allows disabling interrupts
      for single ECC error, double ECC error. When NMI interrupt is enabled it
      can only be disabled by a global peripheral reset or by a system reset.
      The HAL_RAMCFG_IsECCErrorDetected() function allows to check if an ECC error
      has occurred.
      The HAL_RAMCFG_GetSingleErrorAddress() function allows to get the address of
      the last single ECC error detected.
      The HAL_RAMCFG_GetDoubleErrorAddress() function allows to get the address of
      the last double ECC error detected.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Start ECC mechanism for the given SRAM.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG
    *                   instance.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_StartECC(RAMCFG_HandleTypeDef *hramcfg)
  {
  
    HAL_StatusTypeDef status = HAL_OK;
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Check if ECC mechanism is active */
      if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) != RAMCFG_CR_ECCE)
      {
        /* Start the SRAM ECC mechanism and latching the error address */
        hramcfg->Instance->CR |= (RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
  
        /* Update the RAMCFG state */
        hramcfg->State = HAL_RAMCFG_STATE_READY;
      }
    }
    else
    {
      /* Update the RAMCFG error code and return error  */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
  
    }
  
    return status;
  }
  
  /**
    * @brief  Stop ECC mechanism for the given SRAM.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG
    *                   instance.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_StopECC(RAMCFG_HandleTypeDef *hramcfg)
  {
    HAL_StatusTypeDef status = HAL_OK;
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Check if ECC mechanism is active */
      if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) == RAMCFG_CR_ECCE)
      {
        /* Unlock the SRAM ECC bit */
        WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY1);
        WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY2);
  
        /* Start the SRAM ECC mechanism and latching the error address */
        hramcfg->Instance->CR &= ~(RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
  
        /* Update the RAMCFG state */
        hramcfg->State = HAL_RAMCFG_STATE_READY;
      }
    }
    else
    {
      /* Update the RAMCFG error code and return error  */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
    }
  
    return status;
  }
  
  /**
    * @brief  Enable the RAMCFG error interrupts.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  Notifications : Select the notification to be enabled.
    *                         This parameter can be any value of @ref
    *                         RAMCFG_Interrupt group.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_EnableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications)
  {
    HAL_StatusTypeDef status = HAL_OK;
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
    assert_param(IS_RAMCFG_INTERRUPT(Notifications));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Enable RAMCFG interrupts */
      __HAL_RAMCFG_ENABLE_IT(hramcfg, Notifications);
  
      /* Update the RAMCFG state */
      hramcfg->State = HAL_RAMCFG_STATE_READY;
  
    }
    else
    {
      /* Update the RAMCFG error code and return error */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
    }
  
    return status;
  }
  
  /**
    * @brief  Disable the RAMCFG error interrupts.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  Notifications : Select the notification to be disabled.
    *                         This parameter can be :
    *                         RAMCFG_IT_SINGLEERR : Single Error Interrupt.
    *                         RAMCFG_IT_DOUBLEERR : Double Error Interrupt.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_DisableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications)
  {
    HAL_StatusTypeDef status = HAL_OK;
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
    assert_param(IS_RAMCFG_INTERRUPT(Notifications));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Disable RAMCFG interrupts */
      __HAL_RAMCFG_DISABLE_IT(hramcfg, Notifications);
  
      /* Update the RAMCFG state */
      hramcfg->State = HAL_RAMCFG_STATE_READY;
    }
    else
    {
      /* Update the RAMCFG error code and return error */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
    }
  
    return status;
  }
  
  /**
    * @brief  Check if an ECC single error has occurred.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval State of bit (1 or 0).
    */
  uint32_t HAL_RAMCFG_IsECCSingleErrorDetected(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    /* Return the state of SEDC flag */
    return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_SINGLEERR) == (RAMCFG_FLAG_SINGLEERR)) ? 1UL : 0UL);
  }
  
  /**
    * @brief  Check if an ECC double error was occurred.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval State of bit (1 or 0).
    */
  uint32_t HAL_RAMCFG_IsECCDoubleErrorDetected(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    /* Return the state of SEDC flag */
    return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_DOUBLEERR) == (RAMCFG_FLAG_DOUBLEERR)) ? 1UL : 0UL);
  }
  
  /**
    * @brief  Get the RAMCFG single error address.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval Single error address offset.
    */
  uint32_t HAL_RAMCFG_GetSingleErrorAddress(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    return hramcfg->Instance->SEAR;
  }
  
  /**
    * @brief  Get the RAMCFG double error address.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval Double error address offset.
    */
  uint32_t HAL_RAMCFG_GetDoubleErrorAddress(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
  
    return hramcfg->Instance->DEAR;
  }
  /**
    * @}
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group3
    *
  @verbatim
   ===============================================================================
                          ##### Wait State Functions  #####
   ===============================================================================
      [..]
      This section provides functions allowing to get and configure the wait state
      value .
      [..]
      The HAL_RAMCFG_ConfigWaitState() function allows configuring the wait state
      value.
      The HAL_RAMCFG_GetWaitState() function allows getting the current wait state
      value.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Configure the wait state value for the given SRAM.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  WaitState     : Select the value of wait state to be configured.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_ConfigWaitState(RAMCFG_HandleTypeDef *hramcfg, uint32_t WaitState)
  {
    HAL_StatusTypeDef status = HAL_OK;
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
    assert_param(IS_RAMCFG_WAITSTATE(WaitState));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Set the SRAM wait state */
      hramcfg->Instance->CR = WaitState;
  
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_READY;
    }
    else
    {
      /* Update the RAMCFG error code and return error */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
    }
  
    return status;
  }
  
  /**
    * @brief  Get the current wait state value for the given SRAM.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval Wait state value.
    */
  uint32_t HAL_RAMCFG_GetWaitState(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Return the configured wait state number */
    return (hramcfg->Instance->CR & RAMCFG_CR_WSC);
  }
  /**
    * @}
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group4
    *
  @verbatim
   ===============================================================================
                        ##### Write Protection Functions  #####
   ===============================================================================
      [..]
      This section provides functions to enable write protection feature for
      the page(s) of SRAM2.
      [..]
      The HAL_RAMCFG_EnableWriteProtection() function allows the user to enable the write
      protection for the page(s) of SRAM2.
      The HAL_RAMCFG_GetWaitState() function allows get the current wait state
      value. Disabling SRAM2 page(s) protection is performed only by a glabal
      peripheral reset or a by a system reset.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Enable write protection for the given page(s).
    *         Write protection feature can be disabled only by system reset.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  StartPage     : Select the start page number.
    * @param  NbPage        : Number of page to be protected.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_EnableWriteProtection(RAMCFG_HandleTypeDef *hramcfg, uint32_t StartPage, uint32_t NbPage)
  {
    HAL_StatusTypeDef status = HAL_OK;
    uint32_t page_mask_0 = 0U;
    uint32_t page_mask_1 = 0U;
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_WP_INSTANCE(hramcfg->Instance));
    assert_param(IS_RAMCFG_WRITEPROTECTION_PAGE(StartPage + NbPage));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Repeat for page number to be protected */
      for (uint32_t count = 0U; count < NbPage; count++)
      {
        if ((StartPage + count) < 32U)
        {
          page_mask_0 |= (1UL << (StartPage + count));
        }
        else
        {
          page_mask_1 |= (1UL << ((StartPage + count) - 32U));
        }
      }
  
      /* Apply mask to protect pages */
      SET_BIT(hramcfg->Instance->WPR1, page_mask_0);
      SET_BIT(hramcfg->Instance->WPR2, page_mask_1);
  
      /* Update the RAMCFG state */
      hramcfg->State = HAL_RAMCFG_STATE_READY;
    }
    else
    {
      /* Update the RAMCFG error code and return error  */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      status = HAL_ERROR;
    }
  
    return status;
  }
  /**
    * @}
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group5
    *
  @verbatim
   ===============================================================================
                        ##### Erase Operation Functions  #####
   ===============================================================================
      [..]
      This section provides functions allowing a hardware erase for the given SRAM.
      [..]
      The HAL_RAMCFG_Erase() function allows a hardware mass erase for the given
      SRAM. The erase value for all SRAMs is 0.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Launch a Mass Erase for the given SRAM.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
  
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_Erase(RAMCFG_HandleTypeDef *hramcfg)
  {
    uint32_t timeout = RAMCFG_TIMEOUT_VALUE;
    uint32_t tickstart = HAL_GetTick();
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      /* Update RAMCFG peripheral state */
      hramcfg->State = HAL_RAMCFG_STATE_BUSY;
  
      /* Unlock the RAMCFG erase bit */
      WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY1);
      WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY2);
  
      /* Start the SRAM erase operation */
      hramcfg->Instance->CR |= RAMCFG_CR_SRAMER;
  
      /*
         Wait for the SRAM hardware erase operation to complete by polling on
         SRAMBUSY flag to be reset.
      */
      while (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SRAMBUSY) != 0U)
      {
        if (timeout != HAL_MAX_DELAY)
        {
          if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
          {
            /* Update the RAMCFG error code */
            hramcfg->ErrorCode = HAL_RAMCFG_ERROR_TIMEOUT;
  
            /* Update the RAMCFG state and return error status */
            hramcfg->State = HAL_RAMCFG_STATE_ERROR;
            return HAL_ERROR;
          }
        }
      }
    }
    else
    {
      /* Update the error code and return error status */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
      return HAL_ERROR;
    }
  
    /* Update the RAMCFG state */
    hramcfg->State = HAL_RAMCFG_STATE_READY;
  
    return HAL_OK;
  }
  /**
    * @}
    */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group6
    *
  @verbatim
   ===============================================================================
                 ##### Handle Interrupt and Callbacks Functions  #####
   ===============================================================================
      [..]
      This section provides functions to handle RAMCFG interrupts and
      Register / UnRegister the different callbacks.
      [..]
      The HAL_RAMCFG_IRQHandler() function allows the user to handle the active RAMCFG
      interrupt request.
      The HAL_RAMCFG_RegisterCallback() function allows the user to register the selected
      RAMCFG callbacks.
      The HAL_RAMCFG_UnRegisterCallback() function allows the user to unregister the
      selected RAMCFG callbacks.
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Handles RAMCFG interrupt request.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval None.
    */
  void HAL_RAMCFG_IRQHandler(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Single Error Interrupt Management ****************************************/
    if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_SINGLEERR) != 0U)
    {
      if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR) != 0U)
      {
        /* Clear active flags */
        __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR);
  
  #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
        /* Check if a valid single error callback is registered */
        if (hramcfg->DetectSingleErrorCallback != NULL)
        {
          /* Single error detection callback */
          hramcfg->DetectSingleErrorCallback(hramcfg);
        }
  #else
        HAL_RAMCFG_DetectSingleErrorCallback(hramcfg);
  #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
      }
    }
  
    /* Double Error Interrupt Management ****************************************/
    if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_DOUBLEERR) != 0U)
    {
      if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR) != 0U)
      {
        /* Clear active flags */
        __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR);
  
  #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
        /* Check if a valid double error callback is registered */
        if (hramcfg->DetectDoubleErrorCallback != NULL)
        {
          /* Double error detection callback */
          hramcfg->DetectDoubleErrorCallback(hramcfg);
        }
  #else
        HAL_RAMCFG_DetectDoubleErrorCallback(hramcfg);
  #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
      }
    }
  }
  
  /**
    * @brief  RAMCFG single error detection callback.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG.
    * @retval None.
    */
  __weak void HAL_RAMCFG_DetectSingleErrorCallback(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Prevent unused argument(s) compilation warning */
    UNUSED(hramcfg);
  
    /* NOTE : This function should not be modified, when the callback is needed,
              the HAL_RAMCFG_DetectSingleErrorCallback can be implemented in
              the user file.                                                    */
  }
  
  /**
    * @brief  RAMCFG double error detection callback.
    * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
    *                   the configuration information for the specified RAMCFG.
    * @retval None.
    */
  __weak void HAL_RAMCFG_DetectDoubleErrorCallback(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Prevent unused argument(s) compilation warning */
    UNUSED(hramcfg);
  
    /* NOTE : This function should not be modified, when the callback is needed,
              the HAL_RAMCFG_DetectDoubleErrorCallback can be implemented in
              the user file.                                                    */
  }
  
  #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
  /**
    * @brief  Register RAMCFG callbacks.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  CallbackID    : User Callback identifier a HAL_MDMA_CallbackIDTypeDef
    *                         ENUM as parameter.
    * @param  pCallback     : Pointer to private callback function.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_RegisterCallback(RAMCFG_HandleTypeDef *hramcfg,
                                                HAL_RAMCFG_CallbackIDTypeDef CallbackID,
                                                void (* pCallback)(RAMCFG_HandleTypeDef *_hramcfg))
  {
    HAL_StatusTypeDef status = HAL_OK;
  
    if (pCallback == NULL)
    {
      /* Update the error code and return error */
      hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
      return HAL_ERROR;
    }
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      switch (CallbackID)
      {
        case  HAL_RAMCFG_SE_DETECT_CB_ID:
          /* Register single error callback */
          hramcfg->DetectSingleErrorCallback = pCallback;
          break;
  
        case  HAL_RAMCFG_DE_DETECT_CB_ID:
          /* Register single error callback */
          hramcfg->DetectDoubleErrorCallback = pCallback;
          break;
  
        case HAL_RAMCFG_MSPINIT_CB_ID :
          /* Register msp init callback */
          hramcfg->MspInitCallback = pCallback;
          break;
  
        case HAL_RAMCFG_MSPDEINIT_CB_ID :
          /* Register msp de-init callback */
          hramcfg->MspDeInitCallback = pCallback;
          break;
  
        default:
          /* Update the error code and return error */
          hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
          status = HAL_ERROR;
          break;
      }
    }
    else if (hramcfg->State == HAL_RAMCFG_STATE_RESET)
    {
      switch (CallbackID)
      {
        case HAL_RAMCFG_MSPINIT_CB_ID :
          /* Register msp init callback */
          hramcfg->MspInitCallback = pCallback;
          break;
  
        case HAL_RAMCFG_MSPDEINIT_CB_ID :
          /* Register msp de-init callback */
          hramcfg->MspDeInitCallback = pCallback;
          break;
  
        default :
          /* Update the error code and return error */
          hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
          status =  HAL_ERROR;
          break;
      }
    }
    else
    {
      /* Update the error code and return error  */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK;
      status = HAL_ERROR;
    }
  
    return status;
  }
  
  /**
    * @brief  UnRegister RAMCFG callbacks.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @param  CallbackID    : User Callback identifier a HAL_MDMA_CallbackIDTypeDef
    *                         ENUM as parameter.
    * @retval HAL status.
    */
  HAL_StatusTypeDef HAL_RAMCFG_UnRegisterCallback(RAMCFG_HandleTypeDef *hramcfg, HAL_RAMCFG_CallbackIDTypeDef CallbackID)
  {
    HAL_StatusTypeDef status = HAL_OK;
  
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Check RAMCFG state */
    if (hramcfg->State == HAL_RAMCFG_STATE_READY)
    {
      switch (CallbackID)
      {
        case  HAL_RAMCFG_SE_DETECT_CB_ID:
          /* UnRegister single error callback */
          hramcfg->DetectSingleErrorCallback = NULL;
          break;
  
        case  HAL_RAMCFG_DE_DETECT_CB_ID:
          /* UnRegister double error callback */
          hramcfg->DetectDoubleErrorCallback = NULL;
          break;
  
        case HAL_RAMCFG_MSPINIT_CB_ID :
          /* UnRegister msp init callback */
          hramcfg->MspInitCallback = NULL;
          break;
  
        case HAL_RAMCFG_MSPDEINIT_CB_ID :
          /* UnRegister msp de-init callback */
          hramcfg->MspDeInitCallback = NULL;
          break;
  
        case  HAL_RAMCFG_ALL_CB_ID:
          /* UnRegister all available callbacks */
          hramcfg->DetectSingleErrorCallback = NULL;
          hramcfg->DetectDoubleErrorCallback = NULL;
          hramcfg->MspDeInitCallback         = NULL;
          hramcfg->MspInitCallback           = NULL;
          break;
  
        default:
          /* Return error status */
          status = HAL_ERROR;
          break;
      }
    }
    else if (hramcfg->State == HAL_RAMCFG_STATE_RESET)
    {
      switch (CallbackID)
      {
        case HAL_RAMCFG_MSPINIT_CB_ID :
          /* UnRegister msp init callback */
          hramcfg->MspInitCallback = NULL;
          break;
  
        case HAL_RAMCFG_MSPDEINIT_CB_ID :
          /* UnRegister msp de-init callback */
          hramcfg->MspDeInitCallback = NULL;
          break;
  
        case  HAL_RAMCFG_ALL_CB_ID:
          /* UnRegister all available callbacks */
          hramcfg->MspDeInitCallback = NULL;
          hramcfg->MspInitCallback   = NULL;
          break;
  
        default :
          /* Update the error code */
          hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
  
          /* Update return status */
          status =  HAL_ERROR;
          break;
      }
    }
    else
    {
      /* Update the error code and return error */
      hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK;
      status = HAL_ERROR;
    }
  
    return status;
  }
  /**
    * @}
    */
  #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
  
  /** @addtogroup RAMCFG_Exported_Functions_Group7
    *
  @verbatim
   ===============================================================================
                      ##### State and Error Functions  #####
   ===============================================================================
      [..]
      This section provides functions to check and get the RAMCFG state
      and the error code .
      [..]
      The HAL_RAMCFG_GetState() function allows the user to get the RAMCFG peripheral
      state.
      The HAL_RAMCFG_GetError() function allows the user to get the RAMCFG peripheral error
      code.
  
  @endverbatim
    * @{
    */
  
  /**
    * @brief  Get the RAMCFG peripheral state.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval RAMCFG state.
    */
  HAL_RAMCFG_StateTypeDef HAL_RAMCFG_GetState(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Return the RAMCFG state */
    return hramcfg->State;
  }
  
  /**
    * @brief  Get the RAMCFG peripheral error code.
    * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
    *                         contains the configuration information for the
    *                         specified RAMCFG instance.
    * @retval RAMCFG error code.
    */
  uint32_t HAL_RAMCFG_GetError(RAMCFG_HandleTypeDef *hramcfg)
  {
    /* Check the parameters */
    assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
  
    /* Return the RAMCFG error code */
    return hramcfg->ErrorCode;
  }
  /**
    * @}
    */
  
  
  #endif /* HAL_RAMCFG_MODULE_ENABLED */
  /**
    * @}
    */
  
  /**
    * @}
    */
  
  /**
    * @}
    */
  