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