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