/**
  ******************************************************************************
  * @file    stm32h7xx_hal_ospi.c
  * @author  MCD Application Team
  * @brief   OSPI HAL module driver.
             This file provides firmware functions to manage the following
             functionalities of the OctoSPI interface (OSPI).
              + Initialization and de-initialization functions
              + Hyperbus configuration
              + Indirect functional mode management
              + Memory-mapped functional mode management
              + Auto-polling functional mode management
              + Interrupts and flags management
              + DMA channel configuration for indirect functional mode
              + Errors management and abort functionality
              + IO manager configuration

  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 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
 ===============================================================================
                        ##### How to use this driver #####
 ===============================================================================
  [..]
    *** Initialization ***
    ======================
    [..]
     As prerequisite, fill in the HAL_OSPI_MspInit() :
     (+) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE().
     (+) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET().
     (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
     (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
     (+) If interrupt or DMA mode is used, enable and configure OctoSPI global
         interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
     (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
         with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
         link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
         DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
    [..]
     Configure the fifo threshold, the dual-quad mode, the memory type, the
     device size, the CS high time, the free running clock, the clock mode,
     the wrap size, the clock prescaler, the sample shifting, the hold delay
     and the CS boundary using the HAL_OSPI_Init() function.
    [..]
     When using Hyperbus, configure the RW recovery time, the access time,
     the write latency and the latency mode using the HAL_OSPI_HyperbusCfg()
     function.

    *** Indirect functional mode ***
    ================================
    [..]
     In regular mode, configure the command sequence using the HAL_OSPI_Command()
     or HAL_OSPI_Command_IT() functions :
     (+) Instruction phase : the mode used and if present the size, the instruction
         opcode and the DTR mode.
     (+) Address phase : the mode used and if present the size, the address
         value and the DTR mode.
     (+) Alternate-bytes phase : the mode used and if present the size, the
         alternate bytes values and the DTR mode.
     (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
     (+) Data phase : the mode used and if present the number of bytes and the DTR mode.
     (+) Data strobe (DQS) mode : the activation (or not) of this mode
     (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
     (+) Flash identifier : in dual-quad mode, indicates which flash is concerned
     (+) Operation type : always common configuration
    [..]
     In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd()
     function :
     (+) Address space : indicate if the access will be done in register or memory
     (+) Address size
     (+) Number of data
     (+) Data strobe (DQS) mode : the activation (or not) of this mode
    [..]
     If no data is required for the command (only for regular mode, not for
     Hyperbus mode), it is sent directly to the memory :
     (+) In polling mode, the output of the function is done when the transfer is complete.
     (+) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete.
    [..]
     For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or
     HAL_OSPI_Transmit_IT() after the command configuration :
     (+) In polling mode, the output of the function is done when the transfer is complete.
     (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
         is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
     (+) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and
         HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
    [..]
     For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or
     HAL_OSPI_Receive_IT() after the command configuration :
     (+) In polling mode, the output of the function is done when the transfer is complete.
     (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
         is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
     (+) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and
         HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.

    *** Auto-polling functional mode ***
    ====================================
    [..]
     Configure the command sequence by the same way than the indirect mode
    [..]
     Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling()
     or HAL_OSPI_AutoPolling_IT() functions :
     (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
         the polling interval and the automatic stop activation.
    [..]
     After the configuration :
     (+) In polling mode, the output of the function is done when the status match is reached. The
         automatic stop is activated to avoid an infinite loop.
     (+) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached.

    *** MDMA functional mode ***
    ====================================
    [..]
     Configure the SourceInc and DestinationInc of MDMA parameters in the HAL_OSPI_MspInit() function :
     (+) MDMA settings for write operation :
         (++) The DestinationInc should be MDMA_DEST_INC_DISABLE
         (++) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
         (++) The SourceDataSize must be a value of @ref MDMA Source data size
              (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
              aligned with @ref MDMA_Source_increment_mode .
         (++) The DestDataSize must be a value of @ref MDMA Destination data size
              (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
     (+) MDMA settings for read operation :
         (++) The SourceInc should be MDMA_SRC_INC_DISABLE
         (++) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode
         (Except the MDMA_DEST_INC_DOUBLEWORD).
         (++) The SourceDataSize must be a value of @ref MDMA Source data size
              (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
         (++) The DestDataSize must be a value of @ref MDMA Destination data size
              (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
              aligned with @ref MDMA_Destination_increment_mode.
     (+) The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Octospi.
    [..]
     In case of wrong MDMA setting
     (+) For write operation :
         (++) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled
              by the HAL_OSPI_Transmit_DMA().
     (+) For read operation :
         (++) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled
              by the HAL_OSPI_Receive_DMA().

    *** Memory-mapped functional mode ***
    =====================================
    [..]
     Configure the command sequence by the same way than the indirect mode except
     for the operation type in regular mode :
     (+) Operation type equals to read configuration : the command configuration
         applies to read access in memory-mapped mode
     (+) Operation type equals to write configuration : the command configuration
         applies to write access in memory-mapped mode
     (+) Both read and write configuration should be performed before activating
         memory-mapped mode
    [..]
     Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
     functions :
     (+) The timeout activation and the timeout period.
    [..]
     After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
     the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires.

    *** Errors management and abort functionality ***
    =================================================
    [..]
     HAL_OSPI_GetError() function gives the error raised during the last operation.
    [..]
     HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and
     flushes the fifo :
     (+) In polling mode, the output of the function is done when the transfer
         complete bit is set and the busy bit cleared.
     (+) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when
         the transfer complete bit is set.

    *** Control functions ***
    =========================
    [..]
     HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver.
    [..]
     HAL_OSPI_SetTimeout() function configures the timeout value used in the driver.
    [..]
     HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral.
    [..]
     HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold

    *** IO manager configuration functions ***
    ==========================================
    [..]
     HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.

    *** Callback registration ***
    =============================================
    [..]
     The compilation define  USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1
     allows the user to configure dynamically the driver callbacks.

    [..]
     Use function HAL_OSPI_RegisterCallback() to register a user callback,
     it allows to register following callbacks:
     (+) ErrorCallback : callback when error occurs.
     (+) AbortCpltCallback : callback when abort is completed.
     (+) FifoThresholdCallback : callback when the fifo threshold is reached.
     (+) CmdCpltCallback : callback when a command without data is completed.
     (+) RxCpltCallback : callback when a reception transfer is completed.
     (+) TxCpltCallback : callback when a transmission transfer is completed.
     (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
     (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
     (+) StatusMatchCallback : callback when a status match occurs.
     (+) TimeOutCallback : callback when the timeout perioed expires.
     (+) MspInitCallback    : OSPI MspInit.
     (+) MspDeInitCallback  : OSPI MspDeInit.
    [..]
     This function takes as parameters the HAL peripheral handle, the Callback ID
     and a pointer to the user callback function.

    [..]
     Use function HAL_OSPI_UnRegisterCallback() to reset a callback to the default
     weak (overridden) function. It allows to reset following callbacks:
     (+) ErrorCallback : callback when error occurs.
     (+) AbortCpltCallback : callback when abort is completed.
     (+) FifoThresholdCallback : callback when the fifo threshold is reached.
     (+) CmdCpltCallback : callback when a command without data is completed.
     (+) RxCpltCallback : callback when a reception transfer is completed.
     (+) TxCpltCallback : callback when a transmission transfer is completed.
     (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
     (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
     (+) StatusMatchCallback : callback when a status match occurs.
     (+) TimeOutCallback : callback when the timeout perioed expires.
     (+) MspInitCallback    : OSPI MspInit.
     (+) MspDeInitCallback  : OSPI MspDeInit.
    [..]
     This function) takes as parameters the HAL peripheral handle and the Callback ID.

    [..]
     By default, after the HAL_OSPI_Init() and if the state is HAL_OSPI_STATE_RESET
     all callbacks are reset to the corresponding legacy weak (overridden) functions.
     Exception done for MspInit and MspDeInit callbacks that are respectively
     reset to the legacy weak (overridden) functions in the HAL_OSPI_Init()
     and HAL_OSPI_DeInit() only when these callbacks are null (not registered beforehand).
     If not, MspInit or MspDeInit are not null, the HAL_OSPI_Init() and HAL_OSPI_DeInit()
     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)

    [..]
     Callbacks can be registered/unregistered in READY state only.
     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
     during the Init/DeInit.
     In that case first register the MspInit/MspDeInit user callbacks
     using HAL_OSPI_RegisterCallback() before calling HAL_OSPI_DeInit()
     or HAL_OSPI_Init() function.

    [..]
     When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or
     not defined, the callback registering feature is not available
     and weak (overridden) callbacks are used.

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

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

#if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)

/** @addtogroup STM32H7xx_HAL_Driver
  * @{
  */

/** @defgroup OSPI OSPI
  * @brief OSPI HAL module driver
  * @{
  */

#ifdef HAL_OSPI_MODULE_ENABLED

/**
  @cond 0
  */
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000)         /*!< Indirect write mode    */
#define OSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode     */
#define OSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */
#define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)OCTOSPI_CR_FMODE)   /*!< Memory-mapped mode     */

#define OSPI_CFG_STATE_MASK  0x00000004U
#define OSPI_BUSY_STATE_MASK 0x00000008U

#define OSPI_NB_INSTANCE   2U
#define OSPI_IOM_NB_PORTS  2U
#define OSPI_IOM_PORT_MASK 0x1U

/* Private macro -------------------------------------------------------------*/
#define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
                                       ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
                                       ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
                                       ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
static void              OSPI_DMACplt(MDMA_HandleTypeDef *hmdma);
static void              OSPI_DMAError(MDMA_HandleTypeDef *hmdma);
static void              OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma);
static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State,
                                                        uint32_t Tickstart, uint32_t Timeout);
static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
static void OSPI_DMAAbortOnError(MDMA_HandleTypeDef *hmdma);
/**
  @endcond
  */

/* Exported functions --------------------------------------------------------*/

/** @defgroup OSPI_Exported_Functions OSPI Exported Functions
  * @{
  */

/** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
  * @brief    Initialization and Configuration functions
  *
@verbatim
===============================================================================
            ##### Initialization and Configuration functions #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to :
      (+) Initialize the OctoSPI.
      (+) De-initialize the OctoSPI.

@endverbatim
  * @{
  */

/**
  * @brief  Initialize the OSPI mode according to the specified parameters
  *         in the OSPI_InitTypeDef and initialize the associated handle.
  * @param  hospi : OSPI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Init(OSPI_HandleTypeDef *hospi)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t tickstart = HAL_GetTick();

  /* Check the OSPI handle allocation */
  if (hospi == NULL)
  {
    status = HAL_ERROR;
    /* No error code can be set set as the handler is null */
  }
  else
  {
    /* Check the parameters of the initialization structure */
    assert_param(IS_OSPI_FIFO_THRESHOLD(hospi->Init.FifoThreshold));
    assert_param(IS_OSPI_DUALQUAD_MODE(hospi->Init.DualQuad));
    assert_param(IS_OSPI_MEMORY_TYPE(hospi->Init.MemoryType));
    assert_param(IS_OSPI_DEVICE_SIZE(hospi->Init.DeviceSize));
    assert_param(IS_OSPI_CS_HIGH_TIME(hospi->Init.ChipSelectHighTime));
    assert_param(IS_OSPI_FREE_RUN_CLK(hospi->Init.FreeRunningClock));
    assert_param(IS_OSPI_CLOCK_MODE(hospi->Init.ClockMode));
    assert_param(IS_OSPI_WRAP_SIZE(hospi->Init.WrapSize));
    assert_param(IS_OSPI_CLK_PRESCALER(hospi->Init.ClockPrescaler));
    assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
    assert_param(IS_OSPI_DHQC(hospi->Init.DelayHoldQuarterCycle));
    assert_param(IS_OSPI_CS_BOUNDARY(hospi->Init.ChipSelectBoundary));
    assert_param(IS_OSPI_DLYBYP(hospi->Init.DelayBlockBypass));
    assert_param(IS_OSPI_MAXTRAN(hospi->Init.MaxTran));

    /* Initialize error code */
    hospi->ErrorCode = HAL_OSPI_ERROR_NONE;

    /* Check if the state is the reset state */
    if (hospi->State == HAL_OSPI_STATE_RESET)
    {
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
      /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
      hospi->ErrorCallback         = HAL_OSPI_ErrorCallback;
      hospi->AbortCpltCallback     = HAL_OSPI_AbortCpltCallback;
      hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
      hospi->CmdCpltCallback       = HAL_OSPI_CmdCpltCallback;
      hospi->RxCpltCallback        = HAL_OSPI_RxCpltCallback;
      hospi->TxCpltCallback        = HAL_OSPI_TxCpltCallback;
      hospi->RxHalfCpltCallback    = HAL_OSPI_RxHalfCpltCallback;
      hospi->TxHalfCpltCallback    = HAL_OSPI_TxHalfCpltCallback;
      hospi->StatusMatchCallback   = HAL_OSPI_StatusMatchCallback;
      hospi->TimeOutCallback       = HAL_OSPI_TimeOutCallback;

      if (hospi->MspInitCallback == NULL)
      {
        hospi->MspInitCallback = HAL_OSPI_MspInit;
      }

      /* Init the low level hardware */
      hospi->MspInitCallback(hospi);
#else
      /* Initialization of the low level hardware */
      HAL_OSPI_MspInit(hospi);
#endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */

      /* Configure the default timeout for the OSPI memory access */
      (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

      /* Configure memory type, device size, chip select high time, delay block bypass,
         free running clock, clock mode */
      MODIFY_REG(hospi->Instance->DCR1,
                 (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_DLYBYP |
                  OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
                 (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
                  ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
                  hospi->Init.DelayBlockBypass | hospi->Init.ClockMode));

      /* Configure wrap size */
      MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);

      /* Configure chip select boundary and maximum transfer */
      hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) |
                               (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));

      /* Configure refresh */
      hospi->Instance->DCR4 = hospi->Init.Refresh;

      /* Configure FIFO threshold */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));

      /* Wait till busy flag is reset */
      status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);

      if (status == HAL_OK)
      {
        /* Configure clock prescaler */
        MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER,
                   ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));

        /* Configure Dual Quad mode */
        MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);

        /* Configure sample shifting and delay hold quarter cycle */
        MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC),
                   (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));

        /* Enable OctoSPI */
        __HAL_OSPI_ENABLE(hospi);

        /* Enable free running clock if needed : must be done after OSPI enable */
        if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
        {
          SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
        }

        /* Initialize the OSPI state */
        if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
        {
          hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
        }
        else
        {
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Initialize the OSPI MSP.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_MspInit can be implemented in the user file
   */
}

/**
  * @brief  De-Initialize the OSPI peripheral.
  * @param  hospi : OSPI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the OSPI handle allocation */
  if (hospi == NULL)
  {
    status = HAL_ERROR;
    /* No error code can be set set as the handler is null */
  }
  else
  {
    /* Disable OctoSPI */
    __HAL_OSPI_DISABLE(hospi);

    /* Disable free running clock if needed : must be done after OSPI disable */
    CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);

#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    if (hospi->MspDeInitCallback == NULL)
    {
      hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
    }

    /* DeInit the low level hardware */
    hospi->MspDeInitCallback(hospi);
#else
    /* De-initialize the low-level hardware */
    HAL_OSPI_MspDeInit(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */

    /* Reset the driver state */
    hospi->State = HAL_OSPI_STATE_RESET;
  }

  return status;
}

/**
  * @brief  DeInitialize the OSPI MSP.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_MspDeInit can be implemented in the user file
   */
}

/**
  * @}
  */

/** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
  *  @brief OSPI Transmit/Receive functions
  *
@verbatim
 ===============================================================================
                      ##### IO operation functions #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to :
      (+) Handle the interrupts.
      (+) Handle the command sequence (regular and Hyperbus).
      (+) Handle the Hyperbus configuration.
      (+) Transmit data in blocking, interrupt or DMA mode.
      (+) Receive data in blocking, interrupt or DMA mode.
      (+) Manage the auto-polling functional mode.
      (+) Manage the memory-mapped functional mode.

@endverbatim
  * @{
  */

/**
  * @brief  Handle OSPI interrupt request.
  * @param  hospi : OSPI handle
  * @retval None
  */
void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
{
  __IO uint32_t *data_reg = &hospi->Instance->DR;
  uint32_t flag           = hospi->Instance->SR;
  uint32_t itsource       = hospi->Instance->CR;
  uint32_t currentstate   = hospi->State;

  /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
  if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
  {
    if (currentstate == HAL_OSPI_STATE_BUSY_TX)
    {
      /* Write a data in the fifo */
      *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
      hospi->pBuffPtr++;
      hospi->XferCount--;
    }
    else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
    {
      /* Read a data from the fifo */
      *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
      hospi->pBuffPtr++;
      hospi->XferCount--;
    }
    else
    {
      /* Nothing to do */
    }

    if (hospi->XferCount == 0U)
    {
      /* All data have been received or transmitted for the transfer */
      /* Disable fifo threshold interrupt */
      __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
    }

    /* Fifo threshold callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->FifoThresholdCallback(hospi);
#else
    HAL_OSPI_FifoThresholdCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  }
  /* OctoSPI transfer complete interrupt occurred ----------------------------*/
  else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
  {
    if (currentstate == HAL_OSPI_STATE_BUSY_RX)
    {
      if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
      {
        /* Read the last data received in the fifo */
        *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
        hospi->pBuffPtr++;
        hospi->XferCount--;
      }
      else if (hospi->XferCount == 0U)
      {
        /* Clear flag */
        hospi->Instance->FCR = HAL_OSPI_FLAG_TC;

        /* Disable the interrupts */
        __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);

        /* Update state */
        hospi->State = HAL_OSPI_STATE_READY;

        /* RX complete callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->RxCpltCallback(hospi);
#else
        HAL_OSPI_RxCpltCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
      }
      else
      {
        /* Nothing to do */
      }
    }
    else
    {
      /* Clear flag */
      hospi->Instance->FCR = HAL_OSPI_FLAG_TC;

      /* Disable the interrupts */
      __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);

      /* Update state */
      hospi->State = HAL_OSPI_STATE_READY;

      if (currentstate == HAL_OSPI_STATE_BUSY_TX)
      {
        /* TX complete callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->TxCpltCallback(hospi);
#else
        HAL_OSPI_TxCpltCallback(hospi);
#endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
      }
      else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
      {
        /* Command complete callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->CmdCpltCallback(hospi);
#else
        HAL_OSPI_CmdCpltCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
      }
      else if (currentstate == HAL_OSPI_STATE_ABORT)
      {
        if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
        {
          /* Abort called by the user */
          /* Abort complete callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
          hospi->AbortCpltCallback(hospi);
#else
          HAL_OSPI_AbortCpltCallback(hospi);
#endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
        }
        else
        {
          /* Abort due to an error (eg : DMA error) */
          /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
          hospi->ErrorCallback(hospi);
#else
          HAL_OSPI_ErrorCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
        }
      }
      else
      {
        /* Nothing to do */
      }
    }
  }
  /* OctoSPI status match interrupt occurred ---------------------------------*/
  else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
  {
    /* Clear flag */
    hospi->Instance->FCR = HAL_OSPI_FLAG_SM;

    /* Check if automatic poll mode stop is activated */
    if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
    {
      /* Disable the interrupts */
      __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);

      /* Update state */
      hospi->State = HAL_OSPI_STATE_READY;
    }

    /* Status match callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->StatusMatchCallback(hospi);
#else
    HAL_OSPI_StatusMatchCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  }
  /* OctoSPI transfer error interrupt occurred -------------------------------*/
  else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
  {
    /* Clear flag */
    hospi->Instance->FCR = HAL_OSPI_FLAG_TE;

    /* Disable all interrupts */
    __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));

    /* Set error code */
    hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;

    /* Check if the DMA is enabled */
    if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
    {
      /* Disable the DMA transfer on the OctoSPI side */
      CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);

      /* Disable the DMA transfer on the DMA side */
      hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
      if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
      {
        /* Update state */
        hospi->State = HAL_OSPI_STATE_READY;

        /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->ErrorCallback(hospi);
#else
        HAL_OSPI_ErrorCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
      }
    }
    else
    {
      /* Update state */
      hospi->State = HAL_OSPI_STATE_READY;

      /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
      hospi->ErrorCallback(hospi);
#else
      HAL_OSPI_ErrorCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
    }
  }
  /* OctoSPI timeout interrupt occurred --------------------------------------*/
  else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
  {
    /* Clear flag */
    hospi->Instance->FCR = HAL_OSPI_FLAG_TO;

    /* Timeout callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->TimeOutCallback(hospi);
#else
    HAL_OSPI_TimeOutCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  }
  else
  {
    /* Nothing to do */
  }
}

/**
  * @brief  Set the command configuration.
  * @param  hospi   : OSPI handle
  * @param  cmd     : structure that contains the command configuration information
  * @param  Timeout : Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t state;
  uint32_t tickstart = HAL_GetTick();

  /* Check the parameters of the command structure */
  assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));

  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  {
    assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
  }

  assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  {
    assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
    assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
  }

  assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  {
    assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
    assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
  }

  assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  {
    assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
    assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
  }

  assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  {
    if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
    {
      assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
    }
    assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
    assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
  }

  assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
  assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));

  /* Check the state of the driver */
  state = hospi->State;
  if (((state == HAL_OSPI_STATE_READY)         && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
      ((state == HAL_OSPI_STATE_READ_CMD_CFG)  && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
                                                   || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) ||
      ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)  ||
                                                   (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))))
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);

    if (status == HAL_OK)
    {
      /* Initialize error code */
      hospi->ErrorCode = HAL_OSPI_ERROR_NONE;

      /* Configure the registers */
      status = OSPI_ConfigCmd(hospi, cmd);

      if (status == HAL_OK)
      {
        if (cmd->DataMode == HAL_OSPI_DATA_NONE)
        {
          /* When there is no data phase, the transfer start as soon as the configuration is done
             so wait until TC flag is set to go back in idle state */
          status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);

          __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
        }
        else
        {
          /* Update the state */
          if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
          {
            hospi->State = HAL_OSPI_STATE_CMD_CFG;
          }
          else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
          {
            if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
            {
              hospi->State = HAL_OSPI_STATE_CMD_CFG;
            }
            else
            {
              hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
            }
          }
          else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
          {
            if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
            {
              hospi->State = HAL_OSPI_STATE_CMD_CFG;
            }
            else
            {
              hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
            }
          }
          else
          {
            /* Wrap configuration, no state change */
          }
        }
      }
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Set the command configuration in interrupt mode.
  * @param  hospi : OSPI handle
  * @param  cmd   : structure that contains the command configuration information
  * @note   This function is used only in Indirect Read or Write Modes
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();

  /* Check the parameters of the command structure */
  assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));

  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  {
    assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
  }

  assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  {
    assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
    assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
  }

  assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  {
    assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
    assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
  }

  assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  {
    assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
    assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
  }

  assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  {
    assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
    assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
    assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
  }

  assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
  assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));

  /* Check the state of the driver */
  if ((hospi->State  == HAL_OSPI_STATE_READY) && (cmd->OperationType     == HAL_OSPI_OPTYPE_COMMON_CFG) &&
      (cmd->DataMode == HAL_OSPI_DATA_NONE)   && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);

    if (status == HAL_OK)
    {
      /* Initialize error code */
      hospi->ErrorCode = HAL_OSPI_ERROR_NONE;

      /* Clear flags related to interrupt */
      __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);

      /* Configure the registers */
      status = OSPI_ConfigCmd(hospi, cmd);

      if (status == HAL_OK)
      {
        /* Update the state */
        hospi->State = HAL_OSPI_STATE_BUSY_CMD;

        /* Enable the transfer complete and transfer error interrupts */
        __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
      }
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Configure the Hyperbus parameters.
  * @param  hospi   : OSPI handle
  * @param  cfg     : Structure containing the Hyperbus configuration
  * @param  Timeout : Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t state;
  uint32_t tickstart = HAL_GetTick();

  /* Check the parameters of the hyperbus configuration structure */
  assert_param(IS_OSPI_RW_RECOVERY_TIME(cfg->RWRecoveryTime));
  assert_param(IS_OSPI_ACCESS_TIME(cfg->AccessTime));
  assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
  assert_param(IS_OSPI_LATENCY_MODE(cfg->LatencyMode));

  /* Check the state of the driver */
  state = hospi->State;
  if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);

    if (status == HAL_OK)
    {
      /* Configure Hyperbus configuration Latency register */
      WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
                                        (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos)     |
                                        cfg->WriteZeroLatency | cfg->LatencyMode));

      /* Update the state */
      hospi->State = HAL_OSPI_STATE_READY;
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Set the Hyperbus command configuration.
  * @param  hospi   : OSPI handle
  * @param  cmd     : Structure containing the Hyperbus command
  * @param  Timeout : Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();

  /* Check the parameters of the hyperbus command structure */
  assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
  assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
  assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
  assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));

  /* Check the state of the driver */
  if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);

    if (status == HAL_OK)
    {
      /* Re-initialize the value of the functional mode */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);

      /* Configure the address space in the DCR1 register */
      MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);

      /* Configure the CCR and WCCR registers with the address size and the following configuration :
         - DQS signal enabled (used as RWDS)
         - DTR mode enabled on address and data
         - address and data on 8 lines */
      WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
                                       cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
      WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
                                        cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));

      /* Configure the DLR register with the number of data */
      WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));

      /* Configure the AR register with the address value */
      WRITE_REG(hospi->Instance->AR, cmd->Address);

      /* Update the state */
      hospi->State = HAL_OSPI_STATE_CMD_CFG;
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Transmit an amount of data in blocking mode.
  * @param  hospi   : OSPI handle
  * @param  pData   : pointer to data buffer
  * @param  Timeout : Timeout duration
  * @note   This function is used only in Indirect Write Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();
  __IO uint32_t *data_reg = &hospi->Instance->DR;

  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      /* Configure counters and size */
      hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
      hospi->XferSize  = hospi->XferCount;
      hospi->pBuffPtr  = pData;

      /* Configure CR register with functional mode as indirect write */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);

      do
      {
        /* Wait till fifo threshold flag is set to send data */
        status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);

        if (status != HAL_OK)
        {
          break;
        }

        *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
        hospi->pBuffPtr++;
        hospi->XferCount--;
      } while (hospi->XferCount > 0U);

      if (status == HAL_OK)
      {
        /* Wait till transfer complete flag is set to go back in idle state */
        status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);

        if (status == HAL_OK)
        {
          /* Clear transfer complete flag */
          __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

          /* Update state */
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Receive an amount of data in blocking mode.
  * @param  hospi   : OSPI handle
  * @param  pData   : pointer to data buffer
  * @param  Timeout : Timeout duration
  * @note   This function is used only in Indirect Read Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();
  __IO uint32_t *data_reg = &hospi->Instance->DR;
  uint32_t addr_reg = hospi->Instance->AR;
  uint32_t ir_reg = hospi->Instance->IR;

  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      /* Configure counters and size */
      hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
      hospi->XferSize  = hospi->XferCount;
      hospi->pBuffPtr  = pData;

      /* Configure CR register with functional mode as indirect read */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);

      /* Trig the transfer by re-writing address or instruction register */
      if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
      {
        WRITE_REG(hospi->Instance->AR, addr_reg);
      }
      else
      {
        if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
        {
          WRITE_REG(hospi->Instance->AR, addr_reg);
        }
        else
        {
          WRITE_REG(hospi->Instance->IR, ir_reg);
        }
      }

      do
      {
        /* Wait till fifo threshold or transfer complete flags are set to read received data */
        status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);

        if (status != HAL_OK)
        {
          break;
        }

        *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
        hospi->pBuffPtr++;
        hospi->XferCount--;
      } while (hospi->XferCount > 0U);

      if (status == HAL_OK)
      {
        /* Wait till transfer complete flag is set to go back in idle state */
        status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);

        if (status == HAL_OK)
        {
          /* Clear transfer complete flag */
          __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

          /* Update state */
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Send an amount of data in non-blocking mode with interrupt.
  * @param  hospi : OSPI handle
  * @param  pData : pointer to data buffer
  * @note   This function is used only in Indirect Write Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      /* Configure counters and size */
      hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
      hospi->XferSize  = hospi->XferCount;
      hospi->pBuffPtr  = pData;

      /* Configure CR register with functional mode as indirect write */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);

      /* Clear flags related to interrupt */
      __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);

      /* Update the state */
      hospi->State = HAL_OSPI_STATE_BUSY_TX;

      /* Enable the transfer complete, fifo threshold and transfer error interrupts */
      __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Receive an amount of data in non-blocking mode with interrupt.
  * @param  hospi : OSPI handle
  * @param  pData : pointer to data buffer
  * @note   This function is used only in Indirect Read Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t addr_reg = hospi->Instance->AR;
  uint32_t ir_reg = hospi->Instance->IR;

  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      /* Configure counters and size */
      hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
      hospi->XferSize  = hospi->XferCount;
      hospi->pBuffPtr  = pData;

      /* Configure CR register with functional mode as indirect read */
      MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);

      /* Clear flags related to interrupt */
      __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);

      /* Update the state */
      hospi->State = HAL_OSPI_STATE_BUSY_RX;

      /* Enable the transfer complete, fifo threshold and transfer error interrupts */
      __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);

      /* Trig the transfer by re-writing address or instruction register */
      if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
      {
        WRITE_REG(hospi->Instance->AR, addr_reg);
      }
      else
      {
        if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
        {
          WRITE_REG(hospi->Instance->AR, addr_reg);
        }
        else
        {
          WRITE_REG(hospi->Instance->IR, ir_reg);
        }
      }
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Send an amount of data in non-blocking mode with DMA.
  * @param  hospi : OSPI handle
  * @param  pData : pointer to data buffer
  * @note   This function is used only in Indirect Write Mode
  * @note   If DMA peripheral access is configured as halfword, the number
  *         of data and the fifo threshold should be aligned on halfword
  * @note   If DMA peripheral access is configured as word, the number
  *         of data and the fifo threshold should be aligned on word
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t data_size = hospi->Instance->DLR + 1U;

  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      hospi->XferCount = data_size;

      {
        hospi->XferSize = hospi->XferCount;
        hospi->pBuffPtr = pData;

        /* Configure CR register with functional mode as indirect write */
        MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);

        /* Clear flags related to interrupt */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);

        /* Update the state */
        hospi->State = HAL_OSPI_STATE_BUSY_TX;

        /* Set the MDMA transfer complete callback */
        hospi->hmdma->XferCpltCallback = OSPI_DMACplt;

        /* Set the MDMA error callback */
        hospi->hmdma->XferErrorCallback = OSPI_DMAError;

        /* Clear the MDMA abort callback */
        hospi->hmdma->XferAbortCallback = NULL;

        /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment
           to disable */
        MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_DISABLE);

        /* Update MDMA configuration with the correct SourceInc field for Write operation */
        if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_BYTE);
        }
        else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_HALFWORD);
        }
        else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_WORD);
        }
        else
        {
          /* in case of incorrect source data size */
          hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
          status = HAL_ERROR;
        }

        /* Enable the transmit MDMA Channel */
        if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize, 1) == \
            HAL_OK)
        {
          /* Enable the transfer error interrupt */
          __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);

          /* Enable the DMA transfer by setting the DMAEN bit  */
          SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
        }
        else
        {
          status = HAL_ERROR;
          hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Receive an amount of data in non-blocking mode with DMA.
  * @param  hospi : OSPI handle
  * @param  pData : pointer to data buffer.
  * @note   This function is used only in Indirect Read Mode
  * @note   If DMA peripheral access is configured as halfword, the number
  *         of data and the fifo threshold should be aligned on halfword
  * @note   If DMA peripheral access is configured as word, the number
  *         of data and the fifo threshold should be aligned on word
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t data_size = hospi->Instance->DLR + 1U;
  uint32_t addr_reg = hospi->Instance->AR;
  uint32_t ir_reg = hospi->Instance->IR;
  /* Check the data pointer allocation */
  if (pData == NULL)
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  }
  else
  {
    /* Check the state */
    if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
    {
      hospi->XferCount = data_size;

      {
        hospi->XferSize  = hospi->XferCount;
        hospi->pBuffPtr  = pData;

        /* Configure CR register with functional mode as indirect read */
        MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);

        /* Clear flags related to interrupt */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);

        /* Update the state */
        hospi->State = HAL_OSPI_STATE_BUSY_RX;

        /* Set the DMA transfer complete callback */
        hospi->hmdma->XferCpltCallback = OSPI_DMACplt;

        /* Set the DMA error callback */
        hospi->hmdma->XferErrorCallback = OSPI_DMAError;

        /* Clear the DMA abort callback */
        hospi->hmdma->XferAbortCallback = NULL;

        /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
        MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_DISABLE);

        /* Update MDMA configuration with the correct DestinationInc field for read operation */
        if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_BYTE);
        }
        else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_HALFWORD);
        }
        else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
        {
          MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_WORD);
        }
        else
        {
          /* in case of incorrect destination data size */
          hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
          status = HAL_ERROR;
        }

        /* Enable the transmit MDMA Channel */
        if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize, 1) == \
            HAL_OK)
        {
          /* Enable the transfer error interrupt */
          __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);

          /* Trig the transfer by re-writing address or instruction register */
          if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
          {
            WRITE_REG(hospi->Instance->AR, addr_reg);
          }
          else
          {
            if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
            {
              WRITE_REG(hospi->Instance->AR, addr_reg);
            }
            else
            {
              WRITE_REG(hospi->Instance->IR, ir_reg);
            }
          }

          /* Enable the DMA transfer by setting the DMAEN bit  */
          SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
        }
        else
        {
          status = HAL_ERROR;
          hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Configure the OSPI Automatic Polling Mode in blocking mode.
  * @param  hospi   : OSPI handle
  * @param  cfg     : structure that contains the polling configuration information.
  * @param  Timeout : Timeout duration
  * @note   This function is used only in Automatic Polling Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();
  uint32_t addr_reg = hospi->Instance->AR;
  uint32_t ir_reg = hospi->Instance->IR;
#ifdef USE_FULL_ASSERT
  uint32_t dlr_reg = hospi->Instance->DLR;
#endif /* USE_FULL_ASSERT */

  /* Check the parameters of the autopolling configuration structure */
  assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
  assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
  assert_param(IS_OSPI_INTERVAL(cfg->Interval));
  assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));

  /* Check the state */
  if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);

    if (status == HAL_OK)
    {
      /* Configure registers */
      WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
      WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
      WRITE_REG(hospi->Instance->PIR,   cfg->Interval);
      MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
                 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));

      /* Trig the transfer by re-writing address or instruction register */
      if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
      {
        WRITE_REG(hospi->Instance->AR, addr_reg);
      }
      else
      {
        if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
        {
          WRITE_REG(hospi->Instance->AR, addr_reg);
        }
        else
        {
          WRITE_REG(hospi->Instance->IR, ir_reg);
        }
      }

      /* Wait till status match flag is set to go back in idle state */
      status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);

      if (status == HAL_OK)
      {
        /* Clear status match flag */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);

        /* Update state */
        hospi->State = HAL_OSPI_STATE_READY;
      }
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Configure the OSPI Automatic Polling Mode in non-blocking mode.
  * @param  hospi : OSPI handle
  * @param  cfg   : structure that contains the polling configuration information.
  * @note   This function is used only in Automatic Polling Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();
  uint32_t addr_reg = hospi->Instance->AR;
  uint32_t ir_reg = hospi->Instance->IR;
#ifdef USE_FULL_ASSERT
  uint32_t dlr_reg = hospi->Instance->DLR;
#endif /* USE_FULL_ASSERT */

  /* Check the parameters of the autopolling configuration structure */
  assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
  assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
  assert_param(IS_OSPI_INTERVAL(cfg->Interval));
  assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));

  /* Check the state */
  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);

    if (status == HAL_OK)
    {
      /* Configure registers */
      WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
      WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
      WRITE_REG(hospi->Instance->PIR,   cfg->Interval);
      MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
                 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));

      /* Clear flags related to interrupt */
      __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);

      /* Update state */
      hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;

      /* Enable the status match and transfer error interrupts */
      __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);

      /* Trig the transfer by re-writing address or instruction register */
      if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
      {
        WRITE_REG(hospi->Instance->AR, addr_reg);
      }
      else
      {
        if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
        {
          WRITE_REG(hospi->Instance->AR, addr_reg);
        }
        else
        {
          WRITE_REG(hospi->Instance->IR, ir_reg);
        }
      }
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Configure the Memory Mapped mode.
  * @param  hospi : OSPI handle
  * @param  cfg   : structure that contains the memory mapped configuration information.
  * @note   This function is used only in Memory mapped Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
{
  HAL_StatusTypeDef status;
  uint32_t tickstart = HAL_GetTick();

  /* Check the parameters of the memory-mapped configuration structure */
  assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));

  /* Check the state */
  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  {
    /* Wait till busy flag is reset */
    status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);

    if (status == HAL_OK)
    {
      /* Update state */
      hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;

      if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
      {
        assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));

        /* Configure register */
        WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);

        /* Clear flags related to interrupt */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);

        /* Enable the timeout interrupt */
        __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
      }

      /* Configure CR register with functional mode as memory-mapped */
      MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
                 (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Transfer Error callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_ErrorCallback could be implemented in the user file
   */
}

/**
  * @brief  Abort completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_AbortCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  FIFO Threshold callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
   */
}

/**
  * @brief  Command completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_CmdCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Rx Transfer completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_RxCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Tx Transfer completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_TxCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Rx Half Transfer completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Tx Half Transfer completed callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Status Match callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_StatusMatchCallback could be implemented in the user file
   */
}

/**
  * @brief  Timeout callback.
  * @param  hospi : OSPI handle
  * @retval None
  */
__weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hospi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_OSPI_TimeOutCallback could be implemented in the user file
   */
}

#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
/**
  * @brief  Register a User OSPI Callback
  *         To be used to override the weak predefined callback
  * @param hospi : OSPI handle
  * @param CallbackID : ID of the callback to be registered
  *        This parameter can be one of the following values:
  *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
  *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
  *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
  *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
  *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
  *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
  *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
  *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
  *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
  *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
  *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
  *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
  * @param pCallback : pointer to the Callback function
  * @retval status
  */
HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID,
                                            pOSPI_CallbackTypeDef pCallback)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (pCallback == NULL)
  {
    /* Update the error code */
    hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
    return HAL_ERROR;
  }

  if (hospi->State == HAL_OSPI_STATE_READY)
  {
    switch (CallbackID)
    {
      case  HAL_OSPI_ERROR_CB_ID :
        hospi->ErrorCallback = pCallback;
        break;
      case HAL_OSPI_ABORT_CB_ID :
        hospi->AbortCpltCallback = pCallback;
        break;
      case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
        hospi->FifoThresholdCallback = pCallback;
        break;
      case HAL_OSPI_CMD_CPLT_CB_ID :
        hospi->CmdCpltCallback = pCallback;
        break;
      case HAL_OSPI_RX_CPLT_CB_ID :
        hospi->RxCpltCallback = pCallback;
        break;
      case HAL_OSPI_TX_CPLT_CB_ID :
        hospi->TxCpltCallback = pCallback;
        break;
      case HAL_OSPI_RX_HALF_CPLT_CB_ID :
        hospi->RxHalfCpltCallback = pCallback;
        break;
      case HAL_OSPI_TX_HALF_CPLT_CB_ID :
        hospi->TxHalfCpltCallback = pCallback;
        break;
      case HAL_OSPI_STATUS_MATCH_CB_ID :
        hospi->StatusMatchCallback = pCallback;
        break;
      case HAL_OSPI_TIMEOUT_CB_ID :
        hospi->TimeOutCallback = pCallback;
        break;
      case HAL_OSPI_MSP_INIT_CB_ID :
        hospi->MspInitCallback = pCallback;
        break;
      case HAL_OSPI_MSP_DEINIT_CB_ID :
        hospi->MspDeInitCallback = pCallback;
        break;
      default :
        /* Update the error code */
        hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (hospi->State == HAL_OSPI_STATE_RESET)
  {
    switch (CallbackID)
    {
      case HAL_OSPI_MSP_INIT_CB_ID :
        hospi->MspInitCallback = pCallback;
        break;
      case HAL_OSPI_MSP_DEINIT_CB_ID :
        hospi->MspDeInitCallback = pCallback;
        break;
      default :
        /* Update the error code */
        hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
    /* update return status */
    status =  HAL_ERROR;
  }

  return status;
}

/**
  * @brief  Unregister a User OSPI Callback
  *         OSPI Callback is redirected to the weak predefined callback
  * @param hospi : OSPI handle
  * @param CallbackID : ID of the callback to be unregistered
  *        This parameter can be one of the following values:
  *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
  *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
  *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
  *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
  *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
  *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
  *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
  *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
  *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
  *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
  *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
  *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
  * @retval status
  */
HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (hospi->State == HAL_OSPI_STATE_READY)
  {
    switch (CallbackID)
    {
      case  HAL_OSPI_ERROR_CB_ID :
        hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
        break;
      case HAL_OSPI_ABORT_CB_ID :
        hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
        break;
      case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
        hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
        break;
      case HAL_OSPI_CMD_CPLT_CB_ID :
        hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
        break;
      case HAL_OSPI_RX_CPLT_CB_ID :
        hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
        break;
      case HAL_OSPI_TX_CPLT_CB_ID :
        hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
        break;
      case HAL_OSPI_RX_HALF_CPLT_CB_ID :
        hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
        break;
      case HAL_OSPI_TX_HALF_CPLT_CB_ID :
        hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
        break;
      case HAL_OSPI_STATUS_MATCH_CB_ID :
        hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
        break;
      case HAL_OSPI_TIMEOUT_CB_ID :
        hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
        break;
      case HAL_OSPI_MSP_INIT_CB_ID :
        hospi->MspInitCallback = HAL_OSPI_MspInit;
        break;
      case HAL_OSPI_MSP_DEINIT_CB_ID :
        hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
        break;
      default :
        /* Update the error code */
        hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (hospi->State == HAL_OSPI_STATE_RESET)
  {
    switch (CallbackID)
    {
      case HAL_OSPI_MSP_INIT_CB_ID :
        hospi->MspInitCallback = HAL_OSPI_MspInit;
        break;
      case HAL_OSPI_MSP_DEINIT_CB_ID :
        hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
        break;
      default :
        /* Update the error code */
        hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
    /* update return status */
    status =  HAL_ERROR;
  }

  return status;
}
#endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */

/**
  * @}
  */

/** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
  *  @brief   OSPI control and State functions
  *
@verbatim
 ===============================================================================
                  ##### Peripheral Control and State functions #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to :
      (+) Check in run-time the state of the driver.
      (+) Check the error code set during last operation.
      (+) Abort any operation.
      (+) Manage the Fifo threshold.
      (+) Configure the timeout duration used in the driver.

@endverbatim
  * @{
  */

/**
  * @brief  Abort the current transmission.
  * @param  hospi : OSPI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t state;
  uint32_t tickstart = HAL_GetTick();

  /* Check if the state is in one of the busy or configured states */
  state = hospi->State;
  if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
  {
    /* Check if the DMA is enabled */
    if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
    {
      /* Disable the DMA transfer on the OctoSPI side */
      CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);

      /* Disable the DMA transfer on the DMA side */
      status = HAL_MDMA_Abort(hospi->hmdma);
      if (status != HAL_OK)
      {
        hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
      }
    }

    if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
    {
      /* Perform an abort of the OctoSPI */
      SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);

      /* Wait until the transfer complete flag is set to go back in idle state */
      status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);

      if (status == HAL_OK)
      {
        /* Clear transfer complete flag */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

        /* Wait until the busy flag is reset to go back in idle state */
        status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);

        if (status == HAL_OK)
        {
          /* Update state */
          hospi->State = HAL_OSPI_STATE_READY;
        }
      }
    }
    else
    {
      /* Update state */
      hospi->State = HAL_OSPI_STATE_READY;
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Abort the current transmission (non-blocking function)
  * @param  hospi : OSPI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t state;

  /* Check if the state is in one of the busy or configured states */
  state = hospi->State;
  if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
  {
    /* Disable all interrupts */
    __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));

    /* Update state */
    hospi->State = HAL_OSPI_STATE_ABORT;

    /* Check if the DMA is enabled */
    if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
    {
      /* Disable the DMA transfer on the OctoSPI side */
      CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);

      /* Disable the DMA transfer on the DMA side */
      hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
      if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
      {
        /* Update state */
        hospi->State = HAL_OSPI_STATE_READY;

        /* Abort callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->AbortCpltCallback(hospi);
#else
        HAL_OSPI_AbortCpltCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
      }
    }
    else
    {
      if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
      {
        /* Clear transfer complete flag */
        __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

        /* Enable the transfer complete interrupts */
        __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);

        /* Perform an abort of the OctoSPI */
        SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
      }
      else
      {
        /* Update state */
        hospi->State = HAL_OSPI_STATE_READY;

        /* Abort callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
        hospi->AbortCpltCallback(hospi);
#else
        HAL_OSPI_AbortCpltCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
      }
    }
  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/** @brief  Set OSPI Fifo threshold.
  * @param  hospi     : OSPI handle.
  * @param  Threshold : Threshold of the Fifo.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the state */
  if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
  {
    /* Synchronize initialization structure with the new fifo threshold value */
    hospi->Init.FifoThreshold = Threshold;

    /* Configure new fifo threshold */
    MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));

  }
  else
  {
    status = HAL_ERROR;
    hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  }

  /* Return function status */
  return status;
}

/** @brief  Get OSPI Fifo threshold.
  * @param  hospi : OSPI handle.
  * @retval Fifo threshold
  */
uint32_t HAL_OSPI_GetFifoThreshold(const OSPI_HandleTypeDef *hospi)
{
  return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
}

/** @brief Set OSPI timeout.
  * @param  hospi   : OSPI handle.
  * @param  Timeout : Timeout for the memory access.
  * @retval None
  */
HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
{
  hospi->Timeout = Timeout;
  return HAL_OK;
}

/**
  * @brief  Return the OSPI error code.
  * @param  hospi : OSPI handle
  * @retval OSPI Error Code
  */
uint32_t HAL_OSPI_GetError(const OSPI_HandleTypeDef *hospi)
{
  return hospi->ErrorCode;
}

/**
  * @brief  Return the OSPI handle state.
  * @param  hospi : OSPI handle
  * @retval HAL state
  */
uint32_t HAL_OSPI_GetState(const OSPI_HandleTypeDef *hospi)
{
  /* Return OSPI handle state */
  return hospi->State;
}

/**
  * @}
  */

/** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
  *  @brief   OSPI IO Manager configuration function
  *
@verbatim
 ===============================================================================
                  ##### IO Manager configuration function #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to :
      (+) Configure the IO manager.

@endverbatim
  * @{
  */

/**
  * @brief  Configure the OctoSPI IO manager.
  * @param  hospi   : OSPI handle
  * @param  cfg     : Configuration of the IO Manager for the instance
  * @param  Timeout : Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t instance;
  uint8_t index;
  uint8_t ospi_enabled = 0U;
  uint8_t other_instance;
  OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];

  /* Prevent unused argument(s) compilation warning */
  UNUSED(Timeout);

  /* Check the parameters of the OctoSPI IO Manager configuration structure */
  assert_param(IS_OSPIM_PORT(cfg->ClkPort));
  assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
  assert_param(IS_OSPIM_PORT(cfg->NCSPort));
  assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
  assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
  assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime));

  if (hospi->Instance == OCTOSPI1)
  {
    instance = 0U;
    other_instance = 1U;
  }
  else
  {
    instance = 1U;
    other_instance = 0U;
  }

  /**************** Get current configuration of the instances ****************/
  for (index = 0U; index < OSPI_NB_INSTANCE; index++)
  {
    if (OSPIM_GetConfig(index + 1U, &(IOM_cfg[index])) != HAL_OK)
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
    }
  }

  if (status == HAL_OK)
  {
    /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
    if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
    {
      CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
      ospi_enabled |= 0x1U;
    }
    if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
    {
      CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
      ospi_enabled |= 0x2U;
    }

    /***************** Deactivation of previous configuration *****************/
    CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
    if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
    {
      /* De-multiplexing should be performed */
      CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);

      if (other_instance == 1U)
      {
        SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
        if (IOM_cfg[other_instance].DQSPort != 0U)
        {
          SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
        }
        if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], \
                  OCTOSPIM_PCR_IOLSRC_1);
        }
        if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], \
                  OCTOSPIM_PCR_IOHSRC_1);
        }
      }
    }
    else
    {
      if (IOM_cfg[instance].ClkPort != 0U)
      {
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
        if (IOM_cfg[instance].DQSPort != 0U)
        {
          CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
        }
        if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
        }
        if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
        }
      }
    }

    /********************* Deactivation of other instance *********************/
    if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort)     ||
        (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
        (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
    {
      if ((cfg->ClkPort   == IOM_cfg[other_instance].ClkPort)   &&
          (cfg->DQSPort    == IOM_cfg[other_instance].DQSPort)  &&
          (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
          (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
      {
        /* Multiplexing should be performed */
        SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
      }
      else
      {
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
        if (IOM_cfg[other_instance].DQSPort != 0U)
        {
          CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
        }
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
        if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                    OCTOSPIM_PCR_IOLEN);
        }
        if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                    OCTOSPIM_PCR_IOHEN);
        }
      }
    }

    /******************** Activation of new configuration *********************/
    MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
               (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));

    if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
    {
      MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
    }

    if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
    {
      MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
      if (cfg->DQSPort != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
      }

      if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
      }
      else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
      }
      else
      {
        /* Nothing to do */
      }

      if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
      }
      else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
      }
      else
      {
        /* Nothing to do */
      }
    }
    else
    {
      MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
                 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
      if (cfg->DQSPort != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
                   (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
      }

      if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
                   (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
      }
      else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
                   (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
      }
      else
      {
        /* Nothing to do */
      }

      if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
      }
      else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
      }
      else
      {
        /* Nothing to do */
      }
    }

    /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
    if ((ospi_enabled & 0x1U) != 0U)
    {
      SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
    }
    if ((ospi_enabled & 0x2U) != 0U)
    {
      SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
    }
  }

  /* Return function status */
  return status;
}

/**
  * @}
  */

/**
  @cond 0
  */
/**
  * @brief  DMA OSPI process complete callback.
  * @param  hdma : DMA handle
  * @retval None
  */
static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma)
{
  OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
  hospi->XferCount = 0;

  /* Disable the DMA transfer on the OctoSPI side */
  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);

  /* Disable the DMA channel */
  __HAL_MDMA_DISABLE(hmdma);

  /* Enable the OSPI transfer complete Interrupt */
  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
}

/**
  * @brief  DMA OSPI communication error callback.
  * @param  hdma : DMA handle
  * @retval None
  */
static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma)
{
  OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
  hospi->XferCount = 0;
  hospi->ErrorCode = HAL_OSPI_ERROR_DMA;

  /* Disable the DMA transfer on the OctoSPI side */
  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);

  /* Disable all interrupts */
  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);

  /* Update state */
  hospi->State = HAL_OSPI_STATE_ABORT;

  /* Disable the DMA transfer on the DMA side */
  hospi->hmdma->XferAbortCallback = OSPI_DMAAbortOnError;
  if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
  {
    /* Update state */
    hospi->State = HAL_OSPI_STATE_READY;

    /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->ErrorCallback(hospi);
#else
    HAL_OSPI_ErrorCallback(hospi);
#endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  }
}

/**
  * @brief  DMA OSPI abort complete callback.
  * @param  hdma : DMA handle
  * @retval None
  */
static void OSPI_DMAAbortOnError(MDMA_HandleTypeDef *hmdma)
{
  OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);

  /* DMA abort called by OctoSPI abort */
  if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
  {
    /* Clear transfer complete flag */
    __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

    /* Enable the transfer complete interrupts */
    __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);

    /* Perform an abort of the OctoSPI */
    SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
  }
  else
  {
    /* Update state */
    hospi->State = HAL_OSPI_STATE_READY;

    /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->ErrorCallback(hospi);
#else
    HAL_OSPI_ErrorCallback(hospi);
#endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  }
}

/**
  * @brief  DMA OSPI abort complete callback.
  * @param  hdma : DMA handle
  * @retval None
  */
static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
{
  OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
  hospi->XferCount = 0;

  /* Check the state */
  if (hospi->State == HAL_OSPI_STATE_ABORT)
  {
    /* DMA abort called by OctoSPI abort */
    if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
    {
      /* Clear transfer complete flag */
      __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);

      /* Enable the transfer complete interrupts */
      __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);

      /* Perform an abort of the OctoSPI */
      SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
    }
    else
    {
      /* Update state */
      hospi->State = HAL_OSPI_STATE_READY;

      /* Abort callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
      hospi->AbortCpltCallback(hospi);
#else
      HAL_OSPI_AbortCpltCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
    }
  }
  else
  {
    /* DMA abort called due to a transfer error interrupt */
    /* Update state */
    hospi->State = HAL_OSPI_STATE_READY;

    /* Error callback */
#if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
    hospi->ErrorCallback(hospi);
#else
    HAL_OSPI_ErrorCallback(hospi);
#endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  }
}

/**
  * @brief  Wait for a flag state until timeout.
  * @param  hospi     : OSPI handle
  * @param  Flag      : Flag checked
  * @param  State     : Value of the flag expected
  * @param  Timeout   : Duration of the timeout
  * @param  Tickstart : Tick start value
  * @retval HAL status
  */
static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
                                                        FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
{
  /* Wait until flag is in expected state */
  while ((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
  {
    /* Check for the Timeout */
    if (Timeout != HAL_MAX_DELAY)
    {
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
      {
        hospi->State     = HAL_OSPI_STATE_ERROR;
        hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;

        return HAL_ERROR;
      }
    }
  }
  return HAL_OK;
}

/**
  * @brief  Configure the registers for the regular command mode.
  * @param  hospi : OSPI handle
  * @param  cmd   : structure that contains the command configuration information
  * @retval HAL status
  */
static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
{
  HAL_StatusTypeDef status = HAL_OK;
  __IO uint32_t *ccr_reg;
  __IO uint32_t *tcr_reg;
  __IO uint32_t *ir_reg;
  __IO uint32_t *abr_reg;

  /* Re-initialize the value of the functional mode */
  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);

  /* Configure the flash ID */
  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  {
    MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
  }

  if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
  {
    ccr_reg = &(hospi->Instance->WCCR);
    tcr_reg = &(hospi->Instance->WTCR);
    ir_reg  = &(hospi->Instance->WIR);
    abr_reg = &(hospi->Instance->WABR);
  }
  else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
  {
    ccr_reg = &(hospi->Instance->WPCCR);
    tcr_reg = &(hospi->Instance->WPTCR);
    ir_reg  = &(hospi->Instance->WPIR);
    abr_reg = &(hospi->Instance->WPABR);
  }
  else
  {
    ccr_reg = &(hospi->Instance->CCR);
    tcr_reg = &(hospi->Instance->TCR);
    ir_reg  = &(hospi->Instance->IR);
    abr_reg = &(hospi->Instance->ABR);
  }

  /* Configure the CCR register with DQS and SIOO modes */
  *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);

  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  {
    /* Configure the ABR register with alternate bytes value */
    *abr_reg = cmd->AlternateBytes;

    /* Configure the CCR register with alternate bytes communication parameters */
    MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
               (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
  }

  /* Configure the TCR register with the number of dummy cycles */
  MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);

  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  {
    if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
    {
      /* Configure the DLR register with the number of data */
      hospi->Instance->DLR = (cmd->NbData - 1U);
    }
  }

  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  {
    if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
    {
      if (cmd->DataMode != HAL_OSPI_DATA_NONE)
      {
        /* ---- Command with instruction, address and data ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
                                OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
                                OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
                   (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
                    cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize     |
                    cmd->DataMode        | cmd->DataDtrMode));
      }
      else
      {
        /* ---- Command with instruction and address ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
                                OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
                   (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
                    cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize));

        /* The DHQC bit is linked with DDTR bit which should be activated */
        if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
            (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
        {
          MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
        }
      }

      /* Configure the IR register with the instruction value */
      *ir_reg = cmd->Instruction;

      /* Configure the AR register with the address value */
      hospi->Instance->AR = cmd->Address;
    }
    else
    {
      if (cmd->DataMode != HAL_OSPI_DATA_NONE)
      {
        /* ---- Command with instruction and data ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
                                OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
                   (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
                    cmd->DataMode        | cmd->DataDtrMode));
      }
      else
      {
        /* ---- Command with only instruction ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
                   (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));

        /* The DHQC bit is linked with DDTR bit which should be activated */
        if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
            (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
        {
          MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
        }
      }

      /* Configure the IR register with the instruction value */
      *ir_reg = cmd->Instruction;

    }
  }
  else
  {
    if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
    {
      if (cmd->DataMode != HAL_OSPI_DATA_NONE)
      {
        /* ---- Command with address and data ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
                                OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
                   (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | cmd->DataMode |
                    cmd->DataDtrMode));
      }
      else
      {
        /* ---- Command with only address ---- */

        /* Configure the CCR register with all communication parameters */
        MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
                   (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
      }

      /* Configure the AR register with the instruction value */
      hospi->Instance->AR = cmd->Address;
    }
    else
    {
      /* ---- Invalid command configuration (no instruction, no address) ---- */
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
    }
  }

  /* Return function status */
  return status;
}

/**
  * @brief  Get the current IOM configuration for an OctoSPI instance.
  * @param  instance_nb : number of the instance
  * @param  cfg         : configuration of the IO Manager for the instance
  * @retval HAL status
  */
static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t reg;
  uint32_t value = 0U;
  uint32_t index;

  if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
  {
    /* Invalid parameter -> error returned */
    status = HAL_ERROR;
  }
  else
  {
    /* Initialize the structure */
    cfg->ClkPort    = 0U;
    cfg->DQSPort    = 0U;
    cfg->NCSPort    = 0U;
    cfg->IOLowPort  = 0U;
    cfg->IOHighPort = 0U;

    if (instance_nb == 2U)
    {
      if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
      {
        value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC
                 | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
      }
      else
      {
        value = OCTOSPIM_PCR_NCSSRC;
      }
    }

    /* Get the information about the instance */
    for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
    {
      reg = OCTOSPIM->PCR[index];

      if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
      {
        /* The clock is enabled on this port */
        if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
        {
          /* The clock correspond to the instance passed as parameter */
          cfg->ClkPort = index + 1U;
        }
      }

      if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
      {
        /* The DQS is enabled on this port */
        if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
        {
          /* The DQS correspond to the instance passed as parameter */
          cfg->DQSPort = index + 1U;
        }
      }

      if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
      {
        /* The nCS is enabled on this port */
        if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
        {
          /* The nCS correspond to the instance passed as parameter */
          cfg->NCSPort = index + 1U;
        }
      }

      if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        /* The IO Low is enabled on this port */
        if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
        {
          /* The IO Low correspond to the instance passed as parameter */
          if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
          {
            cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
          }
          else
          {
            cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
          }
        }
      }

      if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
      {
        /* The IO High is enabled on this port */
        if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
        {
          /* The IO High correspond to the instance passed as parameter */
          if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
          {
            cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
          }
          else
          {
            cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
          }
        }
      }
    }
  }

  /* Return function status */
  return status;
}

/**
  @endcond
  */

/**
  * @}
  */

#endif /* HAL_OSPI_MODULE_ENABLED */

/**
  * @}
  */

/**
  * @}
  */

#endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
