Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_ospi.c
0004   * @author  MCD Application Team
0005   * @brief   OSPI HAL module driver.
0006              This file provides firmware functions to manage the following
0007              functionalities of the OctoSPI interface (OSPI).
0008               + Initialization and de-initialization functions
0009               + Hyperbus configuration
0010               + Indirect functional mode management
0011               + Memory-mapped functional mode management
0012               + Auto-polling functional mode management
0013               + Interrupts and flags management
0014               + DMA channel configuration for indirect functional mode
0015               + Errors management and abort functionality
0016               + IO manager configuration
0017 
0018   ******************************************************************************
0019   * @attention
0020   *
0021   * Copyright (c) 2017 STMicroelectronics.
0022   * All rights reserved.
0023   *
0024   * This software is licensed under terms that can be found in the LICENSE file
0025   * in the root directory of this software component.
0026   * If no LICENSE file comes with this software, it is provided AS-IS.
0027   *
0028   ******************************************************************************
0029   @verbatim
0030  ===============================================================================
0031                         ##### How to use this driver #####
0032  ===============================================================================
0033   [..]
0034     *** Initialization ***
0035     ======================
0036     [..]
0037      As prerequisite, fill in the HAL_OSPI_MspInit() :
0038      (+) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE().
0039      (+) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET().
0040      (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
0041      (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
0042      (+) If interrupt or DMA mode is used, enable and configure OctoSPI global
0043          interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
0044      (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
0045          with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
0046          link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
0047          DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
0048     [..]
0049      Configure the fifo threshold, the dual-quad mode, the memory type, the
0050      device size, the CS high time, the free running clock, the clock mode,
0051      the wrap size, the clock prescaler, the sample shifting, the hold delay
0052      and the CS boundary using the HAL_OSPI_Init() function.
0053     [..]
0054      When using Hyperbus, configure the RW recovery time, the access time,
0055      the write latency and the latency mode using the HAL_OSPI_HyperbusCfg()
0056      function.
0057 
0058     *** Indirect functional mode ***
0059     ================================
0060     [..]
0061      In regular mode, configure the command sequence using the HAL_OSPI_Command()
0062      or HAL_OSPI_Command_IT() functions :
0063      (+) Instruction phase : the mode used and if present the size, the instruction
0064          opcode and the DTR mode.
0065      (+) Address phase : the mode used and if present the size, the address
0066          value and the DTR mode.
0067      (+) Alternate-bytes phase : the mode used and if present the size, the
0068          alternate bytes values and the DTR mode.
0069      (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
0070      (+) Data phase : the mode used and if present the number of bytes and the DTR mode.
0071      (+) Data strobe (DQS) mode : the activation (or not) of this mode
0072      (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
0073      (+) Flash identifier : in dual-quad mode, indicates which flash is concerned
0074      (+) Operation type : always common configuration
0075     [..]
0076      In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd()
0077      function :
0078      (+) Address space : indicate if the access will be done in register or memory
0079      (+) Address size
0080      (+) Number of data
0081      (+) Data strobe (DQS) mode : the activation (or not) of this mode
0082     [..]
0083      If no data is required for the command (only for regular mode, not for
0084      Hyperbus mode), it is sent directly to the memory :
0085      (+) In polling mode, the output of the function is done when the transfer is complete.
0086      (+) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete.
0087     [..]
0088      For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or
0089      HAL_OSPI_Transmit_IT() after the command configuration :
0090      (+) In polling mode, the output of the function is done when the transfer is complete.
0091      (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
0092          is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
0093      (+) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and
0094          HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
0095     [..]
0096      For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or
0097      HAL_OSPI_Receive_IT() after the command configuration :
0098      (+) In polling mode, the output of the function is done when the transfer is complete.
0099      (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
0100          is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
0101      (+) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and
0102          HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
0103 
0104     *** Auto-polling functional mode ***
0105     ====================================
0106     [..]
0107      Configure the command sequence by the same way than the indirect mode
0108     [..]
0109      Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling()
0110      or HAL_OSPI_AutoPolling_IT() functions :
0111      (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
0112          the polling interval and the automatic stop activation.
0113     [..]
0114      After the configuration :
0115      (+) In polling mode, the output of the function is done when the status match is reached. The
0116          automatic stop is activated to avoid an infinite loop.
0117      (+) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached.
0118 
0119     *** MDMA functional mode ***
0120     ====================================
0121     [..]
0122      Configure the SourceInc and DestinationInc of MDMA parameters in the HAL_OSPI_MspInit() function :
0123      (+) MDMA settings for write operation :
0124          (++) The DestinationInc should be MDMA_DEST_INC_DISABLE
0125          (++) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
0126          (++) The SourceDataSize must be a value of @ref MDMA Source data size
0127               (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
0128               aligned with @ref MDMA_Source_increment_mode .
0129          (++) The DestDataSize must be a value of @ref MDMA Destination data size
0130               (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
0131      (+) MDMA settings for read operation :
0132          (++) The SourceInc should be MDMA_SRC_INC_DISABLE
0133          (++) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode
0134          (Except the MDMA_DEST_INC_DOUBLEWORD).
0135          (++) The SourceDataSize must be a value of @ref MDMA Source data size
0136               (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
0137          (++) The DestDataSize must be a value of @ref MDMA Destination data size
0138               (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
0139               aligned with @ref MDMA_Destination_increment_mode.
0140      (+) The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Octospi.
0141     [..]
0142      In case of wrong MDMA setting
0143      (+) For write operation :
0144          (++) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled
0145               by the HAL_OSPI_Transmit_DMA().
0146      (+) For read operation :
0147          (++) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled
0148               by the HAL_OSPI_Receive_DMA().
0149 
0150     *** Memory-mapped functional mode ***
0151     =====================================
0152     [..]
0153      Configure the command sequence by the same way than the indirect mode except
0154      for the operation type in regular mode :
0155      (+) Operation type equals to read configuration : the command configuration
0156          applies to read access in memory-mapped mode
0157      (+) Operation type equals to write configuration : the command configuration
0158          applies to write access in memory-mapped mode
0159      (+) Both read and write configuration should be performed before activating
0160          memory-mapped mode
0161     [..]
0162      Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
0163      functions :
0164      (+) The timeout activation and the timeout period.
0165     [..]
0166      After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
0167      the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires.
0168 
0169     *** Errors management and abort functionality ***
0170     =================================================
0171     [..]
0172      HAL_OSPI_GetError() function gives the error raised during the last operation.
0173     [..]
0174      HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and
0175      flushes the fifo :
0176      (+) In polling mode, the output of the function is done when the transfer
0177          complete bit is set and the busy bit cleared.
0178      (+) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when
0179          the transfer complete bit is set.
0180 
0181     *** Control functions ***
0182     =========================
0183     [..]
0184      HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver.
0185     [..]
0186      HAL_OSPI_SetTimeout() function configures the timeout value used in the driver.
0187     [..]
0188      HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral.
0189     [..]
0190      HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
0191 
0192     *** IO manager configuration functions ***
0193     ==========================================
0194     [..]
0195      HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.
0196 
0197     *** Callback registration ***
0198     =============================================
0199     [..]
0200      The compilation define  USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1
0201      allows the user to configure dynamically the driver callbacks.
0202 
0203     [..]
0204      Use function HAL_OSPI_RegisterCallback() to register a user callback,
0205      it allows to register following callbacks:
0206      (+) ErrorCallback : callback when error occurs.
0207      (+) AbortCpltCallback : callback when abort is completed.
0208      (+) FifoThresholdCallback : callback when the fifo threshold is reached.
0209      (+) CmdCpltCallback : callback when a command without data is completed.
0210      (+) RxCpltCallback : callback when a reception transfer is completed.
0211      (+) TxCpltCallback : callback when a transmission transfer is completed.
0212      (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
0213      (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
0214      (+) StatusMatchCallback : callback when a status match occurs.
0215      (+) TimeOutCallback : callback when the timeout perioed expires.
0216      (+) MspInitCallback    : OSPI MspInit.
0217      (+) MspDeInitCallback  : OSPI MspDeInit.
0218     [..]
0219      This function takes as parameters the HAL peripheral handle, the Callback ID
0220      and a pointer to the user callback function.
0221 
0222     [..]
0223      Use function HAL_OSPI_UnRegisterCallback() to reset a callback to the default
0224      weak (overridden) function. It allows to reset following callbacks:
0225      (+) ErrorCallback : callback when error occurs.
0226      (+) AbortCpltCallback : callback when abort is completed.
0227      (+) FifoThresholdCallback : callback when the fifo threshold is reached.
0228      (+) CmdCpltCallback : callback when a command without data is completed.
0229      (+) RxCpltCallback : callback when a reception transfer is completed.
0230      (+) TxCpltCallback : callback when a transmission transfer is completed.
0231      (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
0232      (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
0233      (+) StatusMatchCallback : callback when a status match occurs.
0234      (+) TimeOutCallback : callback when the timeout perioed expires.
0235      (+) MspInitCallback    : OSPI MspInit.
0236      (+) MspDeInitCallback  : OSPI MspDeInit.
0237     [..]
0238      This function) takes as parameters the HAL peripheral handle and the Callback ID.
0239 
0240     [..]
0241      By default, after the HAL_OSPI_Init() and if the state is HAL_OSPI_STATE_RESET
0242      all callbacks are reset to the corresponding legacy weak (overridden) functions.
0243      Exception done for MspInit and MspDeInit callbacks that are respectively
0244      reset to the legacy weak (overridden) functions in the HAL_OSPI_Init()
0245      and HAL_OSPI_DeInit() only when these callbacks are null (not registered beforehand).
0246      If not, MspInit or MspDeInit are not null, the HAL_OSPI_Init() and HAL_OSPI_DeInit()
0247      keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0248 
0249     [..]
0250      Callbacks can be registered/unregistered in READY state only.
0251      Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0252      in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0253      during the Init/DeInit.
0254      In that case first register the MspInit/MspDeInit user callbacks
0255      using HAL_OSPI_RegisterCallback() before calling HAL_OSPI_DeInit()
0256      or HAL_OSPI_Init() function.
0257 
0258     [..]
0259      When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or
0260      not defined, the callback registering feature is not available
0261      and weak (overridden) callbacks are used.
0262 
0263   @endverbatim
0264   ******************************************************************************
0265   */
0266 
0267 /* Includes ------------------------------------------------------------------*/
0268 #include "stm32h7xx_hal.h"
0269 
0270 #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)
0271 
0272 /** @addtogroup STM32H7xx_HAL_Driver
0273   * @{
0274   */
0275 
0276 /** @defgroup OSPI OSPI
0277   * @ingroup RTEMSBSPsARMSTM32H7
0278   * @brief OSPI HAL module driver
0279   * @{
0280   */
0281 
0282 #ifdef HAL_OSPI_MODULE_ENABLED
0283 
0284 /**
0285   @cond 0
0286   */
0287 /* Private typedef -----------------------------------------------------------*/
0288 
0289 /* Private define ------------------------------------------------------------*/
0290 #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000)         /*!< Indirect write mode    */
0291 #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode     */
0292 #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */
0293 #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)OCTOSPI_CR_FMODE)   /*!< Memory-mapped mode     */
0294 
0295 #define OSPI_CFG_STATE_MASK  0x00000004U
0296 #define OSPI_BUSY_STATE_MASK 0x00000008U
0297 
0298 #define OSPI_NB_INSTANCE   2U
0299 #define OSPI_IOM_NB_PORTS  2U
0300 #define OSPI_IOM_PORT_MASK 0x1U
0301 
0302 /* Private macro -------------------------------------------------------------*/
0303 #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
0304                                        ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
0305                                        ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
0306                                        ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
0307 
0308 /* Private variables ---------------------------------------------------------*/
0309 
0310 /* Private function prototypes -----------------------------------------------*/
0311 static void              OSPI_DMACplt(MDMA_HandleTypeDef *hmdma);
0312 static void              OSPI_DMAError(MDMA_HandleTypeDef *hmdma);
0313 static void              OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma);
0314 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State,
0315                                                         uint32_t Tickstart, uint32_t Timeout);
0316 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
0317 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
0318 static void OSPI_DMAAbortOnError(MDMA_HandleTypeDef *hmdma);
0319 /**
0320   @endcond
0321   */
0322 
0323 /* Exported functions --------------------------------------------------------*/
0324 
0325 /** @defgroup OSPI_Exported_Functions OSPI Exported Functions
0326   * @ingroup RTEMSBSPsARMSTM32H7
0327   * @{
0328   */
0329 
0330 /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
0331   * @ingroup RTEMSBSPsARMSTM32H7
0332   * @brief    Initialization and Configuration functions
0333   *
0334 @verbatim
0335 ===============================================================================
0336             ##### Initialization and Configuration functions #####
0337  ===============================================================================
0338     [..]
0339     This subsection provides a set of functions allowing to :
0340       (+) Initialize the OctoSPI.
0341       (+) De-initialize the OctoSPI.
0342 
0343 @endverbatim
0344   * @{
0345   */
0346 
0347 /**
0348   * @brief  Initialize the OSPI mode according to the specified parameters
0349   *         in the OSPI_InitTypeDef and initialize the associated handle.
0350   * @param  hospi : OSPI handle
0351   * @retval HAL status
0352   */
0353 HAL_StatusTypeDef HAL_OSPI_Init(OSPI_HandleTypeDef *hospi)
0354 {
0355   HAL_StatusTypeDef status = HAL_OK;
0356   uint32_t tickstart = HAL_GetTick();
0357 
0358   /* Check the OSPI handle allocation */
0359   if (hospi == NULL)
0360   {
0361     status = HAL_ERROR;
0362     /* No error code can be set set as the handler is null */
0363   }
0364   else
0365   {
0366     /* Check the parameters of the initialization structure */
0367     assert_param(IS_OSPI_FIFO_THRESHOLD(hospi->Init.FifoThreshold));
0368     assert_param(IS_OSPI_DUALQUAD_MODE(hospi->Init.DualQuad));
0369     assert_param(IS_OSPI_MEMORY_TYPE(hospi->Init.MemoryType));
0370     assert_param(IS_OSPI_DEVICE_SIZE(hospi->Init.DeviceSize));
0371     assert_param(IS_OSPI_CS_HIGH_TIME(hospi->Init.ChipSelectHighTime));
0372     assert_param(IS_OSPI_FREE_RUN_CLK(hospi->Init.FreeRunningClock));
0373     assert_param(IS_OSPI_CLOCK_MODE(hospi->Init.ClockMode));
0374     assert_param(IS_OSPI_WRAP_SIZE(hospi->Init.WrapSize));
0375     assert_param(IS_OSPI_CLK_PRESCALER(hospi->Init.ClockPrescaler));
0376     assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
0377     assert_param(IS_OSPI_DHQC(hospi->Init.DelayHoldQuarterCycle));
0378     assert_param(IS_OSPI_CS_BOUNDARY(hospi->Init.ChipSelectBoundary));
0379     assert_param(IS_OSPI_DLYBYP(hospi->Init.DelayBlockBypass));
0380     assert_param(IS_OSPI_MAXTRAN(hospi->Init.MaxTran));
0381 
0382     /* Initialize error code */
0383     hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
0384 
0385     /* Check if the state is the reset state */
0386     if (hospi->State == HAL_OSPI_STATE_RESET)
0387     {
0388 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0389       /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
0390       hospi->ErrorCallback         = HAL_OSPI_ErrorCallback;
0391       hospi->AbortCpltCallback     = HAL_OSPI_AbortCpltCallback;
0392       hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
0393       hospi->CmdCpltCallback       = HAL_OSPI_CmdCpltCallback;
0394       hospi->RxCpltCallback        = HAL_OSPI_RxCpltCallback;
0395       hospi->TxCpltCallback        = HAL_OSPI_TxCpltCallback;
0396       hospi->RxHalfCpltCallback    = HAL_OSPI_RxHalfCpltCallback;
0397       hospi->TxHalfCpltCallback    = HAL_OSPI_TxHalfCpltCallback;
0398       hospi->StatusMatchCallback   = HAL_OSPI_StatusMatchCallback;
0399       hospi->TimeOutCallback       = HAL_OSPI_TimeOutCallback;
0400 
0401       if (hospi->MspInitCallback == NULL)
0402       {
0403         hospi->MspInitCallback = HAL_OSPI_MspInit;
0404       }
0405 
0406       /* Init the low level hardware */
0407       hospi->MspInitCallback(hospi);
0408 #else
0409       /* Initialization of the low level hardware */
0410       HAL_OSPI_MspInit(hospi);
0411 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0412 
0413       /* Configure the default timeout for the OSPI memory access */
0414       (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
0415 
0416       /* Configure memory type, device size, chip select high time, delay block bypass,
0417          free running clock, clock mode */
0418       MODIFY_REG(hospi->Instance->DCR1,
0419                  (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_DLYBYP |
0420                   OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
0421                  (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
0422                   ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
0423                   hospi->Init.DelayBlockBypass | hospi->Init.ClockMode));
0424 
0425       /* Configure wrap size */
0426       MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);
0427 
0428       /* Configure chip select boundary and maximum transfer */
0429       hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) |
0430                                (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));
0431 
0432       /* Configure refresh */
0433       hospi->Instance->DCR4 = hospi->Init.Refresh;
0434 
0435       /* Configure FIFO threshold */
0436       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
0437 
0438       /* Wait till busy flag is reset */
0439       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
0440 
0441       if (status == HAL_OK)
0442       {
0443         /* Configure clock prescaler */
0444         MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER,
0445                    ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
0446 
0447         /* Configure Dual Quad mode */
0448         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
0449 
0450         /* Configure sample shifting and delay hold quarter cycle */
0451         MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC),
0452                    (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
0453 
0454         /* Enable OctoSPI */
0455         __HAL_OSPI_ENABLE(hospi);
0456 
0457         /* Enable free running clock if needed : must be done after OSPI enable */
0458         if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
0459         {
0460           SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
0461         }
0462 
0463         /* Initialize the OSPI state */
0464         if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
0465         {
0466           hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
0467         }
0468         else
0469         {
0470           hospi->State = HAL_OSPI_STATE_READY;
0471         }
0472       }
0473     }
0474   }
0475 
0476   /* Return function status */
0477   return status;
0478 }
0479 
0480 /**
0481   * @brief  Initialize the OSPI MSP.
0482   * @param  hospi : OSPI handle
0483   * @retval None
0484   */
0485 __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
0486 {
0487   /* Prevent unused argument(s) compilation warning */
0488   UNUSED(hospi);
0489 
0490   /* NOTE : This function should not be modified, when the callback is needed,
0491             the HAL_OSPI_MspInit can be implemented in the user file
0492    */
0493 }
0494 
0495 /**
0496   * @brief  De-Initialize the OSPI peripheral.
0497   * @param  hospi : OSPI handle
0498   * @retval HAL status
0499   */
0500 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
0501 {
0502   HAL_StatusTypeDef status = HAL_OK;
0503 
0504   /* Check the OSPI handle allocation */
0505   if (hospi == NULL)
0506   {
0507     status = HAL_ERROR;
0508     /* No error code can be set set as the handler is null */
0509   }
0510   else
0511   {
0512     /* Disable OctoSPI */
0513     __HAL_OSPI_DISABLE(hospi);
0514 
0515     /* Disable free running clock if needed : must be done after OSPI disable */
0516     CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
0517 
0518 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0519     if (hospi->MspDeInitCallback == NULL)
0520     {
0521       hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
0522     }
0523 
0524     /* DeInit the low level hardware */
0525     hospi->MspDeInitCallback(hospi);
0526 #else
0527     /* De-initialize the low-level hardware */
0528     HAL_OSPI_MspDeInit(hospi);
0529 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0530 
0531     /* Reset the driver state */
0532     hospi->State = HAL_OSPI_STATE_RESET;
0533   }
0534 
0535   return status;
0536 }
0537 
0538 /**
0539   * @brief  DeInitialize the OSPI MSP.
0540   * @param  hospi : OSPI handle
0541   * @retval None
0542   */
0543 __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
0544 {
0545   /* Prevent unused argument(s) compilation warning */
0546   UNUSED(hospi);
0547 
0548   /* NOTE : This function should not be modified, when the callback is needed,
0549             the HAL_OSPI_MspDeInit can be implemented in the user file
0550    */
0551 }
0552 
0553 /**
0554   * @}
0555   */
0556 
0557 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
0558   * @ingroup RTEMSBSPsARMSTM32H7
0559   *  @brief OSPI Transmit/Receive functions
0560   *
0561 @verbatim
0562  ===============================================================================
0563                       ##### IO operation functions #####
0564  ===============================================================================
0565     [..]
0566     This subsection provides a set of functions allowing to :
0567       (+) Handle the interrupts.
0568       (+) Handle the command sequence (regular and Hyperbus).
0569       (+) Handle the Hyperbus configuration.
0570       (+) Transmit data in blocking, interrupt or DMA mode.
0571       (+) Receive data in blocking, interrupt or DMA mode.
0572       (+) Manage the auto-polling functional mode.
0573       (+) Manage the memory-mapped functional mode.
0574 
0575 @endverbatim
0576   * @{
0577   */
0578 
0579 /**
0580   * @brief  Handle OSPI interrupt request.
0581   * @param  hospi : OSPI handle
0582   * @retval None
0583   */
0584 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
0585 {
0586   __IO uint32_t *data_reg = &hospi->Instance->DR;
0587   uint32_t flag           = hospi->Instance->SR;
0588   uint32_t itsource       = hospi->Instance->CR;
0589   uint32_t currentstate   = hospi->State;
0590 
0591   /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
0592   if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
0593   {
0594     if (currentstate == HAL_OSPI_STATE_BUSY_TX)
0595     {
0596       /* Write a data in the fifo */
0597       *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
0598       hospi->pBuffPtr++;
0599       hospi->XferCount--;
0600     }
0601     else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
0602     {
0603       /* Read a data from the fifo */
0604       *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
0605       hospi->pBuffPtr++;
0606       hospi->XferCount--;
0607     }
0608     else
0609     {
0610       /* Nothing to do */
0611     }
0612 
0613     if (hospi->XferCount == 0U)
0614     {
0615       /* All data have been received or transmitted for the transfer */
0616       /* Disable fifo threshold interrupt */
0617       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
0618     }
0619 
0620     /* Fifo threshold callback */
0621 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0622     hospi->FifoThresholdCallback(hospi);
0623 #else
0624     HAL_OSPI_FifoThresholdCallback(hospi);
0625 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
0626   }
0627   /* OctoSPI transfer complete interrupt occurred ----------------------------*/
0628   else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
0629   {
0630     if (currentstate == HAL_OSPI_STATE_BUSY_RX)
0631     {
0632       if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
0633       {
0634         /* Read the last data received in the fifo */
0635         *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
0636         hospi->pBuffPtr++;
0637         hospi->XferCount--;
0638       }
0639       else if (hospi->XferCount == 0U)
0640       {
0641         /* Clear flag */
0642         hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
0643 
0644         /* Disable the interrupts */
0645         __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
0646 
0647         /* Update state */
0648         hospi->State = HAL_OSPI_STATE_READY;
0649 
0650         /* RX complete callback */
0651 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0652         hospi->RxCpltCallback(hospi);
0653 #else
0654         HAL_OSPI_RxCpltCallback(hospi);
0655 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0656       }
0657       else
0658       {
0659         /* Nothing to do */
0660       }
0661     }
0662     else
0663     {
0664       /* Clear flag */
0665       hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
0666 
0667       /* Disable the interrupts */
0668       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
0669 
0670       /* Update state */
0671       hospi->State = HAL_OSPI_STATE_READY;
0672 
0673       if (currentstate == HAL_OSPI_STATE_BUSY_TX)
0674       {
0675         /* TX complete callback */
0676 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0677         hospi->TxCpltCallback(hospi);
0678 #else
0679         HAL_OSPI_TxCpltCallback(hospi);
0680 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0681       }
0682       else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
0683       {
0684         /* Command complete callback */
0685 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0686         hospi->CmdCpltCallback(hospi);
0687 #else
0688         HAL_OSPI_CmdCpltCallback(hospi);
0689 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0690       }
0691       else if (currentstate == HAL_OSPI_STATE_ABORT)
0692       {
0693         if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
0694         {
0695           /* Abort called by the user */
0696           /* Abort complete callback */
0697 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0698           hospi->AbortCpltCallback(hospi);
0699 #else
0700           HAL_OSPI_AbortCpltCallback(hospi);
0701 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
0702         }
0703         else
0704         {
0705           /* Abort due to an error (eg : DMA error) */
0706           /* Error callback */
0707 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0708           hospi->ErrorCallback(hospi);
0709 #else
0710           HAL_OSPI_ErrorCallback(hospi);
0711 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0712         }
0713       }
0714       else
0715       {
0716         /* Nothing to do */
0717       }
0718     }
0719   }
0720   /* OctoSPI status match interrupt occurred ---------------------------------*/
0721   else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
0722   {
0723     /* Clear flag */
0724     hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
0725 
0726     /* Check if automatic poll mode stop is activated */
0727     if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
0728     {
0729       /* Disable the interrupts */
0730       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
0731 
0732       /* Update state */
0733       hospi->State = HAL_OSPI_STATE_READY;
0734     }
0735 
0736     /* Status match callback */
0737 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0738     hospi->StatusMatchCallback(hospi);
0739 #else
0740     HAL_OSPI_StatusMatchCallback(hospi);
0741 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0742   }
0743   /* OctoSPI transfer error interrupt occurred -------------------------------*/
0744   else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
0745   {
0746     /* Clear flag */
0747     hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
0748 
0749     /* Disable all interrupts */
0750     __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));
0751 
0752     /* Set error code */
0753     hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
0754 
0755     /* Check if the DMA is enabled */
0756     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
0757     {
0758       /* Disable the DMA transfer on the OctoSPI side */
0759       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
0760 
0761       /* Disable the DMA transfer on the DMA side */
0762       hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
0763       if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
0764       {
0765         /* Update state */
0766         hospi->State = HAL_OSPI_STATE_READY;
0767 
0768         /* Error callback */
0769 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0770         hospi->ErrorCallback(hospi);
0771 #else
0772         HAL_OSPI_ErrorCallback(hospi);
0773 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
0774       }
0775     }
0776     else
0777     {
0778       /* Update state */
0779       hospi->State = HAL_OSPI_STATE_READY;
0780 
0781       /* Error callback */
0782 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0783       hospi->ErrorCallback(hospi);
0784 #else
0785       HAL_OSPI_ErrorCallback(hospi);
0786 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0787     }
0788   }
0789   /* OctoSPI timeout interrupt occurred --------------------------------------*/
0790   else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
0791   {
0792     /* Clear flag */
0793     hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
0794 
0795     /* Timeout callback */
0796 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
0797     hospi->TimeOutCallback(hospi);
0798 #else
0799     HAL_OSPI_TimeOutCallback(hospi);
0800 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
0801   }
0802   else
0803   {
0804     /* Nothing to do */
0805   }
0806 }
0807 
0808 /**
0809   * @brief  Set the command configuration.
0810   * @param  hospi   : OSPI handle
0811   * @param  cmd     : structure that contains the command configuration information
0812   * @param  Timeout : Timeout duration
0813   * @retval HAL status
0814   */
0815 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
0816 {
0817   HAL_StatusTypeDef status;
0818   uint32_t state;
0819   uint32_t tickstart = HAL_GetTick();
0820 
0821   /* Check the parameters of the command structure */
0822   assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
0823 
0824   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
0825   {
0826     assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
0827   }
0828 
0829   assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
0830   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
0831   {
0832     assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
0833     assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
0834   }
0835 
0836   assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
0837   if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
0838   {
0839     assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
0840     assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
0841   }
0842 
0843   assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
0844   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
0845   {
0846     assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
0847     assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
0848   }
0849 
0850   assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
0851   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
0852   {
0853     if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
0854     {
0855       assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
0856     }
0857     assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
0858     assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
0859   }
0860 
0861   assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
0862   assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
0863 
0864   /* Check the state of the driver */
0865   state = hospi->State;
0866   if (((state == HAL_OSPI_STATE_READY)         && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
0867       ((state == HAL_OSPI_STATE_READ_CMD_CFG)  && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
0868                                                    || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) ||
0869       ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)  ||
0870                                                    (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))))
0871   {
0872     /* Wait till busy flag is reset */
0873     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
0874 
0875     if (status == HAL_OK)
0876     {
0877       /* Initialize error code */
0878       hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
0879 
0880       /* Configure the registers */
0881       status = OSPI_ConfigCmd(hospi, cmd);
0882 
0883       if (status == HAL_OK)
0884       {
0885         if (cmd->DataMode == HAL_OSPI_DATA_NONE)
0886         {
0887           /* When there is no data phase, the transfer start as soon as the configuration is done
0888              so wait until TC flag is set to go back in idle state */
0889           status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
0890 
0891           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
0892         }
0893         else
0894         {
0895           /* Update the state */
0896           if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
0897           {
0898             hospi->State = HAL_OSPI_STATE_CMD_CFG;
0899           }
0900           else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
0901           {
0902             if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
0903             {
0904               hospi->State = HAL_OSPI_STATE_CMD_CFG;
0905             }
0906             else
0907             {
0908               hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
0909             }
0910           }
0911           else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
0912           {
0913             if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
0914             {
0915               hospi->State = HAL_OSPI_STATE_CMD_CFG;
0916             }
0917             else
0918             {
0919               hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
0920             }
0921           }
0922           else
0923           {
0924             /* Wrap configuration, no state change */
0925           }
0926         }
0927       }
0928     }
0929   }
0930   else
0931   {
0932     status = HAL_ERROR;
0933     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
0934   }
0935 
0936   /* Return function status */
0937   return status;
0938 }
0939 
0940 /**
0941   * @brief  Set the command configuration in interrupt mode.
0942   * @param  hospi : OSPI handle
0943   * @param  cmd   : structure that contains the command configuration information
0944   * @note   This function is used only in Indirect Read or Write Modes
0945   * @retval HAL status
0946   */
0947 HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
0948 {
0949   HAL_StatusTypeDef status;
0950   uint32_t tickstart = HAL_GetTick();
0951 
0952   /* Check the parameters of the command structure */
0953   assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
0954 
0955   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
0956   {
0957     assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
0958   }
0959 
0960   assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
0961   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
0962   {
0963     assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
0964     assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
0965   }
0966 
0967   assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
0968   if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
0969   {
0970     assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
0971     assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
0972   }
0973 
0974   assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
0975   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
0976   {
0977     assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
0978     assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
0979   }
0980 
0981   assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
0982   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
0983   {
0984     assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
0985     assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
0986     assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
0987   }
0988 
0989   assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
0990   assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
0991 
0992   /* Check the state of the driver */
0993   if ((hospi->State  == HAL_OSPI_STATE_READY) && (cmd->OperationType     == HAL_OSPI_OPTYPE_COMMON_CFG) &&
0994       (cmd->DataMode == HAL_OSPI_DATA_NONE)   && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
0995   {
0996     /* Wait till busy flag is reset */
0997     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
0998 
0999     if (status == HAL_OK)
1000     {
1001       /* Initialize error code */
1002       hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
1003 
1004       /* Clear flags related to interrupt */
1005       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1006 
1007       /* Configure the registers */
1008       status = OSPI_ConfigCmd(hospi, cmd);
1009 
1010       if (status == HAL_OK)
1011       {
1012         /* Update the state */
1013         hospi->State = HAL_OSPI_STATE_BUSY_CMD;
1014 
1015         /* Enable the transfer complete and transfer error interrupts */
1016         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
1017       }
1018     }
1019   }
1020   else
1021   {
1022     status = HAL_ERROR;
1023     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1024   }
1025 
1026   /* Return function status */
1027   return status;
1028 }
1029 
1030 /**
1031   * @brief  Configure the Hyperbus parameters.
1032   * @param  hospi   : OSPI handle
1033   * @param  cfg     : Structure containing the Hyperbus configuration
1034   * @param  Timeout : Timeout duration
1035   * @retval HAL status
1036   */
1037 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
1038 {
1039   HAL_StatusTypeDef status;
1040   uint32_t state;
1041   uint32_t tickstart = HAL_GetTick();
1042 
1043   /* Check the parameters of the hyperbus configuration structure */
1044   assert_param(IS_OSPI_RW_RECOVERY_TIME(cfg->RWRecoveryTime));
1045   assert_param(IS_OSPI_ACCESS_TIME(cfg->AccessTime));
1046   assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
1047   assert_param(IS_OSPI_LATENCY_MODE(cfg->LatencyMode));
1048 
1049   /* Check the state of the driver */
1050   state = hospi->State;
1051   if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
1052   {
1053     /* Wait till busy flag is reset */
1054     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1055 
1056     if (status == HAL_OK)
1057     {
1058       /* Configure Hyperbus configuration Latency register */
1059       WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
1060                                         (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos)     |
1061                                         cfg->WriteZeroLatency | cfg->LatencyMode));
1062 
1063       /* Update the state */
1064       hospi->State = HAL_OSPI_STATE_READY;
1065     }
1066   }
1067   else
1068   {
1069     status = HAL_ERROR;
1070     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1071   }
1072 
1073   /* Return function status */
1074   return status;
1075 }
1076 
1077 /**
1078   * @brief  Set the Hyperbus command configuration.
1079   * @param  hospi   : OSPI handle
1080   * @param  cmd     : Structure containing the Hyperbus command
1081   * @param  Timeout : Timeout duration
1082   * @retval HAL status
1083   */
1084 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
1085 {
1086   HAL_StatusTypeDef status;
1087   uint32_t tickstart = HAL_GetTick();
1088 
1089   /* Check the parameters of the hyperbus command structure */
1090   assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
1091   assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
1092   assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
1093   assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
1094 
1095   /* Check the state of the driver */
1096   if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
1097   {
1098     /* Wait till busy flag is reset */
1099     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1100 
1101     if (status == HAL_OK)
1102     {
1103       /* Re-initialize the value of the functional mode */
1104       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
1105 
1106       /* Configure the address space in the DCR1 register */
1107       MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
1108 
1109       /* Configure the CCR and WCCR registers with the address size and the following configuration :
1110          - DQS signal enabled (used as RWDS)
1111          - DTR mode enabled on address and data
1112          - address and data on 8 lines */
1113       WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
1114                                        cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
1115       WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
1116                                         cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
1117 
1118       /* Configure the DLR register with the number of data */
1119       WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
1120 
1121       /* Configure the AR register with the address value */
1122       WRITE_REG(hospi->Instance->AR, cmd->Address);
1123 
1124       /* Update the state */
1125       hospi->State = HAL_OSPI_STATE_CMD_CFG;
1126     }
1127   }
1128   else
1129   {
1130     status = HAL_ERROR;
1131     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1132   }
1133 
1134   /* Return function status */
1135   return status;
1136 }
1137 
1138 /**
1139   * @brief  Transmit an amount of data in blocking mode.
1140   * @param  hospi   : OSPI handle
1141   * @param  pData   : pointer to data buffer
1142   * @param  Timeout : Timeout duration
1143   * @note   This function is used only in Indirect Write Mode
1144   * @retval HAL status
1145   */
1146 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1147 {
1148   HAL_StatusTypeDef status;
1149   uint32_t tickstart = HAL_GetTick();
1150   __IO uint32_t *data_reg = &hospi->Instance->DR;
1151 
1152   /* Check the data pointer allocation */
1153   if (pData == NULL)
1154   {
1155     status = HAL_ERROR;
1156     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1157   }
1158   else
1159   {
1160     /* Check the state */
1161     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1162     {
1163       /* Configure counters and size */
1164       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1165       hospi->XferSize  = hospi->XferCount;
1166       hospi->pBuffPtr  = pData;
1167 
1168       /* Configure CR register with functional mode as indirect write */
1169       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1170 
1171       do
1172       {
1173         /* Wait till fifo threshold flag is set to send data */
1174         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
1175 
1176         if (status != HAL_OK)
1177         {
1178           break;
1179         }
1180 
1181         *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
1182         hospi->pBuffPtr++;
1183         hospi->XferCount--;
1184       } while (hospi->XferCount > 0U);
1185 
1186       if (status == HAL_OK)
1187       {
1188         /* Wait till transfer complete flag is set to go back in idle state */
1189         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1190 
1191         if (status == HAL_OK)
1192         {
1193           /* Clear transfer complete flag */
1194           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1195 
1196           /* Update state */
1197           hospi->State = HAL_OSPI_STATE_READY;
1198         }
1199       }
1200     }
1201     else
1202     {
1203       status = HAL_ERROR;
1204       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1205     }
1206   }
1207 
1208   /* Return function status */
1209   return status;
1210 }
1211 
1212 /**
1213   * @brief  Receive an amount of data in blocking mode.
1214   * @param  hospi   : OSPI handle
1215   * @param  pData   : pointer to data buffer
1216   * @param  Timeout : Timeout duration
1217   * @note   This function is used only in Indirect Read Mode
1218   * @retval HAL status
1219   */
1220 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1221 {
1222   HAL_StatusTypeDef status;
1223   uint32_t tickstart = HAL_GetTick();
1224   __IO uint32_t *data_reg = &hospi->Instance->DR;
1225   uint32_t addr_reg = hospi->Instance->AR;
1226   uint32_t ir_reg = hospi->Instance->IR;
1227 
1228   /* Check the data pointer allocation */
1229   if (pData == NULL)
1230   {
1231     status = HAL_ERROR;
1232     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1233   }
1234   else
1235   {
1236     /* Check the state */
1237     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1238     {
1239       /* Configure counters and size */
1240       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1241       hospi->XferSize  = hospi->XferCount;
1242       hospi->pBuffPtr  = pData;
1243 
1244       /* Configure CR register with functional mode as indirect read */
1245       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1246 
1247       /* Trig the transfer by re-writing address or instruction register */
1248       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1249       {
1250         WRITE_REG(hospi->Instance->AR, addr_reg);
1251       }
1252       else
1253       {
1254         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1255         {
1256           WRITE_REG(hospi->Instance->AR, addr_reg);
1257         }
1258         else
1259         {
1260           WRITE_REG(hospi->Instance->IR, ir_reg);
1261         }
1262       }
1263 
1264       do
1265       {
1266         /* Wait till fifo threshold or transfer complete flags are set to read received data */
1267         status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
1268 
1269         if (status != HAL_OK)
1270         {
1271           break;
1272         }
1273 
1274         *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
1275         hospi->pBuffPtr++;
1276         hospi->XferCount--;
1277       } while (hospi->XferCount > 0U);
1278 
1279       if (status == HAL_OK)
1280       {
1281         /* Wait till transfer complete flag is set to go back in idle state */
1282         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1283 
1284         if (status == HAL_OK)
1285         {
1286           /* Clear transfer complete flag */
1287           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1288 
1289           /* Update state */
1290           hospi->State = HAL_OSPI_STATE_READY;
1291         }
1292       }
1293     }
1294     else
1295     {
1296       status = HAL_ERROR;
1297       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1298     }
1299   }
1300 
1301   /* Return function status */
1302   return status;
1303 }
1304 
1305 /**
1306   * @brief  Send an amount of data in non-blocking mode with interrupt.
1307   * @param  hospi : OSPI handle
1308   * @param  pData : pointer to data buffer
1309   * @note   This function is used only in Indirect Write Mode
1310   * @retval HAL status
1311   */
1312 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1313 {
1314   HAL_StatusTypeDef status = HAL_OK;
1315 
1316   /* Check the data pointer allocation */
1317   if (pData == NULL)
1318   {
1319     status = HAL_ERROR;
1320     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1321   }
1322   else
1323   {
1324     /* Check the state */
1325     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1326     {
1327       /* Configure counters and size */
1328       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1329       hospi->XferSize  = hospi->XferCount;
1330       hospi->pBuffPtr  = pData;
1331 
1332       /* Configure CR register with functional mode as indirect write */
1333       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1334 
1335       /* Clear flags related to interrupt */
1336       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1337 
1338       /* Update the state */
1339       hospi->State = HAL_OSPI_STATE_BUSY_TX;
1340 
1341       /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1342       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1343     }
1344     else
1345     {
1346       status = HAL_ERROR;
1347       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1348     }
1349   }
1350 
1351   /* Return function status */
1352   return status;
1353 }
1354 
1355 /**
1356   * @brief  Receive an amount of data in non-blocking mode with interrupt.
1357   * @param  hospi : OSPI handle
1358   * @param  pData : pointer to data buffer
1359   * @note   This function is used only in Indirect Read Mode
1360   * @retval HAL status
1361   */
1362 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1363 {
1364   HAL_StatusTypeDef status = HAL_OK;
1365   uint32_t addr_reg = hospi->Instance->AR;
1366   uint32_t ir_reg = hospi->Instance->IR;
1367 
1368   /* Check the data pointer allocation */
1369   if (pData == NULL)
1370   {
1371     status = HAL_ERROR;
1372     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1373   }
1374   else
1375   {
1376     /* Check the state */
1377     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1378     {
1379       /* Configure counters and size */
1380       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1381       hospi->XferSize  = hospi->XferCount;
1382       hospi->pBuffPtr  = pData;
1383 
1384       /* Configure CR register with functional mode as indirect read */
1385       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1386 
1387       /* Clear flags related to interrupt */
1388       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1389 
1390       /* Update the state */
1391       hospi->State = HAL_OSPI_STATE_BUSY_RX;
1392 
1393       /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1394       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1395 
1396       /* Trig the transfer by re-writing address or instruction register */
1397       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1398       {
1399         WRITE_REG(hospi->Instance->AR, addr_reg);
1400       }
1401       else
1402       {
1403         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1404         {
1405           WRITE_REG(hospi->Instance->AR, addr_reg);
1406         }
1407         else
1408         {
1409           WRITE_REG(hospi->Instance->IR, ir_reg);
1410         }
1411       }
1412     }
1413     else
1414     {
1415       status = HAL_ERROR;
1416       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1417     }
1418   }
1419 
1420   /* Return function status */
1421   return status;
1422 }
1423 
1424 /**
1425   * @brief  Send an amount of data in non-blocking mode with DMA.
1426   * @param  hospi : OSPI handle
1427   * @param  pData : pointer to data buffer
1428   * @note   This function is used only in Indirect Write Mode
1429   * @note   If DMA peripheral access is configured as halfword, the number
1430   *         of data and the fifo threshold should be aligned on halfword
1431   * @note   If DMA peripheral access is configured as word, the number
1432   *         of data and the fifo threshold should be aligned on word
1433   * @retval HAL status
1434   */
1435 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1436 {
1437   HAL_StatusTypeDef status = HAL_OK;
1438   uint32_t data_size = hospi->Instance->DLR + 1U;
1439 
1440   /* Check the data pointer allocation */
1441   if (pData == NULL)
1442   {
1443     status = HAL_ERROR;
1444     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1445   }
1446   else
1447   {
1448     /* Check the state */
1449     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1450     {
1451       hospi->XferCount = data_size;
1452 
1453       {
1454         hospi->XferSize = hospi->XferCount;
1455         hospi->pBuffPtr = pData;
1456 
1457         /* Configure CR register with functional mode as indirect write */
1458         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1459 
1460         /* Clear flags related to interrupt */
1461         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1462 
1463         /* Update the state */
1464         hospi->State = HAL_OSPI_STATE_BUSY_TX;
1465 
1466         /* Set the MDMA transfer complete callback */
1467         hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1468 
1469         /* Set the MDMA error callback */
1470         hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1471 
1472         /* Clear the MDMA abort callback */
1473         hospi->hmdma->XferAbortCallback = NULL;
1474 
1475         /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment
1476            to disable */
1477         MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_DISABLE);
1478 
1479         /* Update MDMA configuration with the correct SourceInc field for Write operation */
1480         if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
1481         {
1482           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_BYTE);
1483         }
1484         else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
1485         {
1486           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_HALFWORD);
1487         }
1488         else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
1489         {
1490           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_WORD);
1491         }
1492         else
1493         {
1494           /* in case of incorrect source data size */
1495           hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1496           status = HAL_ERROR;
1497         }
1498 
1499         /* Enable the transmit MDMA Channel */
1500         if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize, 1) == \
1501             HAL_OK)
1502         {
1503           /* Enable the transfer error interrupt */
1504           __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1505 
1506           /* Enable the DMA transfer by setting the DMAEN bit  */
1507           SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1508         }
1509         else
1510         {
1511           status = HAL_ERROR;
1512           hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1513           hospi->State = HAL_OSPI_STATE_READY;
1514         }
1515       }
1516     }
1517     else
1518     {
1519       status = HAL_ERROR;
1520       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1521     }
1522   }
1523 
1524   /* Return function status */
1525   return status;
1526 }
1527 
1528 /**
1529   * @brief  Receive an amount of data in non-blocking mode with DMA.
1530   * @param  hospi : OSPI handle
1531   * @param  pData : pointer to data buffer.
1532   * @note   This function is used only in Indirect Read Mode
1533   * @note   If DMA peripheral access is configured as halfword, the number
1534   *         of data and the fifo threshold should be aligned on halfword
1535   * @note   If DMA peripheral access is configured as word, the number
1536   *         of data and the fifo threshold should be aligned on word
1537   * @retval HAL status
1538   */
1539 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1540 {
1541   HAL_StatusTypeDef status = HAL_OK;
1542   uint32_t data_size = hospi->Instance->DLR + 1U;
1543   uint32_t addr_reg = hospi->Instance->AR;
1544   uint32_t ir_reg = hospi->Instance->IR;
1545   /* Check the data pointer allocation */
1546   if (pData == NULL)
1547   {
1548     status = HAL_ERROR;
1549     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1550   }
1551   else
1552   {
1553     /* Check the state */
1554     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1555     {
1556       hospi->XferCount = data_size;
1557 
1558       {
1559         hospi->XferSize  = hospi->XferCount;
1560         hospi->pBuffPtr  = pData;
1561 
1562         /* Configure CR register with functional mode as indirect read */
1563         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1564 
1565         /* Clear flags related to interrupt */
1566         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1567 
1568         /* Update the state */
1569         hospi->State = HAL_OSPI_STATE_BUSY_RX;
1570 
1571         /* Set the DMA transfer complete callback */
1572         hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1573 
1574         /* Set the DMA error callback */
1575         hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1576 
1577         /* Clear the DMA abort callback */
1578         hospi->hmdma->XferAbortCallback = NULL;
1579 
1580         /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
1581         MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS), MDMA_SRC_INC_DISABLE);
1582 
1583         /* Update MDMA configuration with the correct DestinationInc field for read operation */
1584         if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
1585         {
1586           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_BYTE);
1587         }
1588         else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
1589         {
1590           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_HALFWORD);
1591         }
1592         else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
1593         {
1594           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS), MDMA_DEST_INC_WORD);
1595         }
1596         else
1597         {
1598           /* in case of incorrect destination data size */
1599           hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1600           status = HAL_ERROR;
1601         }
1602 
1603         /* Enable the transmit MDMA Channel */
1604         if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize, 1) == \
1605             HAL_OK)
1606         {
1607           /* Enable the transfer error interrupt */
1608           __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1609 
1610           /* Trig the transfer by re-writing address or instruction register */
1611           if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1612           {
1613             WRITE_REG(hospi->Instance->AR, addr_reg);
1614           }
1615           else
1616           {
1617             if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1618             {
1619               WRITE_REG(hospi->Instance->AR, addr_reg);
1620             }
1621             else
1622             {
1623               WRITE_REG(hospi->Instance->IR, ir_reg);
1624             }
1625           }
1626 
1627           /* Enable the DMA transfer by setting the DMAEN bit  */
1628           SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1629         }
1630         else
1631         {
1632           status = HAL_ERROR;
1633           hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1634           hospi->State = HAL_OSPI_STATE_READY;
1635         }
1636       }
1637     }
1638     else
1639     {
1640       status = HAL_ERROR;
1641       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1642     }
1643   }
1644 
1645   /* Return function status */
1646   return status;
1647 }
1648 
1649 /**
1650   * @brief  Configure the OSPI Automatic Polling Mode in blocking mode.
1651   * @param  hospi   : OSPI handle
1652   * @param  cfg     : structure that contains the polling configuration information.
1653   * @param  Timeout : Timeout duration
1654   * @note   This function is used only in Automatic Polling Mode
1655   * @retval HAL status
1656   */
1657 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1658 {
1659   HAL_StatusTypeDef status;
1660   uint32_t tickstart = HAL_GetTick();
1661   uint32_t addr_reg = hospi->Instance->AR;
1662   uint32_t ir_reg = hospi->Instance->IR;
1663 #ifdef USE_FULL_ASSERT
1664   uint32_t dlr_reg = hospi->Instance->DLR;
1665 #endif /* USE_FULL_ASSERT */
1666 
1667   /* Check the parameters of the autopolling configuration structure */
1668   assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
1669   assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1670   assert_param(IS_OSPI_INTERVAL(cfg->Interval));
1671   assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1672 
1673   /* Check the state */
1674   if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
1675   {
1676     /* Wait till busy flag is reset */
1677     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1678 
1679     if (status == HAL_OK)
1680     {
1681       /* Configure registers */
1682       WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
1683       WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
1684       WRITE_REG(hospi->Instance->PIR,   cfg->Interval);
1685       MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1686                  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1687 
1688       /* Trig the transfer by re-writing address or instruction register */
1689       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1690       {
1691         WRITE_REG(hospi->Instance->AR, addr_reg);
1692       }
1693       else
1694       {
1695         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1696         {
1697           WRITE_REG(hospi->Instance->AR, addr_reg);
1698         }
1699         else
1700         {
1701           WRITE_REG(hospi->Instance->IR, ir_reg);
1702         }
1703       }
1704 
1705       /* Wait till status match flag is set to go back in idle state */
1706       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
1707 
1708       if (status == HAL_OK)
1709       {
1710         /* Clear status match flag */
1711         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
1712 
1713         /* Update state */
1714         hospi->State = HAL_OSPI_STATE_READY;
1715       }
1716     }
1717   }
1718   else
1719   {
1720     status = HAL_ERROR;
1721     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1722   }
1723 
1724   /* Return function status */
1725   return status;
1726 }
1727 
1728 /**
1729   * @brief  Configure the OSPI Automatic Polling Mode in non-blocking mode.
1730   * @param  hospi : OSPI handle
1731   * @param  cfg   : structure that contains the polling configuration information.
1732   * @note   This function is used only in Automatic Polling Mode
1733   * @retval HAL status
1734   */
1735 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
1736 {
1737   HAL_StatusTypeDef status;
1738   uint32_t tickstart = HAL_GetTick();
1739   uint32_t addr_reg = hospi->Instance->AR;
1740   uint32_t ir_reg = hospi->Instance->IR;
1741 #ifdef USE_FULL_ASSERT
1742   uint32_t dlr_reg = hospi->Instance->DLR;
1743 #endif /* USE_FULL_ASSERT */
1744 
1745   /* Check the parameters of the autopolling configuration structure */
1746   assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
1747   assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1748   assert_param(IS_OSPI_INTERVAL(cfg->Interval));
1749   assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1750 
1751   /* Check the state */
1752   if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1753   {
1754     /* Wait till busy flag is reset */
1755     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1756 
1757     if (status == HAL_OK)
1758     {
1759       /* Configure registers */
1760       WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
1761       WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
1762       WRITE_REG(hospi->Instance->PIR,   cfg->Interval);
1763       MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1764                  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1765 
1766       /* Clear flags related to interrupt */
1767       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
1768 
1769       /* Update state */
1770       hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
1771 
1772       /* Enable the status match and transfer error interrupts */
1773       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
1774 
1775       /* Trig the transfer by re-writing address or instruction register */
1776       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1777       {
1778         WRITE_REG(hospi->Instance->AR, addr_reg);
1779       }
1780       else
1781       {
1782         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1783         {
1784           WRITE_REG(hospi->Instance->AR, addr_reg);
1785         }
1786         else
1787         {
1788           WRITE_REG(hospi->Instance->IR, ir_reg);
1789         }
1790       }
1791     }
1792   }
1793   else
1794   {
1795     status = HAL_ERROR;
1796     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1797   }
1798 
1799   /* Return function status */
1800   return status;
1801 }
1802 
1803 /**
1804   * @brief  Configure the Memory Mapped mode.
1805   * @param  hospi : OSPI handle
1806   * @param  cfg   : structure that contains the memory mapped configuration information.
1807   * @note   This function is used only in Memory mapped Mode
1808   * @retval HAL status
1809   */
1810 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
1811 {
1812   HAL_StatusTypeDef status;
1813   uint32_t tickstart = HAL_GetTick();
1814 
1815   /* Check the parameters of the memory-mapped configuration structure */
1816   assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1817 
1818   /* Check the state */
1819   if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1820   {
1821     /* Wait till busy flag is reset */
1822     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1823 
1824     if (status == HAL_OK)
1825     {
1826       /* Update state */
1827       hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
1828 
1829       if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
1830       {
1831         assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1832 
1833         /* Configure register */
1834         WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
1835 
1836         /* Clear flags related to interrupt */
1837         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
1838 
1839         /* Enable the timeout interrupt */
1840         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
1841       }
1842 
1843       /* Configure CR register with functional mode as memory-mapped */
1844       MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
1845                  (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1846     }
1847   }
1848   else
1849   {
1850     status = HAL_ERROR;
1851     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1852   }
1853 
1854   /* Return function status */
1855   return status;
1856 }
1857 
1858 /**
1859   * @brief  Transfer Error callback.
1860   * @param  hospi : OSPI handle
1861   * @retval None
1862   */
1863 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
1864 {
1865   /* Prevent unused argument(s) compilation warning */
1866   UNUSED(hospi);
1867 
1868   /* NOTE : This function should not be modified, when the callback is needed,
1869             the HAL_OSPI_ErrorCallback could be implemented in the user file
1870    */
1871 }
1872 
1873 /**
1874   * @brief  Abort completed callback.
1875   * @param  hospi : OSPI handle
1876   * @retval None
1877   */
1878 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
1879 {
1880   /* Prevent unused argument(s) compilation warning */
1881   UNUSED(hospi);
1882 
1883   /* NOTE: This function should not be modified, when the callback is needed,
1884            the HAL_OSPI_AbortCpltCallback could be implemented in the user file
1885    */
1886 }
1887 
1888 /**
1889   * @brief  FIFO Threshold callback.
1890   * @param  hospi : OSPI handle
1891   * @retval None
1892   */
1893 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
1894 {
1895   /* Prevent unused argument(s) compilation warning */
1896   UNUSED(hospi);
1897 
1898   /* NOTE : This function should not be modified, when the callback is needed,
1899             the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
1900    */
1901 }
1902 
1903 /**
1904   * @brief  Command completed callback.
1905   * @param  hospi : OSPI handle
1906   * @retval None
1907   */
1908 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
1909 {
1910   /* Prevent unused argument(s) compilation warning */
1911   UNUSED(hospi);
1912 
1913   /* NOTE: This function should not be modified, when the callback is needed,
1914            the HAL_OSPI_CmdCpltCallback could be implemented in the user file
1915    */
1916 }
1917 
1918 /**
1919   * @brief  Rx Transfer completed callback.
1920   * @param  hospi : OSPI handle
1921   * @retval None
1922   */
1923 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
1924 {
1925   /* Prevent unused argument(s) compilation warning */
1926   UNUSED(hospi);
1927 
1928   /* NOTE: This function should not be modified, when the callback is needed,
1929            the HAL_OSPI_RxCpltCallback could be implemented in the user file
1930    */
1931 }
1932 
1933 /**
1934   * @brief  Tx Transfer completed callback.
1935   * @param  hospi : OSPI handle
1936   * @retval None
1937   */
1938 __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
1939 {
1940   /* Prevent unused argument(s) compilation warning */
1941   UNUSED(hospi);
1942 
1943   /* NOTE: This function should not be modified, when the callback is needed,
1944            the HAL_OSPI_TxCpltCallback could be implemented in the user file
1945    */
1946 }
1947 
1948 /**
1949   * @brief  Rx Half Transfer completed callback.
1950   * @param  hospi : OSPI handle
1951   * @retval None
1952   */
1953 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1954 {
1955   /* Prevent unused argument(s) compilation warning */
1956   UNUSED(hospi);
1957 
1958   /* NOTE: This function should not be modified, when the callback is needed,
1959            the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
1960    */
1961 }
1962 
1963 /**
1964   * @brief  Tx Half Transfer completed callback.
1965   * @param  hospi : OSPI handle
1966   * @retval None
1967   */
1968 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1969 {
1970   /* Prevent unused argument(s) compilation warning */
1971   UNUSED(hospi);
1972 
1973   /* NOTE: This function should not be modified, when the callback is needed,
1974            the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
1975    */
1976 }
1977 
1978 /**
1979   * @brief  Status Match callback.
1980   * @param  hospi : OSPI handle
1981   * @retval None
1982   */
1983 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
1984 {
1985   /* Prevent unused argument(s) compilation warning */
1986   UNUSED(hospi);
1987 
1988   /* NOTE : This function should not be modified, when the callback is needed,
1989             the HAL_OSPI_StatusMatchCallback could be implemented in the user file
1990    */
1991 }
1992 
1993 /**
1994   * @brief  Timeout callback.
1995   * @param  hospi : OSPI handle
1996   * @retval None
1997   */
1998 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
1999 {
2000   /* Prevent unused argument(s) compilation warning */
2001   UNUSED(hospi);
2002 
2003   /* NOTE : This function should not be modified, when the callback is needed,
2004             the HAL_OSPI_TimeOutCallback could be implemented in the user file
2005    */
2006 }
2007 
2008 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2009 /**
2010   * @brief  Register a User OSPI Callback
2011   *         To be used to override the weak predefined callback
2012   * @param hospi : OSPI handle
2013   * @param CallbackID : ID of the callback to be registered
2014   *        This parameter can be one of the following values:
2015   *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
2016   *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
2017   *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2018   *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
2019   *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
2020   *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
2021   *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
2022   *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
2023   *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
2024   *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
2025   *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
2026   *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
2027   * @param pCallback : pointer to the Callback function
2028   * @retval status
2029   */
2030 HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID,
2031                                             pOSPI_CallbackTypeDef pCallback)
2032 {
2033   HAL_StatusTypeDef status = HAL_OK;
2034 
2035   if (pCallback == NULL)
2036   {
2037     /* Update the error code */
2038     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2039     return HAL_ERROR;
2040   }
2041 
2042   if (hospi->State == HAL_OSPI_STATE_READY)
2043   {
2044     switch (CallbackID)
2045     {
2046       case  HAL_OSPI_ERROR_CB_ID :
2047         hospi->ErrorCallback = pCallback;
2048         break;
2049       case HAL_OSPI_ABORT_CB_ID :
2050         hospi->AbortCpltCallback = pCallback;
2051         break;
2052       case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2053         hospi->FifoThresholdCallback = pCallback;
2054         break;
2055       case HAL_OSPI_CMD_CPLT_CB_ID :
2056         hospi->CmdCpltCallback = pCallback;
2057         break;
2058       case HAL_OSPI_RX_CPLT_CB_ID :
2059         hospi->RxCpltCallback = pCallback;
2060         break;
2061       case HAL_OSPI_TX_CPLT_CB_ID :
2062         hospi->TxCpltCallback = pCallback;
2063         break;
2064       case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2065         hospi->RxHalfCpltCallback = pCallback;
2066         break;
2067       case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2068         hospi->TxHalfCpltCallback = pCallback;
2069         break;
2070       case HAL_OSPI_STATUS_MATCH_CB_ID :
2071         hospi->StatusMatchCallback = pCallback;
2072         break;
2073       case HAL_OSPI_TIMEOUT_CB_ID :
2074         hospi->TimeOutCallback = pCallback;
2075         break;
2076       case HAL_OSPI_MSP_INIT_CB_ID :
2077         hospi->MspInitCallback = pCallback;
2078         break;
2079       case HAL_OSPI_MSP_DEINIT_CB_ID :
2080         hospi->MspDeInitCallback = pCallback;
2081         break;
2082       default :
2083         /* Update the error code */
2084         hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2085         /* update return status */
2086         status =  HAL_ERROR;
2087         break;
2088     }
2089   }
2090   else if (hospi->State == HAL_OSPI_STATE_RESET)
2091   {
2092     switch (CallbackID)
2093     {
2094       case HAL_OSPI_MSP_INIT_CB_ID :
2095         hospi->MspInitCallback = pCallback;
2096         break;
2097       case HAL_OSPI_MSP_DEINIT_CB_ID :
2098         hospi->MspDeInitCallback = pCallback;
2099         break;
2100       default :
2101         /* Update the error code */
2102         hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2103         /* update return status */
2104         status =  HAL_ERROR;
2105         break;
2106     }
2107   }
2108   else
2109   {
2110     /* Update the error code */
2111     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2112     /* update return status */
2113     status =  HAL_ERROR;
2114   }
2115 
2116   return status;
2117 }
2118 
2119 /**
2120   * @brief  Unregister a User OSPI Callback
2121   *         OSPI Callback is redirected to the weak predefined callback
2122   * @param hospi : OSPI handle
2123   * @param CallbackID : ID of the callback to be unregistered
2124   *        This parameter can be one of the following values:
2125   *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
2126   *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
2127   *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2128   *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
2129   *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
2130   *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
2131   *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
2132   *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
2133   *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
2134   *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
2135   *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
2136   *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
2137   * @retval status
2138   */
2139 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
2140 {
2141   HAL_StatusTypeDef status = HAL_OK;
2142 
2143   if (hospi->State == HAL_OSPI_STATE_READY)
2144   {
2145     switch (CallbackID)
2146     {
2147       case  HAL_OSPI_ERROR_CB_ID :
2148         hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
2149         break;
2150       case HAL_OSPI_ABORT_CB_ID :
2151         hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
2152         break;
2153       case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2154         hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
2155         break;
2156       case HAL_OSPI_CMD_CPLT_CB_ID :
2157         hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
2158         break;
2159       case HAL_OSPI_RX_CPLT_CB_ID :
2160         hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
2161         break;
2162       case HAL_OSPI_TX_CPLT_CB_ID :
2163         hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
2164         break;
2165       case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2166         hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
2167         break;
2168       case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2169         hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
2170         break;
2171       case HAL_OSPI_STATUS_MATCH_CB_ID :
2172         hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
2173         break;
2174       case HAL_OSPI_TIMEOUT_CB_ID :
2175         hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
2176         break;
2177       case HAL_OSPI_MSP_INIT_CB_ID :
2178         hospi->MspInitCallback = HAL_OSPI_MspInit;
2179         break;
2180       case HAL_OSPI_MSP_DEINIT_CB_ID :
2181         hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2182         break;
2183       default :
2184         /* Update the error code */
2185         hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2186         /* update return status */
2187         status =  HAL_ERROR;
2188         break;
2189     }
2190   }
2191   else if (hospi->State == HAL_OSPI_STATE_RESET)
2192   {
2193     switch (CallbackID)
2194     {
2195       case HAL_OSPI_MSP_INIT_CB_ID :
2196         hospi->MspInitCallback = HAL_OSPI_MspInit;
2197         break;
2198       case HAL_OSPI_MSP_DEINIT_CB_ID :
2199         hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2200         break;
2201       default :
2202         /* Update the error code */
2203         hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2204         /* update return status */
2205         status =  HAL_ERROR;
2206         break;
2207     }
2208   }
2209   else
2210   {
2211     /* Update the error code */
2212     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2213     /* update return status */
2214     status =  HAL_ERROR;
2215   }
2216 
2217   return status;
2218 }
2219 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2220 
2221 /**
2222   * @}
2223   */
2224 
2225 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
2226   * @ingroup RTEMSBSPsARMSTM32H7
2227   *  @brief   OSPI control and State functions
2228   *
2229 @verbatim
2230  ===============================================================================
2231                   ##### Peripheral Control and State functions #####
2232  ===============================================================================
2233     [..]
2234     This subsection provides a set of functions allowing to :
2235       (+) Check in run-time the state of the driver.
2236       (+) Check the error code set during last operation.
2237       (+) Abort any operation.
2238       (+) Manage the Fifo threshold.
2239       (+) Configure the timeout duration used in the driver.
2240 
2241 @endverbatim
2242   * @{
2243   */
2244 
2245 /**
2246   * @brief  Abort the current transmission.
2247   * @param  hospi : OSPI handle
2248   * @retval HAL status
2249   */
2250 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
2251 {
2252   HAL_StatusTypeDef status = HAL_OK;
2253   uint32_t state;
2254   uint32_t tickstart = HAL_GetTick();
2255 
2256   /* Check if the state is in one of the busy or configured states */
2257   state = hospi->State;
2258   if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2259   {
2260     /* Check if the DMA is enabled */
2261     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2262     {
2263       /* Disable the DMA transfer on the OctoSPI side */
2264       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2265 
2266       /* Disable the DMA transfer on the DMA side */
2267       status = HAL_MDMA_Abort(hospi->hmdma);
2268       if (status != HAL_OK)
2269       {
2270         hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2271       }
2272     }
2273 
2274     if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2275     {
2276       /* Perform an abort of the OctoSPI */
2277       SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2278 
2279       /* Wait until the transfer complete flag is set to go back in idle state */
2280       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
2281 
2282       if (status == HAL_OK)
2283       {
2284         /* Clear transfer complete flag */
2285         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2286 
2287         /* Wait until the busy flag is reset to go back in idle state */
2288         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
2289 
2290         if (status == HAL_OK)
2291         {
2292           /* Update state */
2293           hospi->State = HAL_OSPI_STATE_READY;
2294         }
2295       }
2296     }
2297     else
2298     {
2299       /* Update state */
2300       hospi->State = HAL_OSPI_STATE_READY;
2301     }
2302   }
2303   else
2304   {
2305     status = HAL_ERROR;
2306     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2307   }
2308 
2309   /* Return function status */
2310   return status;
2311 }
2312 
2313 /**
2314   * @brief  Abort the current transmission (non-blocking function)
2315   * @param  hospi : OSPI handle
2316   * @retval HAL status
2317   */
2318 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
2319 {
2320   HAL_StatusTypeDef status = HAL_OK;
2321   uint32_t state;
2322 
2323   /* Check if the state is in one of the busy or configured states */
2324   state = hospi->State;
2325   if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2326   {
2327     /* Disable all interrupts */
2328     __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));
2329 
2330     /* Update state */
2331     hospi->State = HAL_OSPI_STATE_ABORT;
2332 
2333     /* Check if the DMA is enabled */
2334     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2335     {
2336       /* Disable the DMA transfer on the OctoSPI side */
2337       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2338 
2339       /* Disable the DMA transfer on the DMA side */
2340       hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
2341       if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
2342       {
2343         /* Update state */
2344         hospi->State = HAL_OSPI_STATE_READY;
2345 
2346         /* Abort callback */
2347 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2348         hospi->AbortCpltCallback(hospi);
2349 #else
2350         HAL_OSPI_AbortCpltCallback(hospi);
2351 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
2352       }
2353     }
2354     else
2355     {
2356       if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2357       {
2358         /* Clear transfer complete flag */
2359         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2360 
2361         /* Enable the transfer complete interrupts */
2362         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2363 
2364         /* Perform an abort of the OctoSPI */
2365         SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2366       }
2367       else
2368       {
2369         /* Update state */
2370         hospi->State = HAL_OSPI_STATE_READY;
2371 
2372         /* Abort callback */
2373 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2374         hospi->AbortCpltCallback(hospi);
2375 #else
2376         HAL_OSPI_AbortCpltCallback(hospi);
2377 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2378       }
2379     }
2380   }
2381   else
2382   {
2383     status = HAL_ERROR;
2384     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2385   }
2386 
2387   /* Return function status */
2388   return status;
2389 }
2390 
2391 /** @brief  Set OSPI Fifo threshold.
2392   * @param  hospi     : OSPI handle.
2393   * @param  Threshold : Threshold of the Fifo.
2394   * @retval HAL status
2395   */
2396 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
2397 {
2398   HAL_StatusTypeDef status = HAL_OK;
2399 
2400   /* Check the state */
2401   if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
2402   {
2403     /* Synchronize initialization structure with the new fifo threshold value */
2404     hospi->Init.FifoThreshold = Threshold;
2405 
2406     /* Configure new fifo threshold */
2407     MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
2408 
2409   }
2410   else
2411   {
2412     status = HAL_ERROR;
2413     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2414   }
2415 
2416   /* Return function status */
2417   return status;
2418 }
2419 
2420 /** @brief  Get OSPI Fifo threshold.
2421   * @param  hospi : OSPI handle.
2422   * @retval Fifo threshold
2423   */
2424 uint32_t HAL_OSPI_GetFifoThreshold(const OSPI_HandleTypeDef *hospi)
2425 {
2426   return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
2427 }
2428 
2429 /** @brief Set OSPI timeout.
2430   * @param  hospi   : OSPI handle.
2431   * @param  Timeout : Timeout for the memory access.
2432   * @retval None
2433   */
2434 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
2435 {
2436   hospi->Timeout = Timeout;
2437   return HAL_OK;
2438 }
2439 
2440 /**
2441   * @brief  Return the OSPI error code.
2442   * @param  hospi : OSPI handle
2443   * @retval OSPI Error Code
2444   */
2445 uint32_t HAL_OSPI_GetError(const OSPI_HandleTypeDef *hospi)
2446 {
2447   return hospi->ErrorCode;
2448 }
2449 
2450 /**
2451   * @brief  Return the OSPI handle state.
2452   * @param  hospi : OSPI handle
2453   * @retval HAL state
2454   */
2455 uint32_t HAL_OSPI_GetState(const OSPI_HandleTypeDef *hospi)
2456 {
2457   /* Return OSPI handle state */
2458   return hospi->State;
2459 }
2460 
2461 /**
2462   * @}
2463   */
2464 
2465 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
2466   * @ingroup RTEMSBSPsARMSTM32H7
2467   *  @brief   OSPI IO Manager configuration function
2468   *
2469 @verbatim
2470  ===============================================================================
2471                   ##### IO Manager configuration function #####
2472  ===============================================================================
2473     [..]
2474     This subsection provides a set of functions allowing to :
2475       (+) Configure the IO manager.
2476 
2477 @endverbatim
2478   * @{
2479   */
2480 
2481 /**
2482   * @brief  Configure the OctoSPI IO manager.
2483   * @param  hospi   : OSPI handle
2484   * @param  cfg     : Configuration of the IO Manager for the instance
2485   * @param  Timeout : Timeout duration
2486   * @retval HAL status
2487   */
2488 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
2489 {
2490   HAL_StatusTypeDef status = HAL_OK;
2491   uint32_t instance;
2492   uint8_t index;
2493   uint8_t ospi_enabled = 0U;
2494   uint8_t other_instance;
2495   OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2496 
2497   /* Prevent unused argument(s) compilation warning */
2498   UNUSED(Timeout);
2499 
2500   /* Check the parameters of the OctoSPI IO Manager configuration structure */
2501   assert_param(IS_OSPIM_PORT(cfg->ClkPort));
2502   assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
2503   assert_param(IS_OSPIM_PORT(cfg->NCSPort));
2504   assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
2505   assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
2506   assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime));
2507 
2508   if (hospi->Instance == OCTOSPI1)
2509   {
2510     instance = 0U;
2511     other_instance = 1U;
2512   }
2513   else
2514   {
2515     instance = 1U;
2516     other_instance = 0U;
2517   }
2518 
2519   /**************** Get current configuration of the instances ****************/
2520   for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2521   {
2522     if (OSPIM_GetConfig(index + 1U, &(IOM_cfg[index])) != HAL_OK)
2523     {
2524       status = HAL_ERROR;
2525       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2526     }
2527   }
2528 
2529   if (status == HAL_OK)
2530   {
2531     /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2532     if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
2533     {
2534       CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2535       ospi_enabled |= 0x1U;
2536     }
2537     if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
2538     {
2539       CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2540       ospi_enabled |= 0x2U;
2541     }
2542 
2543     /***************** Deactivation of previous configuration *****************/
2544     CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
2545     if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2546     {
2547       /* De-multiplexing should be performed */
2548       CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2549 
2550       if (other_instance == 1U)
2551       {
2552         SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
2553         if (IOM_cfg[other_instance].DQSPort != 0U)
2554         {
2555           SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
2556         }
2557         if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2558         {
2559           SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], \
2560                   OCTOSPIM_PCR_IOLSRC_1);
2561         }
2562         if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2563         {
2564           SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], \
2565                   OCTOSPIM_PCR_IOHSRC_1);
2566         }
2567       }
2568     }
2569     else
2570     {
2571       if (IOM_cfg[instance].ClkPort != 0U)
2572       {
2573         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
2574         if (IOM_cfg[instance].DQSPort != 0U)
2575         {
2576           CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
2577         }
2578         if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2579         {
2580           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2581         }
2582         if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2583         {
2584           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2585         }
2586       }
2587     }
2588 
2589     /********************* Deactivation of other instance *********************/
2590     if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort)     ||
2591         (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
2592         (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2593     {
2594       if ((cfg->ClkPort   == IOM_cfg[other_instance].ClkPort)   &&
2595           (cfg->DQSPort    == IOM_cfg[other_instance].DQSPort)  &&
2596           (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
2597           (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2598       {
2599         /* Multiplexing should be performed */
2600         SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2601       }
2602       else
2603       {
2604         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
2605         if (IOM_cfg[other_instance].DQSPort != 0U)
2606         {
2607           CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
2608         }
2609         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
2610         if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2611         {
2612           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2613                     OCTOSPIM_PCR_IOLEN);
2614         }
2615         if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2616         {
2617           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2618                     OCTOSPIM_PCR_IOHEN);
2619         }
2620       }
2621     }
2622 
2623     /******************** Activation of new configuration *********************/
2624     MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
2625                (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
2626 
2627     if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
2628     {
2629       MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
2630     }
2631 
2632     if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2633     {
2634       MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
2635       if (cfg->DQSPort != 0U)
2636       {
2637         MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
2638       }
2639 
2640       if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2641       {
2642         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2643                    (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
2644       }
2645       else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
2646       {
2647         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2648                    (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
2649       }
2650       else
2651       {
2652         /* Nothing to do */
2653       }
2654 
2655       if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2656       {
2657         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2658                    (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
2659       }
2660       else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
2661       {
2662         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2663                    (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
2664       }
2665       else
2666       {
2667         /* Nothing to do */
2668       }
2669     }
2670     else
2671     {
2672       MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
2673                  (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
2674       if (cfg->DQSPort != 0U)
2675       {
2676         MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
2677                    (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
2678       }
2679 
2680       if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2681       {
2682         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2683                    (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2684                    (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
2685       }
2686       else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
2687       {
2688         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2689                    (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2690                    (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
2691       }
2692       else
2693       {
2694         /* Nothing to do */
2695       }
2696 
2697       if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2698       {
2699         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2700                    (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2701                    (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
2702       }
2703       else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
2704       {
2705         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2706                    (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2707                    (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
2708       }
2709       else
2710       {
2711         /* Nothing to do */
2712       }
2713     }
2714 
2715     /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2716     if ((ospi_enabled & 0x1U) != 0U)
2717     {
2718       SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2719     }
2720     if ((ospi_enabled & 0x2U) != 0U)
2721     {
2722       SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2723     }
2724   }
2725 
2726   /* Return function status */
2727   return status;
2728 }
2729 
2730 /**
2731   * @}
2732   */
2733 
2734 /**
2735   @cond 0
2736   */
2737 /**
2738   * @brief  DMA OSPI process complete callback.
2739   * @param  hdma : DMA handle
2740   * @retval None
2741   */
2742 static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma)
2743 {
2744   OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
2745   hospi->XferCount = 0;
2746 
2747   /* Disable the DMA transfer on the OctoSPI side */
2748   CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2749 
2750   /* Disable the DMA channel */
2751   __HAL_MDMA_DISABLE(hmdma);
2752 
2753   /* Enable the OSPI transfer complete Interrupt */
2754   __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2755 }
2756 
2757 /**
2758   * @brief  DMA OSPI communication error callback.
2759   * @param  hdma : DMA handle
2760   * @retval None
2761   */
2762 static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2763 {
2764   OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
2765   hospi->XferCount = 0;
2766   hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2767 
2768   /* Disable the DMA transfer on the OctoSPI side */
2769   CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2770 
2771   /* Disable all interrupts */
2772   __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
2773 
2774   /* Update state */
2775   hospi->State = HAL_OSPI_STATE_ABORT;
2776 
2777   /* Disable the DMA transfer on the DMA side */
2778   hospi->hmdma->XferAbortCallback = OSPI_DMAAbortOnError;
2779   if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
2780   {
2781     /* Update state */
2782     hospi->State = HAL_OSPI_STATE_READY;
2783 
2784     /* Error callback */
2785 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2786     hospi->ErrorCallback(hospi);
2787 #else
2788     HAL_OSPI_ErrorCallback(hospi);
2789 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2790   }
2791 }
2792 
2793 /**
2794   * @brief  DMA OSPI abort complete callback.
2795   * @param  hdma : DMA handle
2796   * @retval None
2797   */
2798 static void OSPI_DMAAbortOnError(MDMA_HandleTypeDef *hmdma)
2799 {
2800   OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
2801 
2802   /* DMA abort called by OctoSPI abort */
2803   if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2804   {
2805     /* Clear transfer complete flag */
2806     __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2807 
2808     /* Enable the transfer complete interrupts */
2809     __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2810 
2811     /* Perform an abort of the OctoSPI */
2812     SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2813   }
2814   else
2815   {
2816     /* Update state */
2817     hospi->State = HAL_OSPI_STATE_READY;
2818 
2819     /* Error callback */
2820 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2821     hospi->ErrorCallback(hospi);
2822 #else
2823     HAL_OSPI_ErrorCallback(hospi);
2824 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2825   }
2826 }
2827 
2828 /**
2829   * @brief  DMA OSPI abort complete callback.
2830   * @param  hdma : DMA handle
2831   * @retval None
2832   */
2833 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2834 {
2835   OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hmdma->Parent);
2836   hospi->XferCount = 0;
2837 
2838   /* Check the state */
2839   if (hospi->State == HAL_OSPI_STATE_ABORT)
2840   {
2841     /* DMA abort called by OctoSPI abort */
2842     if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2843     {
2844       /* Clear transfer complete flag */
2845       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2846 
2847       /* Enable the transfer complete interrupts */
2848       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2849 
2850       /* Perform an abort of the OctoSPI */
2851       SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2852     }
2853     else
2854     {
2855       /* Update state */
2856       hospi->State = HAL_OSPI_STATE_READY;
2857 
2858       /* Abort callback */
2859 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2860       hospi->AbortCpltCallback(hospi);
2861 #else
2862       HAL_OSPI_AbortCpltCallback(hospi);
2863 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2864     }
2865   }
2866   else
2867   {
2868     /* DMA abort called due to a transfer error interrupt */
2869     /* Update state */
2870     hospi->State = HAL_OSPI_STATE_READY;
2871 
2872     /* Error callback */
2873 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2874     hospi->ErrorCallback(hospi);
2875 #else
2876     HAL_OSPI_ErrorCallback(hospi);
2877 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
2878   }
2879 }
2880 
2881 /**
2882   * @brief  Wait for a flag state until timeout.
2883   * @param  hospi     : OSPI handle
2884   * @param  Flag      : Flag checked
2885   * @param  State     : Value of the flag expected
2886   * @param  Timeout   : Duration of the timeout
2887   * @param  Tickstart : Tick start value
2888   * @retval HAL status
2889   */
2890 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
2891                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2892 {
2893   /* Wait until flag is in expected state */
2894   while ((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
2895   {
2896     /* Check for the Timeout */
2897     if (Timeout != HAL_MAX_DELAY)
2898     {
2899       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2900       {
2901         hospi->State     = HAL_OSPI_STATE_ERROR;
2902         hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
2903 
2904         return HAL_ERROR;
2905       }
2906     }
2907   }
2908   return HAL_OK;
2909 }
2910 
2911 /**
2912   * @brief  Configure the registers for the regular command mode.
2913   * @param  hospi : OSPI handle
2914   * @param  cmd   : structure that contains the command configuration information
2915   * @retval HAL status
2916   */
2917 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
2918 {
2919   HAL_StatusTypeDef status = HAL_OK;
2920   __IO uint32_t *ccr_reg;
2921   __IO uint32_t *tcr_reg;
2922   __IO uint32_t *ir_reg;
2923   __IO uint32_t *abr_reg;
2924 
2925   /* Re-initialize the value of the functional mode */
2926   MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
2927 
2928   /* Configure the flash ID */
2929   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
2930   {
2931     MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
2932   }
2933 
2934   if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
2935   {
2936     ccr_reg = &(hospi->Instance->WCCR);
2937     tcr_reg = &(hospi->Instance->WTCR);
2938     ir_reg  = &(hospi->Instance->WIR);
2939     abr_reg = &(hospi->Instance->WABR);
2940   }
2941   else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
2942   {
2943     ccr_reg = &(hospi->Instance->WPCCR);
2944     tcr_reg = &(hospi->Instance->WPTCR);
2945     ir_reg  = &(hospi->Instance->WPIR);
2946     abr_reg = &(hospi->Instance->WPABR);
2947   }
2948   else
2949   {
2950     ccr_reg = &(hospi->Instance->CCR);
2951     tcr_reg = &(hospi->Instance->TCR);
2952     ir_reg  = &(hospi->Instance->IR);
2953     abr_reg = &(hospi->Instance->ABR);
2954   }
2955 
2956   /* Configure the CCR register with DQS and SIOO modes */
2957   *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
2958 
2959   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
2960   {
2961     /* Configure the ABR register with alternate bytes value */
2962     *abr_reg = cmd->AlternateBytes;
2963 
2964     /* Configure the CCR register with alternate bytes communication parameters */
2965     MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
2966                (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
2967   }
2968 
2969   /* Configure the TCR register with the number of dummy cycles */
2970   MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
2971 
2972   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2973   {
2974     if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
2975     {
2976       /* Configure the DLR register with the number of data */
2977       hospi->Instance->DLR = (cmd->NbData - 1U);
2978     }
2979   }
2980 
2981   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
2982   {
2983     if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2984     {
2985       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2986       {
2987         /* ---- Command with instruction, address and data ---- */
2988 
2989         /* Configure the CCR register with all communication parameters */
2990         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
2991                                 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2992                                 OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
2993                    (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2994                     cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize     |
2995                     cmd->DataMode        | cmd->DataDtrMode));
2996       }
2997       else
2998       {
2999         /* ---- Command with instruction and address ---- */
3000 
3001         /* Configure the CCR register with all communication parameters */
3002         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
3003                                 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
3004                    (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
3005                     cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize));
3006 
3007         /* The DHQC bit is linked with DDTR bit which should be activated */
3008         if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
3009             (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
3010         {
3011           MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
3012         }
3013       }
3014 
3015       /* Configure the IR register with the instruction value */
3016       *ir_reg = cmd->Instruction;
3017 
3018       /* Configure the AR register with the address value */
3019       hospi->Instance->AR = cmd->Address;
3020     }
3021     else
3022     {
3023       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3024       {
3025         /* ---- Command with instruction and data ---- */
3026 
3027         /* Configure the CCR register with all communication parameters */
3028         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
3029                                 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
3030                    (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
3031                     cmd->DataMode        | cmd->DataDtrMode));
3032       }
3033       else
3034       {
3035         /* ---- Command with only instruction ---- */
3036 
3037         /* Configure the CCR register with all communication parameters */
3038         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
3039                    (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
3040 
3041         /* The DHQC bit is linked with DDTR bit which should be activated */
3042         if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
3043             (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
3044         {
3045           MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
3046         }
3047       }
3048 
3049       /* Configure the IR register with the instruction value */
3050       *ir_reg = cmd->Instruction;
3051 
3052     }
3053   }
3054   else
3055   {
3056     if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
3057     {
3058       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3059       {
3060         /* ---- Command with address and data ---- */
3061 
3062         /* Configure the CCR register with all communication parameters */
3063         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
3064                                 OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
3065                    (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | cmd->DataMode |
3066                     cmd->DataDtrMode));
3067       }
3068       else
3069       {
3070         /* ---- Command with only address ---- */
3071 
3072         /* Configure the CCR register with all communication parameters */
3073         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
3074                    (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
3075       }
3076 
3077       /* Configure the AR register with the instruction value */
3078       hospi->Instance->AR = cmd->Address;
3079     }
3080     else
3081     {
3082       /* ---- Invalid command configuration (no instruction, no address) ---- */
3083       status = HAL_ERROR;
3084       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
3085     }
3086   }
3087 
3088   /* Return function status */
3089   return status;
3090 }
3091 
3092 /**
3093   * @brief  Get the current IOM configuration for an OctoSPI instance.
3094   * @param  instance_nb : number of the instance
3095   * @param  cfg         : configuration of the IO Manager for the instance
3096   * @retval HAL status
3097   */
3098 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
3099 {
3100   HAL_StatusTypeDef status = HAL_OK;
3101   uint32_t reg;
3102   uint32_t value = 0U;
3103   uint32_t index;
3104 
3105   if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
3106   {
3107     /* Invalid parameter -> error returned */
3108     status = HAL_ERROR;
3109   }
3110   else
3111   {
3112     /* Initialize the structure */
3113     cfg->ClkPort    = 0U;
3114     cfg->DQSPort    = 0U;
3115     cfg->NCSPort    = 0U;
3116     cfg->IOLowPort  = 0U;
3117     cfg->IOHighPort = 0U;
3118 
3119     if (instance_nb == 2U)
3120     {
3121       if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
3122       {
3123         value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC
3124                  | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
3125       }
3126       else
3127       {
3128         value = OCTOSPIM_PCR_NCSSRC;
3129       }
3130     }
3131 
3132     /* Get the information about the instance */
3133     for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
3134     {
3135       reg = OCTOSPIM->PCR[index];
3136 
3137       if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
3138       {
3139         /* The clock is enabled on this port */
3140         if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
3141         {
3142           /* The clock correspond to the instance passed as parameter */
3143           cfg->ClkPort = index + 1U;
3144         }
3145       }
3146 
3147       if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
3148       {
3149         /* The DQS is enabled on this port */
3150         if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
3151         {
3152           /* The DQS correspond to the instance passed as parameter */
3153           cfg->DQSPort = index + 1U;
3154         }
3155       }
3156 
3157       if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
3158       {
3159         /* The nCS is enabled on this port */
3160         if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
3161         {
3162           /* The nCS correspond to the instance passed as parameter */
3163           cfg->NCSPort = index + 1U;
3164         }
3165       }
3166 
3167       if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
3168       {
3169         /* The IO Low is enabled on this port */
3170         if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
3171         {
3172           /* The IO Low correspond to the instance passed as parameter */
3173           if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
3174           {
3175             cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3176           }
3177           else
3178           {
3179             cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3180           }
3181         }
3182       }
3183 
3184       if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
3185       {
3186         /* The IO High is enabled on this port */
3187         if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
3188         {
3189           /* The IO High correspond to the instance passed as parameter */
3190           if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
3191           {
3192             cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3193           }
3194           else
3195           {
3196             cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3197           }
3198         }
3199       }
3200     }
3201   }
3202 
3203   /* Return function status */
3204   return status;
3205 }
3206 
3207 /**
3208   @endcond
3209   */
3210 
3211 /**
3212   * @}
3213   */
3214 
3215 #endif /* HAL_OSPI_MODULE_ENABLED */
3216 
3217 /**
3218   * @}
3219   */
3220 
3221 /**
3222   * @}
3223   */
3224 
3225 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */