STM32H735xx HAL User Manual
stm32h7xx_hal_ospi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_ospi.c
00004   * @author  MCD Application Team
00005   * @brief   OSPI HAL module driver.
00006              This file provides firmware functions to manage the following
00007              functionalities of the OctoSPI interface (OSPI).
00008               + Initialization and de-initialization functions
00009               + Hyperbus configuration
00010               + Indirect functional mode management
00011               + Memory-mapped functional mode management
00012               + Auto-polling functional mode management
00013               + Interrupts and flags management
00014               + DMA channel configuration for indirect functional mode
00015               + Errors management and abort functionality
00016               + IO manager configuration
00017 
00018   ******************************************************************************
00019   * @attention
00020   *
00021   * Copyright (c) 2017 STMicroelectronics.
00022   * All rights reserved.
00023   *
00024   * This software is licensed under terms that can be found in the LICENSE file
00025   * in the root directory of this software component.
00026   * If no LICENSE file comes with this software, it is provided AS-IS.
00027   *
00028   ******************************************************************************
00029   @verbatim
00030  ===============================================================================
00031                         ##### How to use this driver #####
00032  ===============================================================================
00033   [..]
00034     *** Initialization ***
00035     ======================
00036     [..]
00037      As prerequisite, fill in the HAL_OSPI_MspInit() :
00038      (+) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE().
00039      (+) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET().
00040      (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
00041      (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
00042      (+) If interrupt or DMA mode is used, enable and configure OctoSPI global
00043          interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00044      (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
00045          with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
00046          link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
00047          DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00048     [..]
00049      Configure the fifo threshold, the dual-quad mode, the memory type, the
00050      device size, the CS high time, the free running clock, the clock mode,
00051      the wrap size, the clock prescaler, the sample shifting, the hold delay
00052      and the CS boundary using the HAL_OSPI_Init() function.
00053     [..]
00054      When using Hyperbus, configure the RW recovery time, the access time,
00055      the write latency and the latency mode unsing the HAL_OSPI_HyperbusCfg()
00056      function.
00057 
00058     *** Indirect functional mode ***
00059     ================================
00060     [..]
00061      In regular mode, configure the command sequence using the HAL_OSPI_Command()
00062      or HAL_OSPI_Command_IT() functions :
00063      (+) Instruction phase : the mode used and if present the size, the instruction
00064          opcode and the DTR mode.
00065      (+) Address phase : the mode used and if present the size, the address
00066          value and the DTR mode.
00067      (+) Alternate-bytes phase : the mode used and if present the size, the
00068          alternate bytes values and the DTR mode.
00069      (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00070      (+) Data phase : the mode used and if present the number of bytes and the DTR mode.
00071      (+) Data strobe (DQS) mode : the activation (or not) of this mode
00072      (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00073      (+) Flash identifier : in dual-quad mode, indicates which flash is concerned
00074      (+) Operation type : always common configuration
00075     [..]
00076      In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd()
00077      function :
00078      (+) Address space : indicate if the access will be done in register or memory
00079      (+) Address size
00080      (+) Number of data
00081      (+) Data strobe (DQS) mode : the activation (or not) of this mode
00082     [..]
00083      If no data is required for the command (only for regular mode, not for
00084      Hyperbus mode), it is sent directly to the memory :
00085      (+) In polling mode, the output of the function is done when the transfer is complete.
00086      (+) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete.
00087     [..]
00088      For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or
00089      HAL_OSPI_Transmit_IT() after the command configuration :
00090      (+) In polling mode, the output of the function is done when the transfer is complete.
00091      (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
00092          is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
00093      (+) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and
00094          HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
00095     [..]
00096      For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or
00097      HAL_OSPI_Receive_IT() after the command configuration :
00098      (+) In polling mode, the output of the function is done when the transfer is complete.
00099      (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
00100          is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
00101      (+) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and
00102          HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
00103 
00104     *** Auto-polling functional mode ***
00105     ====================================
00106     [..]
00107      Configure the command sequence by the same way than the indirect mode
00108     [..]
00109      Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling()
00110      or HAL_OSPI_AutoPolling_IT() functions :
00111      (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
00112          the polling interval and the automatic stop activation.
00113     [..]
00114      After the configuration :
00115      (+) In polling mode, the output of the function is done when the status match is reached. The
00116          automatic stop is activated to avoid an infinite loop.
00117      (+) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached.
00118 
00119     *** MDMA functional mode ***
00120     ====================================
00121     [..]
00122      Configure the SourceInc and DestinationInc of MDMA paramters in the HAL_OSPI_MspInit() function :
00123      (+) MDMA settings for write operation :
00124          (++) The DestinationInc should be MDMA_DEST_INC_DISABLE
00125          (++) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
00126          (++) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
00127               aligned with @ref MDMA_Source_increment_mode .
00128          (++) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
00129      (+) MDMA settings for read operation :
00130          (++) The SourceInc should be MDMA_SRC_INC_DISABLE
00131          (++) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode (Except the MDMA_DEST_INC_DOUBLEWORD).
00132          (++) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
00133          (++) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
00134               aligned with @ref MDMA_Destination_increment_mode.
00135      (+) The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Octospi.
00136     [..]
00137      In case of wrong MDMA setting
00138      (+) For write operation :
00139          (++) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled by the HAL_OSPI_Transmit_DMA().
00140      (+) For read operation :
00141          (++) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled by the HAL_OSPI_Receive_DMA().
00142 
00143     *** Memory-mapped functional mode ***
00144     =====================================
00145     [..]
00146      Configure the command sequence by the same way than the indirect mode except
00147      for the operation type in regular mode :
00148      (+) Operation type equals to read configuration : the command configuration
00149          applies to read access in memory-mapped mode
00150      (+) Operation type equals to write configuration : the command configuration
00151          applies to write access in memory-mapped mode
00152      (+) Both read and write configuration should be performed before activating
00153          memory-mapped mode
00154     [..]
00155      Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
00156      functions :
00157      (+) The timeout activation and the timeout period.
00158     [..]
00159      After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
00160      the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires.
00161 
00162     *** Errors management and abort functionality ***
00163     =================================================
00164     [..]
00165      HAL_OSPI_GetError() function gives the error raised during the last operation.
00166     [..]
00167      HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and
00168      flushes the fifo :
00169      (+) In polling mode, the output of the function is done when the transfer
00170          complete bit is set and the busy bit cleared.
00171      (+) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when
00172          the transfer complete bit is set.
00173 
00174     *** Control functions ***
00175     =========================
00176     [..]
00177      HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver.
00178     [..]
00179      HAL_OSPI_SetTimeout() function configures the timeout value used in the driver.
00180     [..]
00181      HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral.
00182     [..]
00183      HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
00184 
00185     *** IO manager configuration functions ***
00186     ==========================================
00187     [..]
00188      HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.
00189 
00190     *** Callback registration ***
00191     =============================================
00192     [..]
00193      The compilation define  USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1
00194      allows the user to configure dynamically the driver callbacks.
00195 
00196     [..]
00197      Use function HAL_OSPI_RegisterCallback() to register a user callback,
00198      it allows to register following callbacks:
00199      (+) ErrorCallback : callback when error occurs.
00200      (+) AbortCpltCallback : callback when abort is completed.
00201      (+) FifoThresholdCallback : callback when the fifo threshold is reached.
00202      (+) CmdCpltCallback : callback when a command without data is completed.
00203      (+) RxCpltCallback : callback when a reception transfer is completed.
00204      (+) TxCpltCallback : callback when a transmission transfer is completed.
00205      (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
00206      (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
00207      (+) StatusMatchCallback : callback when a status match occurs.
00208      (+) TimeOutCallback : callback when the timeout perioed expires.
00209      (+) MspInitCallback    : OSPI MspInit.
00210      (+) MspDeInitCallback  : OSPI MspDeInit.
00211     [..]
00212      This function takes as parameters the HAL peripheral handle, the Callback ID
00213      and a pointer to the user callback function.
00214 
00215     [..]
00216      Use function HAL_OSPI_UnRegisterCallback() to reset a callback to the default
00217      weak (surcharged) function. It allows to reset following callbacks:
00218      (+) ErrorCallback : callback when error occurs.
00219      (+) AbortCpltCallback : callback when abort is completed.
00220      (+) FifoThresholdCallback : callback when the fifo threshold is reached.
00221      (+) CmdCpltCallback : callback when a command without data is completed.
00222      (+) RxCpltCallback : callback when a reception transfer is completed.
00223      (+) TxCpltCallback : callback when a transmission transfer is completed.
00224      (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
00225      (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
00226      (+) StatusMatchCallback : callback when a status match occurs.
00227      (+) TimeOutCallback : callback when the timeout perioed expires.
00228      (+) MspInitCallback    : OSPI MspInit.
00229      (+) MspDeInitCallback  : OSPI MspDeInit.
00230     [..]
00231      This function) takes as parameters the HAL peripheral handle and the Callback ID.
00232 
00233     [..]
00234      By default, after the HAL_OSPI_Init() and if the state is HAL_OSPI_STATE_RESET
00235      all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00236      Exception done for MspInit and MspDeInit callbacks that are respectively
00237      reset to the legacy weak (surcharged) functions in the HAL_OSPI_Init()
00238      and HAL_OSPI_DeInit() only when these callbacks are null (not registered beforehand).
00239      If not, MspInit or MspDeInit are not null, the HAL_OSPI_Init() and HAL_OSPI_DeInit()
00240      keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00241 
00242     [..]
00243      Callbacks can be registered/unregistered in READY state only.
00244      Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00245      in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00246      during the Init/DeInit.
00247      In that case first register the MspInit/MspDeInit user callbacks
00248      using HAL_OSPI_RegisterCallback() before calling HAL_OSPI_DeInit()
00249      or HAL_OSPI_Init() function.
00250 
00251     [..]
00252      When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or
00253      not defined, the callback registering feature is not available
00254      and weak (surcharged) callbacks are used.
00255 
00256   @endverbatim
00257   ******************************************************************************
00258   */
00259 
00260 /* Includes ------------------------------------------------------------------*/
00261 #include "stm32h7xx_hal.h"
00262 
00263 #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)
00264 
00265 /** @addtogroup STM32H7xx_HAL_Driver
00266   * @{
00267   */
00268 
00269 /** @defgroup OSPI OSPI
00270   * @brief OSPI HAL module driver
00271   * @{
00272   */
00273 
00274 #ifdef HAL_OSPI_MODULE_ENABLED
00275 
00276 /**
00277   @cond 0
00278   */
00279 /* Private typedef -----------------------------------------------------------*/
00280 
00281 /* Private define ------------------------------------------------------------*/
00282 #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000)         /*!< Indirect write mode    */
00283 #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode     */
00284 #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */
00285 #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)OCTOSPI_CR_FMODE)   /*!< Memory-mapped mode     */
00286 
00287 #define OSPI_CFG_STATE_MASK  0x00000004U
00288 #define OSPI_BUSY_STATE_MASK 0x00000008U
00289 
00290 #define OSPI_NB_INSTANCE   2U
00291 #define OSPI_IOM_NB_PORTS  2U
00292 #define OSPI_IOM_PORT_MASK 0x1U
00293 
00294 /* Private macro -------------------------------------------------------------*/
00295 #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
00296                                        ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
00297                                        ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
00298                                        ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
00299 
00300 /* Private variables ---------------------------------------------------------*/
00301 
00302 /* Private function prototypes -----------------------------------------------*/
00303 static void              OSPI_DMACplt                  (MDMA_HandleTypeDef *hmdma);
00304 static void              OSPI_DMAError                 (MDMA_HandleTypeDef *hmdma);
00305 static void              OSPI_DMAAbortCplt             (MDMA_HandleTypeDef *hmdma);
00306 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State,
00307                                                         uint32_t Tickstart, uint32_t Timeout);
00308 static HAL_StatusTypeDef OSPI_ConfigCmd                (OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
00309 static HAL_StatusTypeDef OSPIM_GetConfig               (uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
00310 /**
00311   @endcond
00312   */
00313 
00314 /* Exported functions --------------------------------------------------------*/
00315 
00316 /** @defgroup OSPI_Exported_Functions OSPI Exported Functions
00317   * @{
00318   */
00319 
00320 /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
00321   * @brief    Initialization and Configuration functions
00322   *
00323 @verbatim
00324 ===============================================================================
00325             ##### Initialization and Configuration functions #####
00326  ===============================================================================
00327     [..]
00328     This subsection provides a set of functions allowing to :
00329       (+) Initialize the OctoSPI.
00330       (+) De-initialize the OctoSPI.
00331 
00332 @endverbatim
00333   * @{
00334   */
00335 
00336 /**
00337   * @brief  Initialize the OSPI mode according to the specified parameters
00338   *         in the OSPI_InitTypeDef and initialize the associated handle.
00339   * @param  hospi : OSPI handle
00340   * @retval HAL status
00341   */
00342 HAL_StatusTypeDef HAL_OSPI_Init (OSPI_HandleTypeDef *hospi)
00343 {
00344   HAL_StatusTypeDef status = HAL_OK;
00345   uint32_t tickstart = HAL_GetTick();
00346 
00347   /* Check the OSPI handle allocation */
00348   if (hospi == NULL)
00349   {
00350     status = HAL_ERROR;
00351     /* No error code can be set set as the handler is null */
00352   }
00353   else
00354   {
00355     /* Check the parameters of the initialization structure */
00356     assert_param(IS_OSPI_FIFO_THRESHOLD (hospi->Init.FifoThreshold));
00357     assert_param(IS_OSPI_DUALQUAD_MODE  (hospi->Init.DualQuad));
00358     assert_param(IS_OSPI_MEMORY_TYPE    (hospi->Init.MemoryType));
00359     assert_param(IS_OSPI_DEVICE_SIZE    (hospi->Init.DeviceSize));
00360     assert_param(IS_OSPI_CS_HIGH_TIME   (hospi->Init.ChipSelectHighTime));
00361     assert_param(IS_OSPI_FREE_RUN_CLK   (hospi->Init.FreeRunningClock));
00362     assert_param(IS_OSPI_CLOCK_MODE     (hospi->Init.ClockMode));
00363     assert_param(IS_OSPI_WRAP_SIZE      (hospi->Init.WrapSize));
00364     assert_param(IS_OSPI_CLK_PRESCALER  (hospi->Init.ClockPrescaler));
00365     assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
00366     assert_param(IS_OSPI_DHQC           (hospi->Init.DelayHoldQuarterCycle));
00367     assert_param(IS_OSPI_CS_BOUNDARY    (hospi->Init.ChipSelectBoundary));
00368     assert_param(IS_OSPI_CKCSHT         (hospi->Init.ClkChipSelectHighTime));
00369     assert_param(IS_OSPI_MAXTRAN        (hospi->Init.MaxTran));
00370 
00371     /* Initialize error code */
00372     hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
00373 
00374     /* Check if the state is the reset state */
00375     if (hospi->State == HAL_OSPI_STATE_RESET)
00376     {
00377 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00378       /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
00379       hospi->ErrorCallback         = HAL_OSPI_ErrorCallback;
00380       hospi->AbortCpltCallback     = HAL_OSPI_AbortCpltCallback;
00381       hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
00382       hospi->CmdCpltCallback       = HAL_OSPI_CmdCpltCallback;
00383       hospi->RxCpltCallback        = HAL_OSPI_RxCpltCallback;
00384       hospi->TxCpltCallback        = HAL_OSPI_TxCpltCallback;
00385       hospi->RxHalfCpltCallback    = HAL_OSPI_RxHalfCpltCallback;
00386       hospi->TxHalfCpltCallback    = HAL_OSPI_TxHalfCpltCallback;
00387       hospi->StatusMatchCallback   = HAL_OSPI_StatusMatchCallback;
00388       hospi->TimeOutCallback       = HAL_OSPI_TimeOutCallback;
00389 
00390       if(hospi->MspInitCallback == NULL)
00391       {
00392         hospi->MspInitCallback = HAL_OSPI_MspInit;
00393       }
00394 
00395       /* Init the low level hardware */
00396       hospi->MspInitCallback(hospi);
00397 #else
00398       /* Initialization of the low level hardware */
00399       HAL_OSPI_MspInit(hospi);
00400 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00401 
00402       /* Configure the default timeout for the OSPI memory access */
00403       (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
00404 
00405       /* Configure memory type, device size, chip select high time, clocked chip select high time, free running clock, clock mode */
00406       MODIFY_REG(hospi->Instance->DCR1,
00407                  (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_CKCSHT |
00408                   OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
00409                  (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
00410                   ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
00411                   (hospi->Init.ClkChipSelectHighTime << OCTOSPI_DCR1_CKCSHT_Pos) | hospi->Init.ClockMode));
00412 
00413       /* Configure wrap size */
00414       MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);
00415 
00416       /* Configure chip select boundary and maximum transfer */
00417       hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) |
00418                                (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));
00419 
00420       /* Configure refresh */
00421       hospi->Instance->DCR4 = hospi->Init.Refresh;
00422 
00423       /* Configure FIFO threshold */
00424       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
00425 
00426       /* Wait till busy flag is reset */
00427       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
00428 
00429       if (status == HAL_OK)
00430       {
00431         /* Configure clock prescaler */
00432         MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER,
00433                   ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
00434 
00435         /* Configure Dual Quad mode */
00436         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
00437 
00438         /* Configure sample shifting and delay hold quarter cycle */
00439         MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC),
00440                   (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
00441 
00442         /* Enable OctoSPI */
00443         __HAL_OSPI_ENABLE(hospi);
00444 
00445         /* Enable free running clock if needed : must be done after OSPI enable */
00446         if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
00447         {
00448           SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
00449         }
00450 
00451         /* Initialize the OSPI state */
00452         if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
00453         {
00454           hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
00455         }
00456         else
00457         {
00458           hospi->State = HAL_OSPI_STATE_READY;
00459         }
00460       }
00461     }
00462   }
00463 
00464   /* Return function status */
00465   return status;
00466 }
00467 
00468 /**
00469   * @brief  Initialize the OSPI MSP.
00470   * @param  hospi : OSPI handle
00471   * @retval None
00472   */
00473 __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
00474 {
00475   /* Prevent unused argument(s) compilation warning */
00476   UNUSED(hospi);
00477 
00478   /* NOTE : This function should not be modified, when the callback is needed,
00479             the HAL_OSPI_MspInit can be implemented in the user file
00480    */
00481 }
00482 
00483 /**
00484   * @brief  De-Initialize the OSPI peripheral.
00485   * @param  hospi : OSPI handle
00486   * @retval HAL status
00487   */
00488 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
00489 {
00490   HAL_StatusTypeDef status = HAL_OK;
00491 
00492   /* Check the OSPI handle allocation */
00493   if (hospi == NULL)
00494   {
00495     status = HAL_ERROR;
00496     /* No error code can be set set as the handler is null */
00497   }
00498   else
00499   {
00500      /* Disable OctoSPI */
00501      __HAL_OSPI_DISABLE(hospi);
00502 
00503      /* Disable free running clock if needed : must be done after OSPI disable */
00504      CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
00505 
00506 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00507      if(hospi->MspDeInitCallback == NULL)
00508      {
00509        hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
00510      }
00511 
00512      /* DeInit the low level hardware */
00513      hospi->MspDeInitCallback(hospi);
00514 #else
00515      /* De-initialize the low-level hardware */
00516      HAL_OSPI_MspDeInit(hospi);
00517 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00518 
00519      /* Reset the driver state */
00520      hospi->State = HAL_OSPI_STATE_RESET;
00521   }
00522 
00523   return status;
00524 }
00525 
00526 /**
00527   * @brief  DeInitialize the OSPI MSP.
00528   * @param  hospi : OSPI handle
00529   * @retval None
00530   */
00531 __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
00532 {
00533   /* Prevent unused argument(s) compilation warning */
00534   UNUSED(hospi);
00535 
00536   /* NOTE : This function should not be modified, when the callback is needed,
00537             the HAL_OSPI_MspDeInit can be implemented in the user file
00538    */
00539 }
00540 
00541 /**
00542   * @}
00543   */
00544 
00545 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
00546   *  @brief OSPI Transmit/Receive functions
00547   *
00548 @verbatim
00549  ===============================================================================
00550                       ##### IO operation functions #####
00551  ===============================================================================
00552     [..]
00553     This subsection provides a set of functions allowing to :
00554       (+) Handle the interrupts.
00555       (+) Handle the command sequence (regular and Hyperbus).
00556       (+) Handle the Hyperbus configuration.
00557       (+) Transmit data in blocking, interrupt or DMA mode.
00558       (+) Receive data in blocking, interrupt or DMA mode.
00559       (+) Manage the auto-polling functional mode.
00560       (+) Manage the memory-mapped functional mode.
00561 
00562 @endverbatim
00563   * @{
00564   */
00565 
00566 /**
00567   * @brief  Handle OSPI interrupt request.
00568   * @param  hospi : OSPI handle
00569   * @retval None
00570   */
00571 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
00572 {
00573   __IO uint32_t *data_reg = &hospi->Instance->DR;
00574   uint32_t flag           = hospi->Instance->SR;
00575   uint32_t itsource       = hospi->Instance->CR;
00576   uint32_t currentstate   = hospi->State;
00577 
00578   /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
00579   if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
00580   {
00581     if (currentstate == HAL_OSPI_STATE_BUSY_TX)
00582     {
00583       /* Write a data in the fifo */
00584       *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
00585       hospi->pBuffPtr++;
00586       hospi->XferCount--;
00587     }
00588     else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
00589     {
00590       /* Read a data from the fifo */
00591       *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
00592       hospi->pBuffPtr++;
00593       hospi->XferCount--;
00594     }
00595     else
00596     {
00597       /* Nothing to do */
00598     }
00599 
00600     if (hospi->XferCount == 0U)
00601     {
00602       /* All data have been received or transmitted for the transfer */
00603       /* Disable fifo threshold interrupt */
00604       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
00605     }
00606 
00607     /* Fifo threshold callback */
00608 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00609     hospi->FifoThresholdCallback(hospi);
00610 #else
00611     HAL_OSPI_FifoThresholdCallback(hospi);
00612 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
00613   }
00614   /* OctoSPI transfer complete interrupt occurred ----------------------------*/
00615   else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
00616   {
00617     if (currentstate == HAL_OSPI_STATE_BUSY_RX)
00618     {
00619       if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
00620       {
00621         /* Read the last data received in the fifo */
00622         *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
00623         hospi->pBuffPtr++;
00624         hospi->XferCount--;
00625       }
00626       else if(hospi->XferCount == 0U)
00627       {
00628         /* Clear flag */
00629         hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
00630 
00631         /* Disable the interrupts */
00632         __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
00633 
00634         /* Update state */
00635         hospi->State = HAL_OSPI_STATE_READY;
00636 
00637         /* RX complete callback */
00638 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00639         hospi->RxCpltCallback(hospi);
00640 #else
00641         HAL_OSPI_RxCpltCallback(hospi);
00642 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00643       }
00644       else
00645       {
00646         /* Nothing to do */
00647       }
00648     }
00649     else
00650     {
00651       /* Clear flag */
00652       hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
00653 
00654       /* Disable the interrupts */
00655       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
00656 
00657       /* Update state */
00658       hospi->State = HAL_OSPI_STATE_READY;
00659 
00660       if (currentstate == HAL_OSPI_STATE_BUSY_TX)
00661       {
00662         /* TX complete callback */
00663 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00664         hospi->TxCpltCallback(hospi);
00665 #else
00666         HAL_OSPI_TxCpltCallback(hospi);
00667 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00668       }
00669       else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
00670       {
00671         /* Command complete callback */
00672 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00673         hospi->CmdCpltCallback(hospi);
00674 #else
00675         HAL_OSPI_CmdCpltCallback(hospi);
00676 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00677       }
00678       else if (currentstate == HAL_OSPI_STATE_ABORT)
00679       {
00680         if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
00681         {
00682           /* Abort called by the user */
00683           /* Abort complete callback */
00684 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00685           hospi->AbortCpltCallback(hospi);
00686 #else
00687           HAL_OSPI_AbortCpltCallback(hospi);
00688 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
00689         }
00690         else
00691         {
00692           /* Abort due to an error (eg : DMA error) */
00693           /* Error callback */
00694 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00695           hospi->ErrorCallback(hospi);
00696 #else
00697           HAL_OSPI_ErrorCallback(hospi);
00698 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00699         }
00700       }
00701       else
00702       {
00703         /* Nothing to do */
00704       }
00705     }
00706   }
00707   /* OctoSPI status match interrupt occurred ---------------------------------*/
00708   else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
00709   {
00710     /* Clear flag */
00711     hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
00712 
00713     /* Check if automatic poll mode stop is activated */
00714     if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
00715     {
00716       /* Disable the interrupts */
00717       __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
00718 
00719       /* Update state */
00720       hospi->State = HAL_OSPI_STATE_READY;
00721     }
00722 
00723     /* Status match callback */
00724 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00725     hospi->StatusMatchCallback(hospi);
00726 #else
00727     HAL_OSPI_StatusMatchCallback(hospi);
00728 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00729   }
00730   /* OctoSPI transfer error interrupt occurred -------------------------------*/
00731   else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
00732   {
00733     /* Clear flag */
00734     hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
00735 
00736     /* Disable all interrupts */
00737     __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));
00738 
00739     /* Set error code */
00740     hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
00741 
00742     /* Check if the DMA is enabled */
00743     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
00744     {
00745       /* Disable the DMA transfer on the OctoSPI side */
00746       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
00747 
00748       /* Disable the DMA transfer on the DMA side */
00749       hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
00750       if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
00751       {
00752         /* Update state */
00753         hospi->State = HAL_OSPI_STATE_READY;
00754 
00755         /* Error callback */
00756 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00757         hospi->ErrorCallback(hospi);
00758 #else
00759         HAL_OSPI_ErrorCallback(hospi);
00760 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
00761       }
00762     }
00763     else
00764     {
00765       /* Update state */
00766       hospi->State = HAL_OSPI_STATE_READY;
00767 
00768       /* Error callback */
00769 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00770       hospi->ErrorCallback(hospi);
00771 #else
00772       HAL_OSPI_ErrorCallback(hospi);
00773 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00774     }
00775   }
00776   /* OctoSPI timeout interrupt occurred --------------------------------------*/
00777   else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
00778   {
00779     /* Clear flag */
00780     hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
00781 
00782     /* Timeout callback */
00783 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
00784     hospi->TimeOutCallback(hospi);
00785 #else
00786     HAL_OSPI_TimeOutCallback(hospi);
00787 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
00788   }
00789   else
00790   {
00791     /* Nothing to do */
00792   }
00793 }
00794 
00795 /**
00796   * @brief  Set the command configuration.
00797   * @param  hospi   : OSPI handle
00798   * @param  cmd     : structure that contains the command configuration information
00799   * @param  Timeout : Timeout duration
00800   * @retval HAL status
00801   */
00802 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
00803 {
00804   HAL_StatusTypeDef status;
00805   uint32_t state;
00806   uint32_t tickstart = HAL_GetTick();
00807 
00808   /* Check the parameters of the command structure */
00809   assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
00810 
00811   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
00812   {
00813     assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
00814   }
00815 
00816   assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00817   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
00818   {
00819     assert_param(IS_OSPI_INSTRUCTION_SIZE    (cmd->InstructionSize));
00820     assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
00821   }
00822 
00823   assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
00824   if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
00825   {
00826     assert_param(IS_OSPI_ADDRESS_SIZE    (cmd->AddressSize));
00827     assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
00828   }
00829 
00830   assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
00831   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
00832   {
00833     assert_param(IS_OSPI_ALT_BYTES_SIZE    (cmd->AlternateBytesSize));
00834     assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
00835   }
00836 
00837   assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
00838   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
00839   {
00840     if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
00841     {
00842       assert_param(IS_OSPI_NUMBER_DATA  (cmd->NbData));
00843     }
00844     assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
00845     assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
00846   }
00847 
00848   assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
00849   assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
00850 
00851   /* Check the state of the driver */
00852   state = hospi->State;
00853   if (((state == HAL_OSPI_STATE_READY)         && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
00854       ((state == HAL_OSPI_STATE_READ_CMD_CFG)  && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
00855                                                 || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) ||
00856       ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)  ||
00857                                                    (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))))
00858   {
00859     /* Wait till busy flag is reset */
00860     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
00861 
00862     if (status == HAL_OK)
00863     {
00864       /* Initialize error code */
00865       hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
00866 
00867       /* Configure the registers */
00868       status = OSPI_ConfigCmd(hospi, cmd);
00869 
00870       if (status == HAL_OK)
00871       {
00872         if (cmd->DataMode == HAL_OSPI_DATA_NONE)
00873         {
00874           /* When there is no data phase, the transfer start as soon as the configuration is done
00875              so wait until TC flag is set to go back in idle state */
00876           status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
00877 
00878           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
00879         }
00880         else
00881         {
00882           /* Update the state */
00883           if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
00884           {
00885             hospi->State = HAL_OSPI_STATE_CMD_CFG;
00886           }
00887           else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
00888           {
00889             if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
00890             {
00891               hospi->State = HAL_OSPI_STATE_CMD_CFG;
00892             }
00893             else
00894             {
00895               hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
00896             }
00897           }
00898           else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
00899           {
00900             if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
00901             {
00902               hospi->State = HAL_OSPI_STATE_CMD_CFG;
00903             }
00904             else
00905             {
00906               hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
00907             }
00908           }
00909           else
00910           {
00911             /* Wrap configuration, no state change */
00912           }
00913         }
00914       }
00915     }
00916   }
00917   else
00918   {
00919     status = HAL_ERROR;
00920     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
00921   }
00922 
00923   /* Return function status */
00924   return status;
00925 }
00926 
00927 /**
00928   * @brief  Set the command configuration in interrupt mode.
00929   * @param  hospi : OSPI handle
00930   * @param  cmd   : structure that contains the command configuration information
00931   * @note   This function is used only in Indirect Read or Write Modes
00932   * @retval HAL status
00933   */
00934 HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
00935 {
00936   HAL_StatusTypeDef status;
00937   uint32_t tickstart = HAL_GetTick();
00938 
00939   /* Check the parameters of the command structure */
00940   assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
00941 
00942   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
00943   {
00944     assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
00945   }
00946 
00947   assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00948   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
00949   {
00950     assert_param(IS_OSPI_INSTRUCTION_SIZE    (cmd->InstructionSize));
00951     assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
00952   }
00953 
00954   assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
00955   if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
00956   {
00957     assert_param(IS_OSPI_ADDRESS_SIZE    (cmd->AddressSize));
00958     assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
00959   }
00960 
00961   assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
00962   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
00963   {
00964     assert_param(IS_OSPI_ALT_BYTES_SIZE    (cmd->AlternateBytesSize));
00965     assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
00966   }
00967 
00968   assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
00969   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
00970   {
00971     assert_param(IS_OSPI_NUMBER_DATA  (cmd->NbData));
00972     assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
00973     assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
00974   }
00975 
00976   assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
00977   assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
00978 
00979   /* Check the state of the driver */
00980   if ((hospi->State  == HAL_OSPI_STATE_READY) && (cmd->OperationType     == HAL_OSPI_OPTYPE_COMMON_CFG) &&
00981       (cmd->DataMode == HAL_OSPI_DATA_NONE)   && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
00982   {
00983     /* Wait till busy flag is reset */
00984     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
00985 
00986     if (status == HAL_OK)
00987     {
00988       /* Initialize error code */
00989       hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
00990 
00991       /* Clear flags related to interrupt */
00992       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
00993 
00994       /* Configure the registers */
00995       status = OSPI_ConfigCmd(hospi, cmd);
00996 
00997       if (status == HAL_OK)
00998       {
00999         /* Update the state */
01000           hospi->State = HAL_OSPI_STATE_BUSY_CMD;
01001 
01002         /* Enable the transfer complete and transfer error interrupts */
01003         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
01004       }
01005     }
01006   }
01007   else
01008   {
01009     status = HAL_ERROR;
01010     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01011   }
01012 
01013   /* Return function status */
01014   return status;
01015 }
01016 
01017 /**
01018   * @brief  Configure the Hyperbus parameters.
01019   * @param  hospi   : OSPI handle
01020   * @param  cfg     : Structure containing the Hyperbus configuration
01021   * @param  Timeout : Timeout duration
01022   * @retval HAL status
01023   */
01024 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
01025 {
01026   HAL_StatusTypeDef status;
01027   uint32_t state;
01028   uint32_t tickstart = HAL_GetTick();
01029 
01030   /* Check the parameters of the hyperbus configuration structure */
01031   assert_param(IS_OSPI_RW_RECOVERY_TIME  (cfg->RWRecoveryTime));
01032   assert_param(IS_OSPI_ACCESS_TIME       (cfg->AccessTime));
01033   assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
01034   assert_param(IS_OSPI_LATENCY_MODE      (cfg->LatencyMode));
01035 
01036   /* Check the state of the driver */
01037   state = hospi->State;
01038   if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
01039   {
01040     /* Wait till busy flag is reset */
01041     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
01042 
01043     if (status == HAL_OK)
01044     {
01045       /* Configure Hyperbus configuration Latency register */
01046       WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
01047                                         (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos)     |
01048                                         cfg->WriteZeroLatency | cfg->LatencyMode));
01049 
01050       /* Update the state */
01051       hospi->State = HAL_OSPI_STATE_READY;
01052     }
01053   }
01054   else
01055   {
01056     status = HAL_ERROR;
01057     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01058   }
01059 
01060   /* Return function status */
01061   return status;
01062 }
01063 
01064 /**
01065   * @brief  Set the Hyperbus command configuration.
01066   * @param  hospi   : OSPI handle
01067   * @param  cmd     : Structure containing the Hyperbus command
01068   * @param  Timeout : Timeout duration
01069   * @retval HAL status
01070   */
01071 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
01072 {
01073   HAL_StatusTypeDef status;
01074   uint32_t tickstart = HAL_GetTick();
01075 
01076   /* Check the parameters of the hyperbus command structure */
01077   assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
01078   assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
01079   assert_param(IS_OSPI_NUMBER_DATA  (cmd->NbData));
01080   assert_param(IS_OSPI_DQS_MODE     (cmd->DQSMode));
01081 
01082   /* Check the state of the driver */
01083   if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
01084   {
01085     /* Wait till busy flag is reset */
01086     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
01087 
01088     if (status == HAL_OK)
01089     {
01090       /* Re-initialize the value of the functional mode */
01091       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
01092 
01093       /* Configure the address space in the DCR1 register */
01094       MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
01095 
01096       /* Configure the CCR and WCCR registers with the address size and the following configuration :
01097          - DQS signal enabled (used as RWDS)
01098          - DTR mode enabled on address and data
01099          - address and data on 8 lines */
01100       WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
01101                                        cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
01102       WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
01103                                         cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
01104 
01105       /* Configure the DLR register with the number of data */
01106       WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
01107 
01108       /* Configure the AR register with the address value */
01109       WRITE_REG(hospi->Instance->AR, cmd->Address);
01110 
01111       /* Update the state */
01112       hospi->State = HAL_OSPI_STATE_CMD_CFG;
01113     }
01114   }
01115   else
01116   {
01117     status = HAL_ERROR;
01118     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01119   }
01120 
01121   /* Return function status */
01122   return status;
01123 }
01124 
01125 /**
01126   * @brief  Transmit an amount of data in blocking mode.
01127   * @param  hospi   : OSPI handle
01128   * @param  pData   : pointer to data buffer
01129   * @param  Timeout : Timeout duration
01130   * @note   This function is used only in Indirect Write Mode
01131   * @retval HAL status
01132   */
01133 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
01134 {
01135   HAL_StatusTypeDef status;
01136   uint32_t tickstart = HAL_GetTick();
01137   __IO uint32_t *data_reg = &hospi->Instance->DR;
01138 
01139   /* Check the data pointer allocation */
01140   if (pData == NULL)
01141   {
01142     status = HAL_ERROR;
01143     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01144   }
01145   else
01146   {
01147     /* Check the state */
01148     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01149     {
01150       /* Configure counters and size */
01151       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
01152       hospi->XferSize  = hospi->XferCount;
01153       hospi->pBuffPtr  = pData;
01154 
01155       /* Configure CR register with functional mode as indirect write */
01156       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01157 
01158       do
01159       {
01160         /* Wait till fifo threshold flag is set to send data */
01161         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
01162 
01163         if (status != HAL_OK)
01164         {
01165           break;
01166         }
01167 
01168         *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
01169         hospi->pBuffPtr++;
01170         hospi->XferCount--;
01171       } while (hospi->XferCount > 0U);
01172 
01173       if (status == HAL_OK)
01174       {
01175         /* Wait till transfer complete flag is set to go back in idle state */
01176         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
01177 
01178         if (status == HAL_OK)
01179         {
01180           /* Clear transfer complete flag */
01181           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
01182 
01183           /* Update state */
01184           hospi->State = HAL_OSPI_STATE_READY;
01185         }
01186       }
01187     }
01188     else
01189     {
01190       status = HAL_ERROR;
01191       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01192     }
01193   }
01194 
01195   /* Return function status */
01196   return status;
01197 }
01198 
01199 /**
01200   * @brief  Receive an amount of data in blocking mode.
01201   * @param  hospi   : OSPI handle
01202   * @param  pData   : pointer to data buffer
01203   * @param  Timeout : Timeout duration
01204   * @note   This function is used only in Indirect Read Mode
01205   * @retval HAL status
01206   */
01207 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
01208 {
01209   HAL_StatusTypeDef status;
01210   uint32_t tickstart = HAL_GetTick();
01211   __IO uint32_t *data_reg = &hospi->Instance->DR;
01212   uint32_t addr_reg = hospi->Instance->AR;
01213   uint32_t ir_reg = hospi->Instance->IR;
01214 
01215   /* Check the data pointer allocation */
01216   if (pData == NULL)
01217   {
01218     status = HAL_ERROR;
01219     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01220   }
01221   else
01222   {
01223     /* Check the state */
01224     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01225     {
01226       /* Configure counters and size */
01227       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
01228       hospi->XferSize  = hospi->XferCount;
01229       hospi->pBuffPtr  = pData;
01230 
01231       /* Configure CR register with functional mode as indirect read */
01232       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01233 
01234       /* Trig the transfer by re-writing address or instruction register */
01235       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
01236       {
01237         WRITE_REG(hospi->Instance->AR, addr_reg);
01238       }
01239       else
01240       {
01241         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
01242         {
01243           WRITE_REG(hospi->Instance->AR, addr_reg);
01244         }
01245         else
01246         {
01247           WRITE_REG(hospi->Instance->IR, ir_reg);
01248         }
01249       }
01250 
01251       do
01252       {
01253         /* Wait till fifo threshold or transfer complete flags are set to read received data */
01254         status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
01255 
01256         if (status != HAL_OK)
01257         {
01258           break;
01259         }
01260 
01261         *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
01262         hospi->pBuffPtr++;
01263         hospi->XferCount--;
01264       } while(hospi->XferCount > 0U);
01265 
01266       if (status == HAL_OK)
01267       {
01268         /* Wait till transfer complete flag is set to go back in idle state */
01269         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
01270 
01271         if (status == HAL_OK)
01272         {
01273           /* Clear transfer complete flag */
01274           __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
01275 
01276           /* Update state */
01277           hospi->State = HAL_OSPI_STATE_READY;
01278         }
01279       }
01280     }
01281     else
01282     {
01283       status = HAL_ERROR;
01284       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01285     }
01286   }
01287 
01288   /* Return function status */
01289   return status;
01290 }
01291 
01292 /**
01293   * @brief  Send an amount of data in non-blocking mode with interrupt.
01294   * @param  hospi : OSPI handle
01295   * @param  pData : pointer to data buffer
01296   * @note   This function is used only in Indirect Write Mode
01297   * @retval HAL status
01298   */
01299 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
01300 {
01301   HAL_StatusTypeDef status = HAL_OK;
01302 
01303   /* Check the data pointer allocation */
01304   if (pData == NULL)
01305   {
01306     status = HAL_ERROR;
01307     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01308   }
01309   else
01310   {
01311     /* Check the state */
01312     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01313     {
01314       /* Configure counters and size */
01315       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
01316       hospi->XferSize  = hospi->XferCount;
01317       hospi->pBuffPtr  = pData;
01318 
01319       /* Configure CR register with functional mode as indirect write */
01320       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01321 
01322       /* Clear flags related to interrupt */
01323       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
01324 
01325       /* Update the state */
01326       hospi->State = HAL_OSPI_STATE_BUSY_TX;
01327 
01328       /* Enable the transfer complete, fifo threshold and transfer error interrupts */
01329       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
01330     }
01331     else
01332     {
01333       status = HAL_ERROR;
01334       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01335     }
01336   }
01337 
01338   /* Return function status */
01339   return status;
01340 }
01341 
01342 /**
01343   * @brief  Receive an amount of data in non-blocking mode with interrupt.
01344   * @param  hospi : OSPI handle
01345   * @param  pData : pointer to data buffer
01346   * @note   This function is used only in Indirect Read Mode
01347   * @retval HAL status
01348   */
01349 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
01350 {
01351   HAL_StatusTypeDef status = HAL_OK;
01352   uint32_t addr_reg = hospi->Instance->AR;
01353   uint32_t ir_reg = hospi->Instance->IR;
01354 
01355   /* Check the data pointer allocation */
01356   if (pData == NULL)
01357   {
01358     status = HAL_ERROR;
01359     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01360   }
01361   else
01362   {
01363     /* Check the state */
01364     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01365     {
01366       /* Configure counters and size */
01367       hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
01368       hospi->XferSize  = hospi->XferCount;
01369       hospi->pBuffPtr  = pData;
01370 
01371       /* Configure CR register with functional mode as indirect read */
01372       MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01373 
01374       /* Clear flags related to interrupt */
01375       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
01376 
01377       /* Update the state */
01378       hospi->State = HAL_OSPI_STATE_BUSY_RX;
01379 
01380       /* Enable the transfer complete, fifo threshold and transfer error interrupts */
01381       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
01382 
01383       /* Trig the transfer by re-writing address or instruction register */
01384       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
01385       {
01386         WRITE_REG(hospi->Instance->AR, addr_reg);
01387       }
01388       else
01389       {
01390         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
01391         {
01392           WRITE_REG(hospi->Instance->AR, addr_reg);
01393         }
01394         else
01395         {
01396           WRITE_REG(hospi->Instance->IR, ir_reg);
01397         }
01398       }
01399     }
01400     else
01401     {
01402       status = HAL_ERROR;
01403       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01404     }
01405   }
01406 
01407   /* Return function status */
01408   return status;
01409 }
01410 
01411 /**
01412   * @brief  Send an amount of data in non-blocking mode with DMA.
01413   * @param  hospi : OSPI handle
01414   * @param  pData : pointer to data buffer
01415   * @note   This function is used only in Indirect Write Mode
01416   * @note   If DMA peripheral access is configured as halfword, the number
01417   *         of data and the fifo threshold should be aligned on halfword
01418   * @note   If DMA peripheral access is configured as word, the number
01419   *         of data and the fifo threshold should be aligned on word
01420   * @retval HAL status
01421   */
01422 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
01423 {
01424   HAL_StatusTypeDef status = HAL_OK;
01425   uint32_t data_size = hospi->Instance->DLR + 1U;
01426 
01427   /* Check the data pointer allocation */
01428   if (pData == NULL)
01429   {
01430     status = HAL_ERROR;
01431     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01432   }
01433   else
01434   {
01435     /* Check the state */
01436     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01437     {
01438       hospi->XferCount = data_size;
01439 
01440       {
01441         hospi->XferSize = hospi->XferCount;
01442         hospi->pBuffPtr = pData;
01443 
01444         /* Configure CR register with functional mode as indirect write */
01445         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01446 
01447         /* Clear flags related to interrupt */
01448         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
01449 
01450         /* Update the state */
01451         hospi->State = HAL_OSPI_STATE_BUSY_TX;
01452 
01453         /* Set the MDMA transfer complete callback */
01454         hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
01455 
01456         /* Set the MDMA error callback */
01457         hospi->hmdma->XferErrorCallback = OSPI_DMAError;
01458 
01459         /* Clear the MDMA abort callback */
01460         hospi->hmdma->XferAbortCallback = NULL;
01461 
01462         /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment to disable */
01463         MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE);
01464 
01465         /* Update MDMA configuration with the correct SourceInc field for Write operation */
01466         if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
01467         {
01468           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE);
01469         }
01470         else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
01471         {
01472           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD);
01473         }
01474         else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
01475         {
01476           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD);
01477         }
01478         else
01479         {
01480           /* in case of incorrect source data size */
01481           hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
01482           status = HAL_ERROR;
01483         }
01484 
01485         /* Enable the transmit MDMA Channel */
01486         if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize,1) == HAL_OK)
01487             {
01488               /* Enable the transfer error interrupt */
01489               __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
01490 
01491               /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
01492             }
01493             else
01494             {
01495               status = HAL_ERROR;
01496               hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
01497               hospi->State = HAL_OSPI_STATE_READY;
01498             }
01499       }
01500     }
01501     else
01502     {
01503       status = HAL_ERROR;
01504       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01505     }
01506   }
01507 
01508   /* Return function status */
01509   return status;
01510 }
01511 
01512 /**
01513   * @brief  Receive an amount of data in non-blocking mode with DMA.
01514   * @param  hospi : OSPI handle
01515   * @param  pData : pointer to data buffer.
01516   * @note   This function is used only in Indirect Read Mode
01517   * @note   If DMA peripheral access is configured as halfword, the number
01518   *         of data and the fifo threshold should be aligned on halfword
01519   * @note   If DMA peripheral access is configured as word, the number
01520   *         of data and the fifo threshold should be aligned on word
01521   * @retval HAL status
01522   */
01523 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
01524 {
01525   HAL_StatusTypeDef status = HAL_OK;
01526   uint32_t data_size = hospi->Instance->DLR + 1U;
01527   uint32_t addr_reg = hospi->Instance->AR;
01528   uint32_t ir_reg = hospi->Instance->IR;
01529   /* Check the data pointer allocation */
01530   if (pData == NULL)
01531   {
01532     status = HAL_ERROR;
01533     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
01534   }
01535   else
01536   {
01537     /* Check the state */
01538     if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01539     {
01540       hospi->XferCount = data_size;
01541 
01542       {
01543         hospi->XferSize  = hospi->XferCount;
01544         hospi->pBuffPtr  = pData;
01545 
01546         /* Configure CR register with functional mode as indirect read */
01547         MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01548 
01549         /* Clear flags related to interrupt */
01550         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
01551 
01552         /* Update the state */
01553         hospi->State = HAL_OSPI_STATE_BUSY_RX;
01554 
01555         /* Set the DMA transfer complete callback */
01556         hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
01557 
01558         /* Set the DMA error callback */
01559         hospi->hmdma->XferErrorCallback = OSPI_DMAError;
01560 
01561         /* Clear the DMA abort callback */
01562         hospi->hmdma->XferAbortCallback = NULL;
01563 
01564         /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
01565         MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE);
01566 
01567         /* Update MDMA configuration with the correct DestinationInc field for read operation */
01568         if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
01569         {
01570           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE);
01571         }
01572         else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
01573         {
01574           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD);
01575         }
01576         else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
01577         {
01578           MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD);
01579         }
01580         else
01581         {
01582           /* in case of incorrect destination data size */
01583           hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
01584           status = HAL_ERROR;
01585         }
01586 
01587         /* Enable the transmit MDMA Channel */
01588         if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize, 1) == HAL_OK)
01589           {
01590             /* Enable the transfer error interrupt */
01591             __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
01592 
01593             /* Trig the transfer by re-writing address or instruction register */
01594             if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
01595             {
01596               WRITE_REG(hospi->Instance->AR, addr_reg);
01597             }
01598             else
01599             {
01600               if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
01601               {
01602                 WRITE_REG(hospi->Instance->AR, addr_reg);
01603               }
01604               else
01605               {
01606                 WRITE_REG(hospi->Instance->IR, ir_reg);
01607               }
01608             }
01609 
01610             /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
01611           }
01612           else
01613           {
01614             status = HAL_ERROR;
01615             hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
01616             hospi->State = HAL_OSPI_STATE_READY;
01617           }
01618       }
01619     }
01620     else
01621     {
01622       status = HAL_ERROR;
01623       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01624     }
01625   }
01626 
01627   /* Return function status */
01628   return status;
01629 }
01630 
01631 /**
01632   * @brief  Configure the OSPI Automatic Polling Mode in blocking mode.
01633   * @param  hospi   : OSPI handle
01634   * @param  cfg     : structure that contains the polling configuration information.
01635   * @param  Timeout : Timeout duration
01636   * @note   This function is used only in Automatic Polling Mode
01637   * @retval HAL status
01638   */
01639 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
01640 {
01641   HAL_StatusTypeDef status;
01642   uint32_t tickstart = HAL_GetTick();
01643   uint32_t addr_reg = hospi->Instance->AR;
01644   uint32_t ir_reg = hospi->Instance->IR;
01645 #ifdef USE_FULL_ASSERT
01646   uint32_t dlr_reg = hospi->Instance->DLR;
01647 #endif /* USE_FULL_ASSERT */
01648 
01649   /* Check the parameters of the autopolling configuration structure */
01650   assert_param(IS_OSPI_MATCH_MODE       (cfg->MatchMode));
01651   assert_param(IS_OSPI_AUTOMATIC_STOP   (cfg->AutomaticStop));
01652   assert_param(IS_OSPI_INTERVAL         (cfg->Interval));
01653   assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
01654 
01655   /* Check the state */
01656   if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
01657   {
01658     /* Wait till busy flag is reset */
01659     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
01660 
01661     if (status == HAL_OK)
01662     {
01663       /* Configure registers */
01664       WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
01665       WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
01666       WRITE_REG (hospi->Instance->PIR,   cfg->Interval);
01667       MODIFY_REG(hospi->Instance->CR,    (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
01668                  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
01669 
01670       /* Trig the transfer by re-writing address or instruction register */
01671       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
01672       {
01673         WRITE_REG(hospi->Instance->AR, addr_reg);
01674       }
01675       else
01676       {
01677         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
01678         {
01679           WRITE_REG(hospi->Instance->AR, addr_reg);
01680         }
01681         else
01682         {
01683           WRITE_REG(hospi->Instance->IR, ir_reg);
01684         }
01685       }
01686 
01687       /* Wait till status match flag is set to go back in idle state */
01688       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
01689 
01690       if (status == HAL_OK)
01691       {
01692         /* Clear status match flag */
01693         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
01694 
01695         /* Update state */
01696         hospi->State = HAL_OSPI_STATE_READY;
01697       }
01698     }
01699   }
01700   else
01701   {
01702     status = HAL_ERROR;
01703     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01704   }
01705 
01706   /* Return function status */
01707   return status;
01708 }
01709 
01710 /**
01711   * @brief  Configure the OSPI Automatic Polling Mode in non-blocking mode.
01712   * @param  hospi : OSPI handle
01713   * @param  cfg   : structure that contains the polling configuration information.
01714   * @note   This function is used only in Automatic Polling Mode
01715   * @retval HAL status
01716   */
01717 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
01718 {
01719   HAL_StatusTypeDef status;
01720   uint32_t tickstart = HAL_GetTick();
01721   uint32_t addr_reg = hospi->Instance->AR;
01722   uint32_t ir_reg = hospi->Instance->IR;
01723 #ifdef USE_FULL_ASSERT
01724   uint32_t dlr_reg = hospi->Instance->DLR;
01725 #endif /* USE_FULL_ASSERT */
01726 
01727   /* Check the parameters of the autopolling configuration structure */
01728   assert_param(IS_OSPI_MATCH_MODE       (cfg->MatchMode));
01729   assert_param(IS_OSPI_AUTOMATIC_STOP   (cfg->AutomaticStop));
01730   assert_param(IS_OSPI_INTERVAL         (cfg->Interval));
01731   assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
01732 
01733   /* Check the state */
01734   if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01735   {
01736     /* Wait till busy flag is reset */
01737     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
01738 
01739     if (status == HAL_OK)
01740     {
01741       /* Configure registers */
01742       WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
01743       WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
01744       WRITE_REG (hospi->Instance->PIR,   cfg->Interval);
01745       MODIFY_REG(hospi->Instance->CR,    (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
01746                  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
01747 
01748       /* Clear flags related to interrupt */
01749       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
01750 
01751       /* Update state */
01752       hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
01753 
01754       /* Enable the status match and transfer error interrupts */
01755       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
01756 
01757       /* Trig the transfer by re-writing address or instruction register */
01758       if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
01759       {
01760         WRITE_REG(hospi->Instance->AR, addr_reg);
01761       }
01762       else
01763       {
01764         if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
01765         {
01766           WRITE_REG(hospi->Instance->AR, addr_reg);
01767         }
01768         else
01769         {
01770           WRITE_REG(hospi->Instance->IR, ir_reg);
01771         }
01772       }
01773     }
01774   }
01775   else
01776   {
01777     status = HAL_ERROR;
01778     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01779   }
01780 
01781   /* Return function status */
01782   return status;
01783 }
01784 
01785 /**
01786   * @brief  Configure the Memory Mapped mode.
01787   * @param  hospi : OSPI handle
01788   * @param  cfg   : structure that contains the memory mapped configuration information.
01789   * @note   This function is used only in Memory mapped Mode
01790   * @retval HAL status
01791   */
01792 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
01793 {
01794   HAL_StatusTypeDef status;
01795   uint32_t tickstart = HAL_GetTick();
01796 
01797   /* Check the parameters of the memory-mapped configuration structure */
01798   assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
01799 
01800   /* Check the state */
01801   if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
01802   {
01803     /* Wait till busy flag is reset */
01804     status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
01805 
01806     if (status == HAL_OK)
01807     {
01808       /* Update state */
01809       hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
01810 
01811       if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
01812       {
01813         assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
01814 
01815         /* Configure register */
01816         WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
01817 
01818         /* Clear flags related to interrupt */
01819         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
01820 
01821         /* Enable the timeout interrupt */
01822         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
01823       }
01824 
01825       /* Configure CR register with functional mode as memory-mapped */
01826       MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
01827                  (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
01828     }
01829   }
01830   else
01831   {
01832     status = HAL_ERROR;
01833     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
01834   }
01835 
01836   /* Return function status */
01837   return status;
01838 }
01839 
01840 /**
01841   * @brief  Transfer Error callback.
01842   * @param  hospi : OSPI handle
01843   * @retval None
01844   */
01845 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
01846 {
01847   /* Prevent unused argument(s) compilation warning */
01848   UNUSED(hospi);
01849 
01850   /* NOTE : This function should not be modified, when the callback is needed,
01851             the HAL_OSPI_ErrorCallback could be implemented in the user file
01852    */
01853 }
01854 
01855 /**
01856   * @brief  Abort completed callback.
01857   * @param  hospi : OSPI handle
01858   * @retval None
01859   */
01860 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
01861 {
01862   /* Prevent unused argument(s) compilation warning */
01863   UNUSED(hospi);
01864 
01865   /* NOTE: This function should not be modified, when the callback is needed,
01866            the HAL_OSPI_AbortCpltCallback could be implemented in the user file
01867    */
01868 }
01869 
01870 /**
01871   * @brief  FIFO Threshold callback.
01872   * @param  hospi : OSPI handle
01873   * @retval None
01874   */
01875 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
01876 {
01877   /* Prevent unused argument(s) compilation warning */
01878   UNUSED(hospi);
01879 
01880   /* NOTE : This function should not be modified, when the callback is needed,
01881             the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
01882    */
01883 }
01884 
01885 /**
01886   * @brief  Command completed callback.
01887   * @param  hospi : OSPI handle
01888   * @retval None
01889   */
01890 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
01891 {
01892   /* Prevent unused argument(s) compilation warning */
01893   UNUSED(hospi);
01894 
01895   /* NOTE: This function should not be modified, when the callback is needed,
01896            the HAL_OSPI_CmdCpltCallback could be implemented in the user file
01897    */
01898 }
01899 
01900 /**
01901   * @brief  Rx Transfer completed callback.
01902   * @param  hospi : OSPI handle
01903   * @retval None
01904   */
01905 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
01906 {
01907   /* Prevent unused argument(s) compilation warning */
01908   UNUSED(hospi);
01909 
01910   /* NOTE: This function should not be modified, when the callback is needed,
01911            the HAL_OSPI_RxCpltCallback could be implemented in the user file
01912    */
01913 }
01914 
01915 /**
01916   * @brief  Tx Transfer completed callback.
01917   * @param  hospi : OSPI handle
01918   * @retval None
01919   */
01920  __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
01921 {
01922   /* Prevent unused argument(s) compilation warning */
01923   UNUSED(hospi);
01924 
01925   /* NOTE: This function should not be modified, when the callback is needed,
01926            the HAL_OSPI_TxCpltCallback could be implemented in the user file
01927    */
01928 }
01929 
01930 /**
01931   * @brief  Rx Half Transfer completed callback.
01932   * @param  hospi : OSPI handle
01933   * @retval None
01934   */
01935 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
01936 {
01937   /* Prevent unused argument(s) compilation warning */
01938   UNUSED(hospi);
01939 
01940   /* NOTE: This function should not be modified, when the callback is needed,
01941            the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
01942    */
01943 }
01944 
01945 /**
01946   * @brief  Tx Half Transfer completed callback.
01947   * @param  hospi : OSPI handle
01948   * @retval None
01949   */
01950 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
01951 {
01952   /* Prevent unused argument(s) compilation warning */
01953   UNUSED(hospi);
01954 
01955   /* NOTE: This function should not be modified, when the callback is needed,
01956            the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
01957    */
01958 }
01959 
01960 /**
01961   * @brief  Status Match callback.
01962   * @param  hospi : OSPI handle
01963   * @retval None
01964   */
01965 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
01966 {
01967   /* Prevent unused argument(s) compilation warning */
01968   UNUSED(hospi);
01969 
01970   /* NOTE : This function should not be modified, when the callback is needed,
01971             the HAL_OSPI_StatusMatchCallback could be implemented in the user file
01972    */
01973 }
01974 
01975 /**
01976   * @brief  Timeout callback.
01977   * @param  hospi : OSPI handle
01978   * @retval None
01979   */
01980 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
01981 {
01982   /* Prevent unused argument(s) compilation warning */
01983   UNUSED(hospi);
01984 
01985   /* NOTE : This function should not be modified, when the callback is needed,
01986             the HAL_OSPI_TimeOutCallback could be implemented in the user file
01987    */
01988 }
01989 
01990 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
01991 /**
01992   * @brief  Register a User OSPI Callback
01993   *         To be used instead of the weak (surcharged) predefined callback
01994   * @param hospi : OSPI handle
01995   * @param CallbackID : ID of the callback to be registered
01996   *        This parameter can be one of the following values:
01997   *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
01998   *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
01999   *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
02000   *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
02001   *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
02002   *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
02003   *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
02004   *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
02005   *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
02006   *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
02007   *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
02008   *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
02009   * @param pCallback : pointer to the Callback function
02010   * @retval status
02011   */
02012 HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID,
02013                                             pOSPI_CallbackTypeDef pCallback)
02014 {
02015   HAL_StatusTypeDef status = HAL_OK;
02016 
02017   if(pCallback == NULL)
02018   {
02019     /* Update the error code */
02020     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02021     return HAL_ERROR;
02022   }
02023 
02024   if(hospi->State == HAL_OSPI_STATE_READY)
02025   {
02026     switch (CallbackID)
02027     {
02028     case  HAL_OSPI_ERROR_CB_ID :
02029       hospi->ErrorCallback = pCallback;
02030       break;
02031     case HAL_OSPI_ABORT_CB_ID :
02032       hospi->AbortCpltCallback = pCallback;
02033       break;
02034     case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
02035       hospi->FifoThresholdCallback = pCallback;
02036       break;
02037     case HAL_OSPI_CMD_CPLT_CB_ID :
02038       hospi->CmdCpltCallback = pCallback;
02039       break;
02040     case HAL_OSPI_RX_CPLT_CB_ID :
02041       hospi->RxCpltCallback = pCallback;
02042       break;
02043     case HAL_OSPI_TX_CPLT_CB_ID :
02044       hospi->TxCpltCallback = pCallback;
02045       break;
02046     case HAL_OSPI_RX_HALF_CPLT_CB_ID :
02047       hospi->RxHalfCpltCallback = pCallback;
02048       break;
02049     case HAL_OSPI_TX_HALF_CPLT_CB_ID :
02050       hospi->TxHalfCpltCallback = pCallback;
02051       break;
02052     case HAL_OSPI_STATUS_MATCH_CB_ID :
02053       hospi->StatusMatchCallback = pCallback;
02054       break;
02055     case HAL_OSPI_TIMEOUT_CB_ID :
02056       hospi->TimeOutCallback = pCallback;
02057       break;
02058     case HAL_OSPI_MSP_INIT_CB_ID :
02059       hospi->MspInitCallback = pCallback;
02060       break;
02061     case HAL_OSPI_MSP_DEINIT_CB_ID :
02062       hospi->MspDeInitCallback = pCallback;
02063       break;
02064     default :
02065       /* Update the error code */
02066       hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02067       /* update return status */
02068       status =  HAL_ERROR;
02069       break;
02070     }
02071   }
02072   else if (hospi->State == HAL_OSPI_STATE_RESET)
02073   {
02074     switch (CallbackID)
02075     {
02076     case HAL_OSPI_MSP_INIT_CB_ID :
02077       hospi->MspInitCallback = pCallback;
02078       break;
02079     case HAL_OSPI_MSP_DEINIT_CB_ID :
02080       hospi->MspDeInitCallback = pCallback;
02081       break;
02082     default :
02083       /* Update the error code */
02084       hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02085       /* update return status */
02086       status =  HAL_ERROR;
02087       break;
02088     }
02089   }
02090   else
02091   {
02092     /* Update the error code */
02093     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02094     /* update return status */
02095     status =  HAL_ERROR;
02096   }
02097 
02098   return status;
02099 }
02100 
02101 /**
02102   * @brief  Unregister a User OSPI Callback
02103   *         OSPI Callback is redirected to the weak (surcharged) predefined callback
02104   * @param hospi : OSPI handle
02105   * @param CallbackID : ID of the callback to be unregistered
02106   *        This parameter can be one of the following values:
02107   *          @arg @ref HAL_OSPI_ERROR_CB_ID          OSPI Error Callback ID
02108   *          @arg @ref HAL_OSPI_ABORT_CB_ID          OSPI Abort Callback ID
02109   *          @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
02110   *          @arg @ref HAL_OSPI_CMD_CPLT_CB_ID       OSPI Command Complete Callback ID
02111   *          @arg @ref HAL_OSPI_RX_CPLT_CB_ID        OSPI Rx Complete Callback ID
02112   *          @arg @ref HAL_OSPI_TX_CPLT_CB_ID        OSPI Tx Complete Callback ID
02113   *          @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID   OSPI Rx Half Complete Callback ID
02114   *          @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID   OSPI Tx Half Complete Callback ID
02115   *          @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID   OSPI Status Match Callback ID
02116   *          @arg @ref HAL_OSPI_TIMEOUT_CB_ID        OSPI Timeout Callback ID
02117   *          @arg @ref HAL_OSPI_MSP_INIT_CB_ID       OSPI MspInit callback ID
02118   *          @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID     OSPI MspDeInit callback ID
02119   * @retval status
02120   */
02121 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
02122 {
02123   HAL_StatusTypeDef status = HAL_OK;
02124 
02125   if(hospi->State == HAL_OSPI_STATE_READY)
02126   {
02127     switch (CallbackID)
02128     {
02129     case  HAL_OSPI_ERROR_CB_ID :
02130       hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
02131       break;
02132     case HAL_OSPI_ABORT_CB_ID :
02133       hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
02134       break;
02135     case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
02136       hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
02137       break;
02138     case HAL_OSPI_CMD_CPLT_CB_ID :
02139       hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
02140       break;
02141     case HAL_OSPI_RX_CPLT_CB_ID :
02142       hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
02143       break;
02144     case HAL_OSPI_TX_CPLT_CB_ID :
02145       hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
02146       break;
02147     case HAL_OSPI_RX_HALF_CPLT_CB_ID :
02148       hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
02149       break;
02150     case HAL_OSPI_TX_HALF_CPLT_CB_ID :
02151       hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
02152       break;
02153     case HAL_OSPI_STATUS_MATCH_CB_ID :
02154       hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
02155       break;
02156     case HAL_OSPI_TIMEOUT_CB_ID :
02157       hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
02158       break;
02159     case HAL_OSPI_MSP_INIT_CB_ID :
02160       hospi->MspInitCallback = HAL_OSPI_MspInit;
02161       break;
02162     case HAL_OSPI_MSP_DEINIT_CB_ID :
02163       hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
02164       break;
02165     default :
02166       /* Update the error code */
02167       hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02168       /* update return status */
02169       status =  HAL_ERROR;
02170       break;
02171     }
02172   }
02173   else if (hospi->State == HAL_OSPI_STATE_RESET)
02174   {
02175     switch (CallbackID)
02176     {
02177     case HAL_OSPI_MSP_INIT_CB_ID :
02178       hospi->MspInitCallback = HAL_OSPI_MspInit;
02179       break;
02180     case HAL_OSPI_MSP_DEINIT_CB_ID :
02181       hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
02182       break;
02183     default :
02184       /* Update the error code */
02185       hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02186       /* update return status */
02187       status =  HAL_ERROR;
02188       break;
02189     }
02190   }
02191   else
02192   {
02193     /* Update the error code */
02194     hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
02195     /* update return status */
02196     status =  HAL_ERROR;
02197   }
02198 
02199   return status;
02200 }
02201 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
02202 
02203 /**
02204   * @}
02205   */
02206 
02207 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
02208   *  @brief   OSPI control and State functions
02209   *
02210 @verbatim
02211  ===============================================================================
02212                   ##### Peripheral Control and State functions #####
02213  ===============================================================================
02214     [..]
02215     This subsection provides a set of functions allowing to :
02216       (+) Check in run-time the state of the driver.
02217       (+) Check the error code set during last operation.
02218       (+) Abort any operation.
02219       (+) Manage the Fifo threshold.
02220       (+) Configure the timeout duration used in the driver.
02221 
02222 @endverbatim
02223   * @{
02224   */
02225 
02226 /**
02227 * @brief  Abort the current transmission.
02228 * @param  hospi : OSPI handle
02229 * @retval HAL status
02230 */
02231 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
02232 {
02233   HAL_StatusTypeDef status = HAL_OK;
02234   uint32_t state;
02235   uint32_t tickstart = HAL_GetTick();
02236 
02237   /* Check if the state is in one of the busy or configured states */
02238   state = hospi->State;
02239   if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
02240   {
02241     /* Check if the DMA is enabled */
02242     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
02243     {
02244       /* Disable the DMA transfer on the OctoSPI side */
02245       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
02246 
02247       /* Disable the DMA transfer on the DMA side */
02248       status = HAL_MDMA_Abort(hospi->hmdma);
02249       if (status != HAL_OK)
02250       {
02251         hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
02252       }
02253     }
02254 
02255     if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
02256     {
02257       /* Perform an abort of the OctoSPI */
02258       SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
02259 
02260       /* Wait until the transfer complete flag is set to go back in idle state */
02261       status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
02262 
02263       if (status == HAL_OK)
02264       {
02265         /* Clear transfer complete flag */
02266         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
02267 
02268         /* Wait until the busy flag is reset to go back in idle state */
02269         status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
02270 
02271         if (status == HAL_OK)
02272         {
02273           /* Update state */
02274           hospi->State = HAL_OSPI_STATE_READY;
02275         }
02276       }
02277     }
02278     else
02279     {
02280       /* Update state */
02281       hospi->State = HAL_OSPI_STATE_READY;
02282     }
02283   }
02284   else
02285   {
02286     status = HAL_ERROR;
02287     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
02288   }
02289 
02290   /* Return function status */
02291   return status;
02292 }
02293 
02294 /**
02295 * @brief  Abort the current transmission (non-blocking function)
02296 * @param  hospi : OSPI handle
02297 * @retval HAL status
02298 */
02299 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
02300 {
02301   HAL_StatusTypeDef status = HAL_OK;
02302   uint32_t state;
02303 
02304   /* Check if the state is in one of the busy or configured states */
02305   state = hospi->State;
02306   if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
02307   {
02308     /* Disable all interrupts */
02309     __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));
02310 
02311     /* Update state */
02312     hospi->State = HAL_OSPI_STATE_ABORT;
02313 
02314     /* Check if the DMA is enabled */
02315     if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
02316     {
02317       /* Disable the DMA transfer on the OctoSPI side */
02318       CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
02319 
02320       /* Disable the DMA transfer on the DMA side */
02321       hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
02322       if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
02323       {
02324         /* Update state */
02325         hospi->State = HAL_OSPI_STATE_READY;
02326 
02327         /* Abort callback */
02328 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
02329         hospi->AbortCpltCallback(hospi);
02330 #else
02331         HAL_OSPI_AbortCpltCallback(hospi);
02332 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
02333       }
02334     }
02335     else
02336     {
02337       if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
02338       {
02339         /* Clear transfer complete flag */
02340         __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
02341 
02342         /* Enable the transfer complete interrupts */
02343         __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
02344 
02345         /* Perform an abort of the OctoSPI */
02346         SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
02347       }
02348       else
02349       {
02350         /* Update state */
02351         hospi->State = HAL_OSPI_STATE_READY;
02352 
02353         /* Abort callback */
02354 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
02355         hospi->AbortCpltCallback(hospi);
02356 #else
02357         HAL_OSPI_AbortCpltCallback(hospi);
02358 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
02359       }
02360     }
02361   }
02362   else
02363   {
02364     status = HAL_ERROR;
02365     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
02366   }
02367 
02368   /* Return function status */
02369   return status;
02370 }
02371 
02372 /** @brief  Set OSPI Fifo threshold.
02373   * @param  hospi     : OSPI handle.
02374   * @param  Threshold : Threshold of the Fifo.
02375   * @retval HAL status
02376   */
02377 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
02378 {
02379   HAL_StatusTypeDef status = HAL_OK;
02380 
02381   /* Check the state */
02382   if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
02383   {
02384     /* Synchronize initialization structure with the new fifo threshold value */
02385     hospi->Init.FifoThreshold = Threshold;
02386 
02387     /* Configure new fifo threshold */
02388     MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos));
02389 
02390   }
02391   else
02392   {
02393     status = HAL_ERROR;
02394     hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
02395   }
02396 
02397   /* Return function status */
02398   return status;
02399 }
02400 
02401 /** @brief  Get OSPI Fifo threshold.
02402   * @param  hospi : OSPI handle.
02403   * @retval Fifo threshold
02404   */
02405 uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef *hospi)
02406 {
02407   return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
02408 }
02409 
02410 /** @brief Set OSPI timeout.
02411   * @param  hospi   : OSPI handle.
02412   * @param  Timeout : Timeout for the memory access.
02413   * @retval None
02414   */
02415 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
02416 {
02417   hospi->Timeout = Timeout;
02418   return HAL_OK;
02419 }
02420 
02421 /**
02422 * @brief  Return the OSPI error code.
02423 * @param  hospi : OSPI handle
02424 * @retval OSPI Error Code
02425 */
02426 uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef *hospi)
02427 {
02428   return hospi->ErrorCode;
02429 }
02430 
02431 /**
02432   * @brief  Return the OSPI handle state.
02433   * @param  hospi : OSPI handle
02434   * @retval HAL state
02435   */
02436 uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef *hospi)
02437 {
02438   /* Return OSPI handle state */
02439   return hospi->State;
02440 }
02441 
02442 /**
02443   * @}
02444   */
02445 
02446 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
02447   *  @brief   OSPI IO Manager configuration function
02448   *
02449 @verbatim
02450  ===============================================================================
02451                   ##### IO Manager configuration function #####
02452  ===============================================================================
02453     [..]
02454     This subsection provides a set of functions allowing to :
02455       (+) Configure the IO manager.
02456 
02457 @endverbatim
02458   * @{
02459   */
02460 
02461 /**
02462   * @brief  Configure the OctoSPI IO manager.
02463   * @param  hospi   : OSPI handle
02464   * @param  cfg     : Configuration of the IO Manager for the instance
02465   * @param  Timeout : Timeout duration
02466   * @retval HAL status
02467   */
02468 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
02469 {
02470   HAL_StatusTypeDef status = HAL_OK;
02471   uint32_t instance;
02472   uint8_t index;
02473   uint8_t ospi_enabled = 0U;
02474   uint8_t other_instance;
02475   OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
02476 
02477   /* Prevent unused argument(s) compilation warning */
02478   UNUSED(Timeout);
02479 
02480   /* Check the parameters of the OctoSPI IO Manager configuration structure */
02481   assert_param(IS_OSPIM_PORT(cfg->ClkPort));
02482   assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
02483   assert_param(IS_OSPIM_PORT(cfg->NCSPort));
02484   assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
02485   assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
02486   assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime));
02487 
02488   if (hospi->Instance == OCTOSPI1)
02489   {
02490     instance = 0U;
02491     other_instance = 1U;
02492   }
02493   else
02494   {
02495     instance = 1U;
02496     other_instance = 0U;
02497   }
02498 
02499   /**************** Get current configuration of the instances ****************/
02500   for (index = 0U; index < OSPI_NB_INSTANCE; index++)
02501   {
02502     if (OSPIM_GetConfig(index+1U, &(IOM_cfg[index])) != HAL_OK)
02503     {
02504       status = HAL_ERROR;
02505       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
02506     }
02507   }
02508 
02509   if (status == HAL_OK)
02510   {
02511     /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
02512     if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
02513     {
02514       CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
02515       ospi_enabled |= 0x1U;
02516     }
02517     if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
02518     {
02519       CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
02520       ospi_enabled |= 0x2U;
02521     }
02522 
02523     /***************** Deactivation of previous configuration *****************/
02524     CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
02525     if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
02526     {
02527       /* De-multiplexing should be performed */
02528       CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
02529 
02530       if (other_instance == 1U)
02531       {
02532         SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKSRC);
02533         if (IOM_cfg[other_instance].DQSPort != 0U)
02534         {
02535           SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSSRC);
02536         }
02537         if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
02538         {
02539           SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLSRC_1);
02540         }
02541         if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
02542         {
02543           SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHSRC_1);
02544         }
02545       }
02546     }
02547     else
02548     {
02549       if (IOM_cfg[instance].ClkPort != 0U)
02550       {
02551         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
02552         if (IOM_cfg[instance].DQSPort != 0U)
02553         {
02554           CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
02555         }
02556         if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
02557         {
02558           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
02559         }
02560         if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
02561         {
02562           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
02563         }
02564       }
02565     }
02566 
02567     /********************* Deactivation of other instance *********************/
02568     if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort)     ||
02569         (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
02570         (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
02571     {
02572       if ((cfg->ClkPort   == IOM_cfg[other_instance].ClkPort)   &&
02573           (cfg->DQSPort    == IOM_cfg[other_instance].DQSPort)  &&
02574           (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
02575           (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
02576       {
02577         /* Multiplexing should be performed */
02578         SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
02579       }
02580       else
02581       {
02582         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
02583         if (IOM_cfg[other_instance].DQSPort != 0U)
02584         {
02585           CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
02586         }
02587         CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
02588         if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
02589         {
02590           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)],
02591                     OCTOSPIM_PCR_IOLEN);
02592         }
02593         if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
02594         {
02595           CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)],
02596                     OCTOSPIM_PCR_IOHEN);
02597         }
02598       }
02599     }
02600 
02601     /******************** Activation of new configuration *********************/
02602         MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
02603                   (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
02604 
02605     if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
02606     {
02607       MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
02608     }
02609 
02610     if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
02611     {
02612       MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
02613       if (cfg->DQSPort != 0U)
02614       {
02615         MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
02616       }
02617 
02618       if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
02619       {
02620         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)],
02621                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
02622       }
02623       else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
02624       {
02625         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)],
02626                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
02627       }
02628       else
02629       {
02630          /* Nothing to do */
02631       }
02632 
02633       if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
02634       {
02635         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)],
02636                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
02637       }
02638       else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
02639       {
02640         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)],
02641                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
02642       }
02643       else
02644       {
02645          /* Nothing to do */
02646       }
02647     }
02648     else
02649     {
02650       MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
02651                 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
02652       if (cfg->DQSPort != 0U)
02653       {
02654         MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
02655                   (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
02656       }
02657 
02658       if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
02659       {
02660         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)],
02661                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
02662                   (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
02663       }
02664       else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
02665       {
02666         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)],
02667                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
02668                   (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
02669       }
02670       else
02671       {
02672          /* Nothing to do */
02673       }
02674 
02675       if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
02676       {
02677         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)],
02678                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
02679                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
02680       }
02681       else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
02682       {
02683         MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)],
02684                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
02685                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
02686       }
02687       else
02688       {
02689          /* Nothing to do */
02690       }
02691     }
02692 
02693     /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
02694     if ((ospi_enabled & 0x1U) != 0U)
02695     {
02696       SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
02697     }
02698     if ((ospi_enabled & 0x2U) != 0U)
02699     {
02700       SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
02701     }
02702   }
02703 
02704   /* Return function status */
02705   return status;
02706 }
02707 
02708 /**
02709   * @}
02710   */
02711 
02712 /**
02713   @cond 0
02714   */
02715 /**
02716   * @brief  DMA OSPI process complete callback.
02717   * @param  hdma : DMA handle
02718   * @retval None
02719   */
02720 static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma)
02721 {
02722   OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
02723   hospi->XferCount = 0;
02724 
02725   /* Disable the DMA transfer on the OctoSPI side */
02726   CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
02727 
02728   /* Disable the DMA channel */
02729   __HAL_MDMA_DISABLE(hmdma);
02730 
02731   /* Enable the OSPI transfer complete Interrupt */
02732   __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
02733 }
02734 
02735 /**
02736   * @brief  DMA OSPI communication error callback.
02737   * @param  hdma : DMA handle
02738   * @retval None
02739   */
02740 static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma)
02741 {
02742   OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
02743   hospi->XferCount = 0;
02744   hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
02745 
02746   /* Disable the DMA transfer on the OctoSPI side */
02747   CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
02748 
02749   /* Abort the OctoSPI */
02750   if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
02751   {
02752     /* Disable the interrupts */
02753     __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
02754 
02755     /* Update state */
02756     hospi->State = HAL_OSPI_STATE_READY;
02757 
02758     /* Error callback */
02759 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
02760     hospi->ErrorCallback(hospi);
02761 #else
02762     HAL_OSPI_ErrorCallback(hospi);
02763 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
02764   }
02765 }
02766 
02767 /**
02768   * @brief  DMA OSPI abort complete callback.
02769   * @param  hdma : DMA handle
02770   * @retval None
02771   */
02772 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
02773 {
02774   OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
02775   hospi->XferCount = 0;
02776 
02777   /* Check the state */
02778   if (hospi->State == HAL_OSPI_STATE_ABORT)
02779   {
02780     /* DMA abort called by OctoSPI abort */
02781     if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
02782     {
02783       /* Clear transfer complete flag */
02784       __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
02785 
02786       /* Enable the transfer complete interrupts */
02787       __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
02788 
02789       /* Perform an abort of the OctoSPI */
02790       SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
02791     }
02792     else
02793     {
02794       /* Update state */
02795       hospi->State = HAL_OSPI_STATE_READY;
02796 
02797       /* Abort callback */
02798 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
02799       hospi->AbortCpltCallback(hospi);
02800 #else
02801       HAL_OSPI_AbortCpltCallback(hospi);
02802 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
02803     }
02804   }
02805   else
02806   {
02807     /* DMA abort called due to a transfer error interrupt */
02808     /* Update state */
02809     hospi->State = HAL_OSPI_STATE_READY;
02810 
02811     /* Error callback */
02812 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
02813     hospi->ErrorCallback(hospi);
02814 #else
02815     HAL_OSPI_ErrorCallback(hospi);
02816 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
02817   }
02818 }
02819 
02820 /**
02821   * @brief  Wait for a flag state until timeout.
02822   * @param  hospi     : OSPI handle
02823   * @param  Flag      : Flag checked
02824   * @param  State     : Value of the flag expected
02825   * @param  Timeout   : Duration of the timeout
02826   * @param  Tickstart : Tick start value
02827   * @retval HAL status
02828   */
02829 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
02830                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
02831 {
02832   /* Wait until flag is in expected state */
02833   while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
02834   {
02835     /* Check for the Timeout */
02836     if (Timeout != HAL_MAX_DELAY)
02837     {
02838       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
02839       {
02840         hospi->State     = HAL_OSPI_STATE_ERROR;
02841         hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
02842 
02843         return HAL_ERROR;
02844       }
02845     }
02846   }
02847   return HAL_OK;
02848 }
02849 
02850 /**
02851   * @brief  Configure the registers for the regular command mode.
02852   * @param  hospi : OSPI handle
02853   * @param  cmd   : structure that contains the command configuration information
02854   * @retval HAL status
02855   */
02856 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
02857 {
02858   HAL_StatusTypeDef status = HAL_OK;
02859   __IO uint32_t *ccr_reg;
02860   __IO uint32_t *tcr_reg;
02861   __IO uint32_t *ir_reg;
02862   __IO uint32_t *abr_reg;
02863 
02864   /* Re-initialize the value of the functional mode */
02865   MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
02866 
02867   /* Configure the flash ID */
02868   if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
02869   {
02870     MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
02871   }
02872 
02873   if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
02874   {
02875     ccr_reg = &(hospi->Instance->WCCR);
02876     tcr_reg = &(hospi->Instance->WTCR);
02877     ir_reg  = &(hospi->Instance->WIR);
02878     abr_reg = &(hospi->Instance->WABR);
02879   }
02880   else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
02881   {
02882     ccr_reg = &(hospi->Instance->WPCCR);
02883     tcr_reg = &(hospi->Instance->WPTCR);
02884     ir_reg  = &(hospi->Instance->WPIR);
02885     abr_reg = &(hospi->Instance->WPABR);
02886   }
02887   else
02888   {
02889     ccr_reg = &(hospi->Instance->CCR);
02890     tcr_reg = &(hospi->Instance->TCR);
02891     ir_reg  = &(hospi->Instance->IR);
02892     abr_reg = &(hospi->Instance->ABR);
02893   }
02894 
02895   /* Configure the CCR register with DQS and SIOO modes */
02896   *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
02897 
02898   if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
02899   {
02900     /* Configure the ABR register with alternate bytes value */
02901     *abr_reg = cmd->AlternateBytes;
02902 
02903     /* Configure the CCR register with alternate bytes communication parameters */
02904     MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
02905                            (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
02906   }
02907 
02908   /* Configure the TCR register with the number of dummy cycles */
02909   MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
02910 
02911   if (cmd->DataMode != HAL_OSPI_DATA_NONE)
02912   {
02913     if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
02914     {
02915       /* Configure the DLR register with the number of data */
02916       hospi->Instance->DLR = (cmd->NbData - 1U);
02917     }
02918   }
02919 
02920   if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
02921   {
02922     if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
02923     {
02924       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
02925       {
02926         /* ---- Command with instruction, address and data ---- */
02927 
02928         /* Configure the CCR register with all communication parameters */
02929         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
02930                                 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
02931                                 OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
02932                                (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
02933                                 cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize     |
02934                                 cmd->DataMode        | cmd->DataDtrMode));
02935       }
02936       else
02937       {
02938         /* ---- Command with instruction and address ---- */
02939 
02940         /* Configure the CCR register with all communication parameters */
02941         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE  | OCTOSPI_CCR_IDTR  | OCTOSPI_CCR_ISIZE  |
02942                                 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
02943                                (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
02944                                 cmd->AddressMode     | cmd->AddressDtrMode     | cmd->AddressSize));
02945 
02946         /* The DHQC bit is linked with DDTR bit which should be activated */
02947         if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
02948             (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
02949         {
02950           MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
02951         }
02952       }
02953 
02954       /* Configure the IR register with the instruction value */
02955       *ir_reg = cmd->Instruction;
02956 
02957       /* Configure the AR register with the address value */
02958       hospi->Instance->AR = cmd->Address;
02959     }
02960     else
02961     {
02962       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
02963       {
02964         /* ---- Command with instruction and data ---- */
02965 
02966         /* Configure the CCR register with all communication parameters */
02967         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
02968                                 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
02969                                (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
02970                                 cmd->DataMode        | cmd->DataDtrMode));
02971       }
02972       else
02973       {
02974         /* ---- Command with only instruction ---- */
02975 
02976         /* Configure the CCR register with all communication parameters */
02977         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
02978                                (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
02979 
02980         /* The DHQC bit is linked with DDTR bit which should be activated */
02981         if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
02982             (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
02983         {
02984           MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
02985         }
02986       }
02987 
02988       /* Configure the IR register with the instruction value */
02989       *ir_reg = cmd->Instruction;
02990 
02991     }
02992   }
02993   else
02994   {
02995     if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
02996     {
02997       if (cmd->DataMode != HAL_OSPI_DATA_NONE)
02998       {
02999         /* ---- Command with address and data ---- */
03000 
03001         /* Configure the CCR register with all communication parameters */
03002         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
03003                                 OCTOSPI_CCR_DMODE  | OCTOSPI_CCR_DDTR),
03004                                (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize     |
03005                                 cmd->DataMode    | cmd->DataDtrMode));
03006       }
03007       else
03008       {
03009         /* ---- Command with only address ---- */
03010 
03011         /* Configure the CCR register with all communication parameters */
03012         MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
03013                                (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
03014       }
03015 
03016       /* Configure the AR register with the instruction value */
03017       hospi->Instance->AR = cmd->Address;
03018     }
03019     else
03020     {
03021       /* ---- Invalid command configuration (no instruction, no address) ---- */
03022       status = HAL_ERROR;
03023       hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
03024     }
03025   }
03026 
03027   /* Return function status */
03028   return status;
03029 }
03030 
03031 /**
03032   * @brief  Get the current IOM configuration for an OctoSPI instance.
03033   * @param  instance_nb : number of the instance
03034   * @param  cfg         : configuration of the IO Manager for the instance
03035   * @retval HAL status
03036   */
03037 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
03038 {
03039   HAL_StatusTypeDef status = HAL_OK;
03040   uint32_t reg;
03041   uint32_t value = 0U;
03042   uint32_t index;
03043 
03044   if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
03045   {
03046     /* Invalid parameter -> error returned */
03047     status = HAL_ERROR;
03048   }
03049   else
03050   {
03051     /* Initialize the structure */
03052     cfg->ClkPort    = 0U;
03053     cfg->DQSPort    = 0U;
03054     cfg->NCSPort    = 0U;
03055     cfg->IOLowPort  = 0U;
03056     cfg->IOHighPort = 0U;
03057 
03058     if (instance_nb == 2U)
03059     {
03060       if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
03061       {
03062         value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC
03063                | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
03064       }
03065       else
03066       {
03067         value = OCTOSPIM_PCR_NCSSRC;
03068       }
03069     }
03070 
03071     /* Get the information about the instance */
03072     for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
03073     {
03074       reg = OCTOSPIM->PCR[index];
03075 
03076       if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
03077       {
03078         /* The clock is enabled on this port */
03079         if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
03080         {
03081           /* The clock correspond to the instance passed as parameter */
03082           cfg->ClkPort = index+1U;
03083         }
03084       }
03085 
03086       if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
03087       {
03088         /* The DQS is enabled on this port */
03089         if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
03090         {
03091           /* The DQS correspond to the instance passed as parameter */
03092           cfg->DQSPort = index+1U;
03093         }
03094       }
03095 
03096       if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
03097       {
03098         /* The nCS is enabled on this port */
03099         if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
03100         {
03101           /* The nCS correspond to the instance passed as parameter */
03102           cfg->NCSPort = index+1U;
03103         }
03104       }
03105 
03106       if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
03107       {
03108         /* The IO Low is enabled on this port */
03109         if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
03110         {
03111           /* The IO Low correspond to the instance passed as parameter */
03112           if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
03113           {
03114             cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
03115           }
03116           else
03117           {
03118             cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
03119           }
03120         }
03121       }
03122 
03123       if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
03124       {
03125         /* The IO High is enabled on this port */
03126         if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
03127         {
03128           /* The IO High correspond to the instance passed as parameter */
03129           if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
03130           {
03131             cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
03132           }
03133           else
03134           {
03135             cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
03136           }
03137         }
03138       }
03139     }
03140   }
03141 
03142   /* Return function status */
03143   return status;
03144 }
03145 
03146 /**
03147   @endcond
03148   */
03149 
03150 /**
03151   * @}
03152   */
03153 
03154 #endif /* HAL_OSPI_MODULE_ENABLED */
03155 
03156 /**
03157   * @}
03158   */
03159 
03160 /**
03161   * @}
03162   */
03163 
03164 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */