STM32L443xx HAL User Manual
stm32l4xx_hal_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_qspi.c
00004   * @author  MCD Application Team
00005   * @brief   QSPI HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the QuadSPI interface (QSPI).
00008   *           + Initialization and de-initialization functions
00009   *           + Indirect functional mode management
00010   *           + Memory-mapped functional mode management
00011   *           + Auto-polling functional mode management
00012   *           + Interrupts and flags management
00013   *           + DMA channel configuration for indirect functional mode
00014   *           + Errors management and abort functionality
00015   *
00016   *
00017   ******************************************************************************
00018   * @attention
00019   *
00020   * Copyright (c) 2017 STMicroelectronics.
00021   * All rights reserved.
00022   *
00023   * This software is licensed under terms that can be found in the LICENSE file
00024   * in the root directory of this software component.
00025   * If no LICENSE file comes with this software, it is provided AS-IS.
00026   *
00027   ******************************************************************************
00028   @verbatim
00029  ===============================================================================
00030                         ##### How to use this driver #####
00031  ===============================================================================
00032   [..]
00033     *** Initialization ***
00034     ======================
00035     [..]
00036       (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
00037         (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
00038         (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
00039         (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
00040         (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
00041         (++) If interrupt mode is used, enable and configure QuadSPI global
00042             interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00043         (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
00044             with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
00045             link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
00046             DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00047       (#) Configure the flash size, the clock prescaler, the fifo threshold, the
00048           clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
00049 
00050     *** Indirect functional mode ***
00051     ================================
00052     [..]
00053       (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
00054           functions :
00055          (++) Instruction phase : the mode used and if present the instruction opcode.
00056          (++) Address phase : the mode used and if present the size and the address value.
00057          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
00058              bytes values.
00059          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00060          (++) Data phase : the mode used and if present the number of bytes.
00061          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
00062              if activated.
00063          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00064       (#) If no data is required for the command, it is sent directly to the memory :
00065          (++) In polling mode, the output of the function is done when the transfer is complete.
00066          (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
00067       (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
00068           HAL_QSPI_Transmit_IT() after the command configuration :
00069          (++) In polling mode, the output of the function is done when the transfer is complete.
00070          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
00071              is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
00072          (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
00073              HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
00074       (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
00075           HAL_QSPI_Receive_IT() after the command configuration :
00076          (++) In polling mode, the output of the function is done when the transfer is complete.
00077          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
00078              is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
00079          (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
00080              HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
00081 
00082     *** Auto-polling functional mode ***
00083     ====================================
00084     [..]
00085       (#) Configure the command sequence and the auto-polling functional mode using the
00086           HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
00087          (++) Instruction phase : the mode used and if present the instruction opcode.
00088          (++) Address phase : the mode used and if present the size and the address value.
00089          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
00090              bytes values.
00091          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00092          (++) Data phase : the mode used.
00093          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
00094              if activated.
00095          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00096          (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
00097              the polling interval and the automatic stop activation.
00098       (#) After the configuration :
00099          (++) In polling mode, the output of the function is done when the status match is reached. The
00100              automatic stop is activated to avoid an infinite loop.
00101          (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
00102 
00103     *** Memory-mapped functional mode ***
00104     =====================================
00105     [..]
00106       (#) Configure the command sequence and the memory-mapped functional mode using the
00107           HAL_QSPI_MemoryMapped() functions :
00108          (++) Instruction phase : the mode used and if present the instruction opcode.
00109          (++) Address phase : the mode used and the size.
00110          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
00111              bytes values.
00112          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00113          (++) Data phase : the mode used.
00114          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
00115              if activated.
00116          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00117          (++) The timeout activation and the timeout period.
00118       (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
00119           the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
00120 
00121     *** Errors management and abort functionality ***
00122     =================================================
00123     [..]
00124       (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
00125       (#) HAL_QSPI_Abort() and HAL_QSPI_Abort_IT() functions aborts any on-going operation and
00126           flushes the fifo :
00127          (++) In polling mode, the output of the function is done when the transfer
00128               complete bit is set and the busy bit cleared.
00129          (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
00130               the transfer complete bit is set.
00131 
00132     *** Control functions ***
00133     =========================
00134     [..]
00135       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
00136       (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
00137       (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
00138       (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
00139       (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
00140 
00141     *** Callback registration ***
00142     =============================================
00143     [..]
00144       The compilation define  USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
00145       allows the user to configure dynamically the driver callbacks.
00146 
00147       Use Functions HAL_QSPI_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    : QSPI MspInit.
00160         (+) MspDeInitCallback  : QSPI 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 HAL_QSPI_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    : QSPI MspInit.
00177         (+) MspDeInitCallback  : QSPI MspDeInit.
00178       This function) takes as parameters the HAL peripheral handle and the Callback ID.
00179 
00180       By default, after the HAL_QSPI_Init and if the state is HAL_QSPI_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 HAL_QSPI_Init
00184       and  HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
00185       If not, MspInit or MspDeInit are not null, the HAL_QSPI_Init and HAL_QSPI_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 HAL_QSPI_RegisterCallback before calling HAL_QSPI_DeInit
00194       or HAL_QSPI_Init function.
00195 
00196       When The compilation define USE_HAL_QSPI_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     *** Workarounds linked to Silicon Limitation ***
00201     ====================================================
00202     [..]
00203       (#) Workarounds Implemented inside HAL Driver
00204          (++) Extra data written in the FIFO at the end of a read transfer
00205 
00206   @endverbatim
00207   ******************************************************************************
00208   */
00209 
00210 /* Includes ------------------------------------------------------------------*/
00211 #include "stm32l4xx_hal.h"
00212 
00213 #if defined(QUADSPI)
00214 
00215 /** @addtogroup STM32L4xx_HAL_Driver
00216   * @{
00217   */
00218 
00219 /** @defgroup QSPI QSPI
00220   * @brief QSPI HAL module driver
00221   * @{
00222   */
00223 #ifdef HAL_QSPI_MODULE_ENABLED
00224 
00225 /* Private typedef -----------------------------------------------------------*/
00226 
00227 /* Private define ------------------------------------------------------------*/
00228 /** @defgroup QSPI_Private_Constants QSPI Private Constants
00229   * @{
00230   */
00231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U                     /*!<Indirect write mode*/
00232 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
00233 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
00234 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/
00235 /**
00236   * @}
00237   */
00238 
00239 /* Private macro -------------------------------------------------------------*/
00240 /** @defgroup QSPI_Private_Macros QSPI Private Macros
00241   * @{
00242   */
00243 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
00244                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
00245                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
00246                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
00247 /**
00248   * @}
00249   */
00250 
00251 /* Private variables ---------------------------------------------------------*/
00252 
00253 /* Private function prototypes -----------------------------------------------*/
00254 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
00255 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
00256 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00257 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00258 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
00259 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
00260 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
00261 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
00262 
00263 /* Exported functions --------------------------------------------------------*/
00264 
00265 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
00266   * @{
00267   */
00268 
00269 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
00270   *  @brief    Initialization and Configuration functions
00271   *
00272 @verbatim
00273 ===============================================================================
00274             ##### Initialization and Configuration functions #####
00275  ===============================================================================
00276     [..]
00277     This subsection provides a set of functions allowing to :
00278       (+) Initialize the QuadSPI.
00279       (+) De-initialize the QuadSPI.
00280 
00281 @endverbatim
00282   * @{
00283   */
00284 
00285 /**
00286   * @brief Initialize the QSPI mode according to the specified parameters
00287   *        in the QSPI_InitTypeDef and initialize the associated handle.
00288   * @param hqspi QSPI handle
00289   * @retval HAL status
00290   */
00291 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
00292 {
00293   HAL_StatusTypeDef status;
00294   uint32_t tickstart = HAL_GetTick();
00295 
00296   /* Check the QSPI handle allocation */
00297   if(hqspi == NULL)
00298   {
00299     return HAL_ERROR;
00300   }
00301 
00302   /* Check the parameters */
00303   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
00304   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
00305   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
00306   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
00307   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
00308   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
00309   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
00310 #if defined(QUADSPI_CR_DFM)
00311   assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
00312 
00313   if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
00314   {
00315     assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
00316   }
00317 #endif
00318 
00319   if(hqspi->State == HAL_QSPI_STATE_RESET)
00320   {
00321     /* Allocate lock resource and initialize it */
00322     hqspi->Lock = HAL_UNLOCKED;
00323 
00324 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00325     /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
00326     hqspi->ErrorCallback         = HAL_QSPI_ErrorCallback;
00327     hqspi->AbortCpltCallback     = HAL_QSPI_AbortCpltCallback;
00328     hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
00329     hqspi->CmdCpltCallback       = HAL_QSPI_CmdCpltCallback;
00330     hqspi->RxCpltCallback        = HAL_QSPI_RxCpltCallback;
00331     hqspi->TxCpltCallback        = HAL_QSPI_TxCpltCallback;
00332     hqspi->RxHalfCpltCallback    = HAL_QSPI_RxHalfCpltCallback;
00333     hqspi->TxHalfCpltCallback    = HAL_QSPI_TxHalfCpltCallback;
00334     hqspi->StatusMatchCallback   = HAL_QSPI_StatusMatchCallback;
00335     hqspi->TimeOutCallback       = HAL_QSPI_TimeOutCallback;
00336 
00337     if(hqspi->MspInitCallback == NULL)
00338     {
00339       hqspi->MspInitCallback = HAL_QSPI_MspInit;
00340     }
00341 
00342     /* Init the low level hardware */
00343     hqspi->MspInitCallback(hqspi);
00344 #else
00345     /* Init the low level hardware : GPIO, CLOCK */
00346     HAL_QSPI_MspInit(hqspi);
00347 #endif
00348 
00349     /* Configure the default timeout for the QSPI memory access */
00350     HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
00351   }
00352 
00353   /* Configure QSPI FIFO Threshold */
00354   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
00355              ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
00356 
00357   /* Wait till BUSY flag reset */
00358   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
00359 
00360   if(status == HAL_OK)
00361   {
00362     /* Configure QSPI Clock Prescaler and Sample Shift */
00363 #if defined(QUADSPI_CR_DFM)
00364     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
00365                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
00366                 hqspi->Init.SampleShifting  | hqspi->Init.FlashID | hqspi->Init.DualFlash));
00367 #else
00368     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT),
00369                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
00370                 hqspi->Init.SampleShifting));
00371 #endif
00372 
00373     /* Configure QSPI Flash Size, CS High Time and Clock Mode */
00374     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
00375                ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
00376                 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
00377 
00378     /* Enable the QSPI peripheral */
00379     __HAL_QSPI_ENABLE(hqspi);
00380 
00381     /* Set QSPI error code to none */
00382     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00383 
00384     /* Initialize the QSPI state */
00385     hqspi->State = HAL_QSPI_STATE_READY;
00386   }
00387 
00388   /* Release Lock */
00389   __HAL_UNLOCK(hqspi);
00390 
00391   /* Return function status */
00392   return status;
00393 }
00394 
00395 /**
00396   * @brief De-Initialize the QSPI peripheral.
00397   * @param hqspi QSPI handle
00398   * @retval HAL status
00399   */
00400 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
00401 {
00402   /* Check the QSPI handle allocation */
00403   if(hqspi == NULL)
00404   {
00405     return HAL_ERROR;
00406   }
00407 
00408   /* Disable the QSPI Peripheral Clock */
00409   __HAL_QSPI_DISABLE(hqspi);
00410 
00411 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00412   if(hqspi->MspDeInitCallback == NULL)
00413   {
00414     hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
00415   }
00416 
00417   /* DeInit the low level hardware */
00418   hqspi->MspDeInitCallback(hqspi);
00419 #else
00420   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00421   HAL_QSPI_MspDeInit(hqspi);
00422 #endif
00423 
00424   /* Set QSPI error code to none */
00425   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00426 
00427   /* Initialize the QSPI state */
00428   hqspi->State = HAL_QSPI_STATE_RESET;
00429 
00430   /* Release Lock */
00431   __HAL_UNLOCK(hqspi);
00432 
00433   return HAL_OK;
00434 }
00435 
00436 /**
00437   * @brief Initialize the QSPI MSP.
00438   * @param hqspi QSPI handle
00439   * @retval None
00440   */
00441 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
00442 {
00443   /* Prevent unused argument(s) compilation warning */
00444   UNUSED(hqspi);
00445 
00446   /* NOTE : This function should not be modified, when the callback is needed,
00447             the HAL_QSPI_MspInit can be implemented in the user file
00448    */
00449 }
00450 
00451 /**
00452   * @brief DeInitialize the QSPI MSP.
00453   * @param hqspi QSPI handle
00454   * @retval None
00455   */
00456 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
00457 {
00458   /* Prevent unused argument(s) compilation warning */
00459   UNUSED(hqspi);
00460 
00461   /* NOTE : This function should not be modified, when the callback is needed,
00462             the HAL_QSPI_MspDeInit can be implemented in the user file
00463    */
00464 }
00465 
00466 /**
00467   * @}
00468   */
00469 
00470 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
00471   *  @brief QSPI Transmit/Receive functions
00472   *
00473 @verbatim
00474  ===============================================================================
00475                       ##### IO operation functions #####
00476  ===============================================================================
00477     [..]
00478     This subsection provides a set of functions allowing to :
00479       (+) Handle the interrupts.
00480       (+) Handle the command sequence.
00481       (+) Transmit data in blocking, interrupt or DMA mode.
00482       (+) Receive data in blocking, interrupt or DMA mode.
00483       (+) Manage the auto-polling functional mode.
00484       (+) Manage the memory-mapped functional mode.
00485 
00486 @endverbatim
00487   * @{
00488   */
00489 
00490 /**
00491   * @brief Handle QSPI interrupt request.
00492   * @param hqspi QSPI handle
00493   * @retval None
00494   */
00495 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
00496 {
00497   __IO uint32_t *data_reg;
00498   uint32_t flag = READ_REG(hqspi->Instance->SR);
00499   uint32_t itsource = READ_REG(hqspi->Instance->CR);
00500 
00501   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
00502   if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
00503   {
00504     data_reg = &hqspi->Instance->DR;
00505 
00506     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00507     {
00508       /* Transmission process */
00509       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
00510       {
00511         if (hqspi->TxXferCount > 0U)
00512         {
00513           /* Fill the FIFO until the threshold is reached */
00514           *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
00515           hqspi->pTxBuffPtr++;
00516           hqspi->TxXferCount--;
00517         }
00518         else
00519         {
00520           /* No more data available for the transfer */
00521           /* Disable the QSPI FIFO Threshold Interrupt */
00522           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
00523           break;
00524         }
00525       }
00526     }
00527     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00528     {
00529       /* Receiving Process */
00530       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
00531       {
00532         if (hqspi->RxXferCount > 0U)
00533         {
00534           /* Read the FIFO until the threshold is reached */
00535           *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
00536           hqspi->pRxBuffPtr++;
00537           hqspi->RxXferCount--;
00538         }
00539         else
00540         {
00541           /* All data have been received for the transfer */
00542           /* Disable the QSPI FIFO Threshold Interrupt */
00543           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
00544           break;
00545         }
00546       }
00547     }
00548     else
00549     {
00550       /* Nothing to do */
00551     }
00552 
00553     /* FIFO Threshold callback */
00554 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00555     hqspi->FifoThresholdCallback(hqspi);
00556 #else
00557     HAL_QSPI_FifoThresholdCallback(hqspi);
00558 #endif
00559   }
00560 
00561   /* QSPI Transfer Complete interrupt occurred -------------------------------*/
00562   else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
00563   {
00564     /* Clear interrupt */
00565     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
00566 
00567     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
00568     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00569 
00570     /* Transfer complete callback */
00571     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00572     {
00573       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
00574       {
00575         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00576         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00577 
00578         /* Disable the DMA channel */
00579         __HAL_DMA_DISABLE(hqspi->hdma);
00580       }
00581 
00582 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
00583       /* Clear Busy bit */
00584       HAL_QSPI_Abort_IT(hqspi);
00585 #endif
00586 
00587       /* Change state of QSPI */
00588       hqspi->State = HAL_QSPI_STATE_READY;
00589 
00590       /* TX Complete callback */
00591 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00592       hqspi->TxCpltCallback(hqspi);
00593 #else
00594       HAL_QSPI_TxCpltCallback(hqspi);
00595 #endif
00596     }
00597     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00598     {
00599       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
00600       {
00601         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00602         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00603 
00604         /* Disable the DMA channel */
00605         __HAL_DMA_DISABLE(hqspi->hdma);
00606       }
00607       else
00608       {
00609         data_reg = &hqspi->Instance->DR;
00610         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
00611         {
00612           if (hqspi->RxXferCount > 0U)
00613           {
00614             /* Read the last data received in the FIFO until it is empty */
00615             *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
00616             hqspi->pRxBuffPtr++;
00617             hqspi->RxXferCount--;
00618           }
00619           else
00620           {
00621             /* All data have been received for the transfer */
00622             break;
00623           }
00624         }
00625       }
00626 
00627 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
00628       /* Workaround - Extra data written in the FIFO at the end of a read transfer */
00629       HAL_QSPI_Abort_IT(hqspi);
00630 #endif
00631 
00632       /* Change state of QSPI */
00633       hqspi->State = HAL_QSPI_STATE_READY;
00634 
00635       /* RX Complete callback */
00636 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00637       hqspi->RxCpltCallback(hqspi);
00638 #else
00639       HAL_QSPI_RxCpltCallback(hqspi);
00640 #endif
00641     }
00642     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
00643     {
00644       /* Change state of QSPI */
00645       hqspi->State = HAL_QSPI_STATE_READY;
00646 
00647       /* Command Complete callback */
00648 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00649       hqspi->CmdCpltCallback(hqspi);
00650 #else
00651       HAL_QSPI_CmdCpltCallback(hqspi);
00652 #endif
00653     }
00654     else if(hqspi->State == HAL_QSPI_STATE_ABORT)
00655     {
00656       /* Reset functional mode configuration to indirect write mode by default */
00657       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
00658 
00659       /* Change state of QSPI */
00660       hqspi->State = HAL_QSPI_STATE_READY;
00661 
00662       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
00663       {
00664         /* Abort called by the user */
00665 
00666         /* Abort Complete callback */
00667 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00668         hqspi->AbortCpltCallback(hqspi);
00669 #else
00670         HAL_QSPI_AbortCpltCallback(hqspi);
00671 #endif
00672       }
00673       else
00674       {
00675         /* Abort due to an error (eg :  DMA error) */
00676 
00677         /* Error callback */
00678 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00679         hqspi->ErrorCallback(hqspi);
00680 #else
00681         HAL_QSPI_ErrorCallback(hqspi);
00682 #endif
00683       }
00684     }
00685     else
00686     {
00687      /* Nothing to do */
00688     }
00689   }
00690 
00691   /* QSPI Status Match interrupt occurred ------------------------------------*/
00692   else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
00693   {
00694     /* Clear interrupt */
00695     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
00696 
00697     /* Check if the automatic poll mode stop is activated */
00698     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
00699     {
00700       /* Disable the QSPI Transfer Error and Status Match Interrupts */
00701       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
00702 
00703       /* Change state of QSPI */
00704       hqspi->State = HAL_QSPI_STATE_READY;
00705     }
00706 
00707     /* Status match callback */
00708 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00709     hqspi->StatusMatchCallback(hqspi);
00710 #else
00711     HAL_QSPI_StatusMatchCallback(hqspi);
00712 #endif
00713   }
00714 
00715   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
00716   else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
00717   {
00718     /* Clear interrupt */
00719     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
00720 
00721     /* Disable all the QSPI Interrupts */
00722     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00723 
00724     /* Set error code */
00725     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
00726 
00727     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
00728     {
00729       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00730       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00731 
00732       /* Disable the DMA channel */
00733       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
00734       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
00735       {
00736         /* Set error code to DMA */
00737         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
00738 
00739         /* Change state of QSPI */
00740         hqspi->State = HAL_QSPI_STATE_READY;
00741 
00742         /* Error callback */
00743 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00744         hqspi->ErrorCallback(hqspi);
00745 #else
00746         HAL_QSPI_ErrorCallback(hqspi);
00747 #endif
00748       }
00749     }
00750     else
00751     {
00752       /* Change state of QSPI */
00753       hqspi->State = HAL_QSPI_STATE_READY;
00754 
00755       /* Error callback */
00756 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00757       hqspi->ErrorCallback(hqspi);
00758 #else
00759       HAL_QSPI_ErrorCallback(hqspi);
00760 #endif
00761     }
00762   }
00763 
00764   /* QSPI Timeout interrupt occurred -----------------------------------------*/
00765   else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
00766   {
00767     /* Clear interrupt */
00768     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
00769 
00770     /* Timeout callback */
00771 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
00772     hqspi->TimeOutCallback(hqspi);
00773 #else
00774     HAL_QSPI_TimeOutCallback(hqspi);
00775 #endif
00776   }
00777 
00778    else
00779   {
00780    /* Nothing to do */
00781   }
00782 }
00783 
00784 /**
00785   * @brief Set the command configuration.
00786   * @param hqspi QSPI handle
00787   * @param cmd : structure that contains the command configuration information
00788   * @param Timeout Timeout duration
00789   * @note   This function is used only in Indirect Read or Write Modes
00790   * @retval HAL status
00791   */
00792 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
00793 {
00794   HAL_StatusTypeDef status;
00795   uint32_t tickstart = HAL_GetTick();
00796 
00797   /* Check the parameters */
00798   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00799   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00800   {
00801     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00802   }
00803 
00804   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00805   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00806   {
00807     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00808   }
00809 
00810   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00811   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00812   {
00813     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00814   }
00815 
00816   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00817   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00818 
00819   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00820   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00821   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00822 
00823   /* Process locked */
00824   __HAL_LOCK(hqspi);
00825 
00826   if(hqspi->State == HAL_QSPI_STATE_READY)
00827   {
00828     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00829 
00830     /* Update QSPI state */
00831     hqspi->State = HAL_QSPI_STATE_BUSY;
00832 
00833     /* Wait till BUSY flag reset */
00834     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
00835 
00836     if (status == HAL_OK)
00837     {
00838       /* Call the configuration function */
00839       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00840 
00841       if (cmd->DataMode == QSPI_DATA_NONE)
00842       {
00843         /* When there is no data phase, the transfer start as soon as the configuration is done
00844         so wait until TC flag is set to go back in idle state */
00845         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
00846 
00847         if (status == HAL_OK)
00848         {
00849           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00850 
00851           /* Update QSPI state */
00852           hqspi->State = HAL_QSPI_STATE_READY;
00853         }
00854       }
00855       else
00856       {
00857         /* Update QSPI state */
00858         hqspi->State = HAL_QSPI_STATE_READY;
00859       }
00860     }
00861   }
00862   else
00863   {
00864     status = HAL_BUSY;
00865   }
00866 
00867   /* Process unlocked */
00868   __HAL_UNLOCK(hqspi);
00869 
00870   /* Return function status */
00871   return status;
00872 }
00873 
00874 /**
00875   * @brief Set the command configuration in interrupt mode.
00876   * @param hqspi QSPI handle
00877   * @param cmd structure that contains the command configuration information
00878   * @note   This function is used only in Indirect Read or Write Modes
00879   * @retval HAL status
00880   */
00881 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
00882 {
00883   HAL_StatusTypeDef status;
00884   uint32_t tickstart = HAL_GetTick();
00885 
00886   /* Check the parameters */
00887   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00888   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00889   {
00890     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00891   }
00892 
00893   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00894   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00895   {
00896     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00897   }
00898 
00899   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00900   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00901   {
00902     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00903   }
00904 
00905   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00906   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00907 
00908   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00909   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00910   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00911 
00912   /* Process locked */
00913   __HAL_LOCK(hqspi);
00914 
00915   if(hqspi->State == HAL_QSPI_STATE_READY)
00916   {
00917     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00918 
00919     /* Update QSPI state */
00920     hqspi->State = HAL_QSPI_STATE_BUSY;
00921 
00922     /* Wait till BUSY flag reset */
00923     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
00924 
00925     if (status == HAL_OK)
00926     {
00927       if (cmd->DataMode == QSPI_DATA_NONE)
00928       {
00929         /* Clear interrupt */
00930         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
00931       }
00932 
00933       /* Call the configuration function */
00934       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00935 
00936       if (cmd->DataMode == QSPI_DATA_NONE)
00937       {
00938         /* When there is no data phase, the transfer start as soon as the configuration is done
00939         so activate TC and TE interrupts */
00940         /* Process unlocked */
00941         __HAL_UNLOCK(hqspi);
00942 
00943         /* Enable the QSPI Transfer Error Interrupt */
00944         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
00945       }
00946       else
00947       {
00948         /* Update QSPI state */
00949         hqspi->State = HAL_QSPI_STATE_READY;
00950 
00951         /* Process unlocked */
00952         __HAL_UNLOCK(hqspi);
00953       }
00954     }
00955     else
00956     {
00957       /* Process unlocked */
00958       __HAL_UNLOCK(hqspi);
00959     }
00960   }
00961   else
00962   {
00963     status = HAL_BUSY;
00964 
00965     /* Process unlocked */
00966     __HAL_UNLOCK(hqspi);
00967   }
00968 
00969   /* Return function status */
00970   return status;
00971 }
00972 
00973 /**
00974   * @brief Transmit an amount of data in blocking mode.
00975   * @param hqspi QSPI handle
00976   * @param pData pointer to data buffer
00977   * @param Timeout Timeout duration
00978   * @note   This function is used only in Indirect Write Mode
00979   * @retval HAL status
00980   */
00981 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
00982 {
00983   HAL_StatusTypeDef status = HAL_OK;
00984   uint32_t tickstart = HAL_GetTick();
00985   __IO uint32_t *data_reg = &hqspi->Instance->DR;
00986 
00987   /* Process locked */
00988   __HAL_LOCK(hqspi);
00989 
00990   if(hqspi->State == HAL_QSPI_STATE_READY)
00991   {
00992     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00993 
00994     if(pData != NULL )
00995     {
00996       /* Update state */
00997       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
00998 
00999       /* Configure counters and size of the handle */
01000       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01001       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01002       hqspi->pTxBuffPtr = pData;
01003 
01004       /* Configure QSPI: CCR register with functional as indirect write */
01005       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01006 
01007       while(hqspi->TxXferCount > 0U)
01008       {
01009         /* Wait until FT flag is set to send data */
01010         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
01011 
01012         if (status != HAL_OK)
01013         {
01014           break;
01015         }
01016 
01017         *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
01018         hqspi->pTxBuffPtr++;
01019         hqspi->TxXferCount--;
01020       }
01021 
01022       if (status == HAL_OK)
01023       {
01024         /* Wait until TC flag is set to go back in idle state */
01025         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
01026 
01027         if (status == HAL_OK)
01028         {
01029           /* Clear Transfer Complete bit */
01030           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
01031 
01032 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
01033           /* Clear Busy bit */
01034           status = HAL_QSPI_Abort(hqspi);
01035 #endif
01036         }
01037       }
01038 
01039       /* Update QSPI state */
01040       hqspi->State = HAL_QSPI_STATE_READY;
01041     }
01042     else
01043     {
01044       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01045       status = HAL_ERROR;
01046     }
01047   }
01048   else
01049   {
01050     status = HAL_BUSY;
01051   }
01052 
01053   /* Process unlocked */
01054   __HAL_UNLOCK(hqspi);
01055 
01056   return status;
01057 }
01058 
01059 
01060 /**
01061   * @brief Receive an amount of data in blocking mode.
01062   * @param hqspi QSPI handle
01063   * @param pData pointer to data buffer
01064   * @param Timeout Timeout duration
01065   * @note   This function is used only in Indirect Read Mode
01066   * @retval HAL status
01067   */
01068 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
01069 {
01070   HAL_StatusTypeDef status = HAL_OK;
01071   uint32_t tickstart = HAL_GetTick();
01072   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01073   __IO uint32_t *data_reg = &hqspi->Instance->DR;
01074 
01075   /* Process locked */
01076   __HAL_LOCK(hqspi);
01077 
01078   if(hqspi->State == HAL_QSPI_STATE_READY)
01079   {
01080     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01081 
01082     if(pData != NULL )
01083     {
01084       /* Update state */
01085       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01086 
01087       /* Configure counters and size of the handle */
01088       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01089       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01090       hqspi->pRxBuffPtr = pData;
01091 
01092       /* Configure QSPI: CCR register with functional as indirect read */
01093       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01094 
01095       /* Start the transfer by re-writing the address in AR register */
01096       WRITE_REG(hqspi->Instance->AR, addr_reg);
01097 
01098       while(hqspi->RxXferCount > 0U)
01099       {
01100         /* Wait until FT or TC flag is set to read received data */
01101         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
01102 
01103         if  (status != HAL_OK)
01104         {
01105           break;
01106         }
01107 
01108         *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
01109         hqspi->pRxBuffPtr++;
01110         hqspi->RxXferCount--;
01111       }
01112 
01113       if (status == HAL_OK)
01114       {
01115         /* Wait until TC flag is set to go back in idle state */
01116         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
01117 
01118         if  (status == HAL_OK)
01119         {
01120           /* Clear Transfer Complete bit */
01121           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
01122 
01123 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
01124           /* Workaround - Extra data written in the FIFO at the end of a read transfer */
01125           status = HAL_QSPI_Abort(hqspi);
01126 #endif
01127         }
01128       }
01129 
01130       /* Update QSPI state */
01131       hqspi->State = HAL_QSPI_STATE_READY;
01132     }
01133     else
01134     {
01135       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01136       status = HAL_ERROR;
01137     }
01138   }
01139   else
01140   {
01141     status = HAL_BUSY;
01142   }
01143 
01144   /* Process unlocked */
01145   __HAL_UNLOCK(hqspi);
01146 
01147   return status;
01148 }
01149 
01150 /**
01151   * @brief  Send an amount of data in non-blocking mode with interrupt.
01152   * @param  hqspi QSPI handle
01153   * @param  pData pointer to data buffer
01154   * @note   This function is used only in Indirect Write Mode
01155   * @retval HAL status
01156   */
01157 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01158 {
01159   HAL_StatusTypeDef status = HAL_OK;
01160 
01161   /* Process locked */
01162   __HAL_LOCK(hqspi);
01163 
01164   if(hqspi->State == HAL_QSPI_STATE_READY)
01165   {
01166     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01167 
01168     if(pData != NULL )
01169     {
01170       /* Update state */
01171       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
01172 
01173       /* Configure counters and size of the handle */
01174       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01175       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01176       hqspi->pTxBuffPtr = pData;
01177 
01178       /* Clear interrupt */
01179       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
01180 
01181       /* Configure QSPI: CCR register with functional as indirect write */
01182       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01183 
01184       /* Process unlocked */
01185       __HAL_UNLOCK(hqspi);
01186 
01187       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
01188       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
01189     }
01190     else
01191     {
01192       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01193       status = HAL_ERROR;
01194 
01195       /* Process unlocked */
01196       __HAL_UNLOCK(hqspi);
01197     }
01198   }
01199   else
01200   {
01201     status = HAL_BUSY;
01202 
01203     /* Process unlocked */
01204     __HAL_UNLOCK(hqspi);
01205   }
01206 
01207   return status;
01208 }
01209 
01210 /**
01211   * @brief  Receive an amount of data in non-blocking mode with interrupt.
01212   * @param  hqspi QSPI handle
01213   * @param  pData pointer to data buffer
01214   * @note   This function is used only in Indirect Read Mode
01215   * @retval HAL status
01216   */
01217 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01218 {
01219   HAL_StatusTypeDef status = HAL_OK;
01220   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01221 
01222   /* Process locked */
01223   __HAL_LOCK(hqspi);
01224 
01225   if(hqspi->State == HAL_QSPI_STATE_READY)
01226   {
01227     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01228 
01229     if(pData != NULL )
01230     {
01231       /* Update state */
01232       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01233 
01234       /* Configure counters and size of the handle */
01235       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01236       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01237       hqspi->pRxBuffPtr = pData;
01238 
01239       /* Clear interrupt */
01240       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
01241 
01242       /* Configure QSPI: CCR register with functional as indirect read */
01243       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01244 
01245       /* Start the transfer by re-writing the address in AR register */
01246       WRITE_REG(hqspi->Instance->AR, addr_reg);
01247 
01248       /* Process unlocked */
01249       __HAL_UNLOCK(hqspi);
01250 
01251       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
01252       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
01253     }
01254     else
01255     {
01256       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01257       status = HAL_ERROR;
01258 
01259       /* Process unlocked */
01260       __HAL_UNLOCK(hqspi);
01261     }
01262   }
01263   else
01264   {
01265     status = HAL_BUSY;
01266 
01267     /* Process unlocked */
01268     __HAL_UNLOCK(hqspi);
01269   }
01270 
01271   return status;
01272 }
01273 
01274 /**
01275   * @brief  Send an amount of data in non-blocking mode with DMA.
01276   * @param  hqspi QSPI handle
01277   * @param  pData pointer to data buffer
01278   * @note   This function is used only in Indirect Write Mode
01279   * @note   If DMA peripheral access is configured as halfword, the number
01280   *         of data and the fifo threshold should be aligned on halfword
01281   * @note   If DMA peripheral access is configured as word, the number
01282   *         of data and the fifo threshold should be aligned on word
01283   * @retval HAL status
01284   */
01285 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01286 {
01287   HAL_StatusTypeDef status = HAL_OK;
01288   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
01289 
01290   /* Process locked */
01291   __HAL_LOCK(hqspi);
01292 
01293   if(hqspi->State == HAL_QSPI_STATE_READY)
01294   {
01295     /* Clear the error code */
01296     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01297 
01298     if(pData != NULL )
01299     {
01300       /* Configure counters of the handle */
01301       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
01302       {
01303         hqspi->TxXferCount = data_size;
01304       }
01305       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
01306       {
01307         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
01308         {
01309           /* The number of data or the fifo threshold is not aligned on halfword
01310           => no transfer possible with DMA peripheral access configured as halfword */
01311           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01312           status = HAL_ERROR;
01313 
01314           /* Process unlocked */
01315           __HAL_UNLOCK(hqspi);
01316         }
01317         else
01318         {
01319           hqspi->TxXferCount = (data_size >> 1U);
01320         }
01321       }
01322       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
01323       {
01324         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
01325         {
01326           /* The number of data or the fifo threshold is not aligned on word
01327           => no transfer possible with DMA peripheral access configured as word */
01328           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01329           status = HAL_ERROR;
01330 
01331           /* Process unlocked */
01332           __HAL_UNLOCK(hqspi);
01333         }
01334         else
01335         {
01336           hqspi->TxXferCount = (data_size >> 2U);
01337         }
01338       }
01339       else
01340       {
01341         /* Nothing to do */
01342       }
01343 
01344       if (status == HAL_OK)
01345       {
01346         /* Update state */
01347         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
01348 
01349         /* Clear interrupt */
01350         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
01351 
01352         /* Configure size and pointer of the handle */
01353         hqspi->TxXferSize = hqspi->TxXferCount;
01354         hqspi->pTxBuffPtr = pData;
01355 
01356         /* Configure QSPI: CCR register with functional mode as indirect write */
01357         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01358 
01359         /* Set the QSPI DMA transfer complete callback */
01360         hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
01361 
01362         /* Set the QSPI DMA Half transfer complete callback */
01363         hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
01364 
01365         /* Set the DMA error callback */
01366         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01367 
01368         /* Clear the DMA abort callback */
01369         hqspi->hdma->XferAbortCallback = NULL;
01370 
01371         /* Configure the direction of the DMA */
01372         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
01373         MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
01374 
01375         /* Enable the QSPI transmit DMA Channel */
01376         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
01377         {
01378           /* Process unlocked */
01379           __HAL_UNLOCK(hqspi);
01380 
01381           /* Enable the QSPI transfer error Interrupt */
01382           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
01383 
01384           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01385           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01386         }
01387         else
01388         {
01389           status = HAL_ERROR;
01390           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
01391           hqspi->State = HAL_QSPI_STATE_READY;
01392 
01393           /* Process unlocked */
01394           __HAL_UNLOCK(hqspi);
01395         }
01396      }
01397     }
01398     else
01399     {
01400       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01401       status = HAL_ERROR;
01402 
01403       /* Process unlocked */
01404       __HAL_UNLOCK(hqspi);
01405     }
01406   }
01407   else
01408   {
01409     status = HAL_BUSY;
01410 
01411     /* Process unlocked */
01412     __HAL_UNLOCK(hqspi);
01413   }
01414 
01415   return status;
01416 }
01417 
01418 /**
01419   * @brief  Receive an amount of data in non-blocking mode with DMA.
01420   * @param  hqspi QSPI handle
01421   * @param  pData pointer to data buffer.
01422   * @note   This function is used only in Indirect Read Mode
01423   * @note   If DMA peripheral access is configured as halfword, the number
01424   *         of data and the fifo threshold should be aligned on halfword
01425   * @note   If DMA peripheral access is configured as word, the number
01426   *         of data and the fifo threshold should be aligned on word
01427   * @retval HAL status
01428   */
01429 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01430 {
01431   HAL_StatusTypeDef status = HAL_OK;
01432   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01433   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
01434 
01435   /* Process locked */
01436   __HAL_LOCK(hqspi);
01437 
01438   if(hqspi->State == HAL_QSPI_STATE_READY)
01439   {
01440     /* Clear the error code */
01441     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01442 
01443     if(pData != NULL )
01444     {
01445       /* Configure counters of the handle */
01446       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
01447       {
01448         hqspi->RxXferCount = data_size;
01449       }
01450       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
01451       {
01452         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
01453         {
01454           /* The number of data or the fifo threshold is not aligned on halfword
01455              => no transfer possible with DMA peripheral access configured as halfword */
01456           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01457           status = HAL_ERROR;
01458 
01459           /* Process unlocked */
01460           __HAL_UNLOCK(hqspi);
01461         }
01462         else
01463         {
01464           hqspi->RxXferCount = (data_size >> 1U);
01465         }
01466       }
01467       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
01468       {
01469         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
01470         {
01471           /* The number of data or the fifo threshold is not aligned on word
01472              => no transfer possible with DMA peripheral access configured as word */
01473           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01474           status = HAL_ERROR;
01475 
01476           /* Process unlocked */
01477           __HAL_UNLOCK(hqspi);
01478         }
01479         else
01480         {
01481           hqspi->RxXferCount = (data_size >> 2U);
01482         }
01483       }
01484       else
01485       {
01486         /* Nothing to do */
01487       }
01488 
01489       if (status == HAL_OK)
01490       {
01491         /* Update state */
01492         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01493 
01494         /* Clear interrupt */
01495         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
01496 
01497         /* Configure size and pointer of the handle */
01498         hqspi->RxXferSize = hqspi->RxXferCount;
01499         hqspi->pRxBuffPtr = pData;
01500 
01501         /* Set the QSPI DMA transfer complete callback */
01502         hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
01503 
01504         /* Set the QSPI DMA Half transfer complete callback */
01505         hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
01506 
01507         /* Set the DMA error callback */
01508         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01509 
01510         /* Clear the DMA abort callback */
01511         hqspi->hdma->XferAbortCallback = NULL;
01512 
01513         /* Configure the direction of the DMA */
01514         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
01515         MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
01516 
01517         /* Enable the DMA Channel */
01518         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
01519         {
01520           /* Configure QSPI: CCR register with functional as indirect read */
01521           MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01522 
01523           /* Start the transfer by re-writing the address in AR register */
01524           WRITE_REG(hqspi->Instance->AR, addr_reg);
01525 
01526           /* Process unlocked */
01527           __HAL_UNLOCK(hqspi);
01528 
01529           /* Enable the QSPI transfer error Interrupt */
01530           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
01531 
01532           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01533           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01534         }
01535         else
01536         {
01537           status = HAL_ERROR;
01538           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
01539           hqspi->State = HAL_QSPI_STATE_READY;
01540 
01541           /* Process unlocked */
01542           __HAL_UNLOCK(hqspi);
01543         }
01544       }
01545     }
01546     else
01547     {
01548       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01549       status = HAL_ERROR;
01550 
01551       /* Process unlocked */
01552       __HAL_UNLOCK(hqspi);
01553     }
01554   }
01555   else
01556   {
01557     status = HAL_BUSY;
01558 
01559     /* Process unlocked */
01560     __HAL_UNLOCK(hqspi);
01561   }
01562 
01563   return status;
01564 }
01565 
01566 /**
01567   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode.
01568   * @param  hqspi QSPI handle
01569   * @param  cmd structure that contains the command configuration information.
01570   * @param  cfg structure that contains the polling configuration information.
01571   * @param  Timeout Timeout duration
01572   * @note   This function is used only in Automatic Polling Mode
01573   * @retval HAL status
01574   */
01575 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
01576 {
01577   HAL_StatusTypeDef status;
01578   uint32_t tickstart = HAL_GetTick();
01579 
01580   /* Check the parameters */
01581   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01582   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01583   {
01584     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01585   }
01586 
01587   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01588   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01589   {
01590     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01591   }
01592 
01593   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01594   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01595   {
01596     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01597   }
01598 
01599   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01600   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01601 
01602   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01603   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01604   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01605 
01606   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01607   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01608   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01609 
01610   /* Process locked */
01611   __HAL_LOCK(hqspi);
01612 
01613   if(hqspi->State == HAL_QSPI_STATE_READY)
01614   {
01615     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01616 
01617     /* Update state */
01618     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01619 
01620     /* Wait till BUSY flag reset */
01621     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
01622 
01623     if (status == HAL_OK)
01624     {
01625       /* Configure QSPI: PSMAR register with the status match value */
01626       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01627 
01628       /* Configure QSPI: PSMKR register with the status mask value */
01629       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01630 
01631       /* Configure QSPI: PIR register with the interval value */
01632       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01633 
01634       /* Configure QSPI: CR register with Match mode and Automatic stop enabled
01635       (otherwise there will be an infinite loop in blocking mode) */
01636       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
01637                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
01638 
01639       /* Call the configuration function */
01640       cmd->NbData = cfg->StatusBytesSize;
01641       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01642 
01643       /* Wait until SM flag is set to go back in idle state */
01644       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
01645 
01646       if (status == HAL_OK)
01647       {
01648         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
01649 
01650         /* Update state */
01651         hqspi->State = HAL_QSPI_STATE_READY;
01652       }
01653     }
01654   }
01655   else
01656   {
01657     status = HAL_BUSY;
01658   }
01659 
01660   /* Process unlocked */
01661   __HAL_UNLOCK(hqspi);
01662 
01663   /* Return function status */
01664   return status;
01665 }
01666 
01667 /**
01668   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode.
01669   * @param  hqspi QSPI handle
01670   * @param  cmd structure that contains the command configuration information.
01671   * @param  cfg structure that contains the polling configuration information.
01672   * @note   This function is used only in Automatic Polling Mode
01673   * @retval HAL status
01674   */
01675 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
01676 {
01677   HAL_StatusTypeDef status;
01678   uint32_t tickstart = HAL_GetTick();
01679 
01680   /* Check the parameters */
01681   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01682   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01683   {
01684     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01685   }
01686 
01687   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01688   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01689   {
01690     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01691   }
01692 
01693   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01694   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01695   {
01696     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01697   }
01698 
01699   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01700   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01701 
01702   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01703   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01704   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01705 
01706   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01707   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01708   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01709   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
01710 
01711   /* Process locked */
01712   __HAL_LOCK(hqspi);
01713 
01714   if(hqspi->State == HAL_QSPI_STATE_READY)
01715   {
01716     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01717 
01718     /* Update state */
01719     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01720 
01721     /* Wait till BUSY flag reset */
01722     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
01723 
01724     if (status == HAL_OK)
01725     {
01726       /* Configure QSPI: PSMAR register with the status match value */
01727       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01728 
01729       /* Configure QSPI: PSMKR register with the status mask value */
01730       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01731 
01732       /* Configure QSPI: PIR register with the interval value */
01733       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01734 
01735       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
01736       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
01737                (cfg->MatchMode | cfg->AutomaticStop));
01738 
01739       /* Clear interrupt */
01740       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
01741 
01742       /* Call the configuration function */
01743       cmd->NbData = cfg->StatusBytesSize;
01744       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01745 
01746       /* Process unlocked */
01747       __HAL_UNLOCK(hqspi);
01748 
01749       /* Enable the QSPI Transfer Error and status match Interrupt */
01750       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
01751 
01752     }
01753     else
01754     {
01755       /* Process unlocked */
01756       __HAL_UNLOCK(hqspi);
01757     }
01758   }
01759   else
01760   {
01761     status = HAL_BUSY;
01762 
01763     /* Process unlocked */
01764     __HAL_UNLOCK(hqspi);
01765   }
01766 
01767   /* Return function status */
01768   return status;
01769 }
01770 
01771 /**
01772   * @brief  Configure the Memory Mapped mode.
01773   * @param  hqspi QSPI handle
01774   * @param  cmd structure that contains the command configuration information.
01775   * @param  cfg structure that contains the memory mapped configuration information.
01776   * @note   This function is used only in Memory mapped Mode
01777   * @retval HAL status
01778   */
01779 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
01780 {
01781   HAL_StatusTypeDef status;
01782   uint32_t tickstart = HAL_GetTick();
01783 
01784   /* Check the parameters */
01785   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01786   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01787   {
01788   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01789   }
01790 
01791   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01792   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01793   {
01794     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01795   }
01796 
01797   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01798   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01799   {
01800     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01801   }
01802 
01803   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01804   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01805 
01806   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01807   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01808   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01809 
01810   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
01811 
01812   /* Process locked */
01813   __HAL_LOCK(hqspi);
01814 
01815   if(hqspi->State == HAL_QSPI_STATE_READY)
01816   {
01817     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01818 
01819     /* Update state */
01820     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
01821 
01822     /* Wait till BUSY flag reset */
01823     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
01824 
01825     if (status == HAL_OK)
01826     {
01827       /* Configure QSPI: CR register with timeout counter enable */
01828     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
01829 
01830     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
01831       {
01832         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
01833 
01834         /* Configure QSPI: LPTR register with the low-power timeout value */
01835         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
01836 
01837         /* Clear interrupt */
01838         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
01839 
01840         /* Enable the QSPI TimeOut Interrupt */
01841         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
01842       }
01843 
01844       /* Call the configuration function */
01845       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
01846     }
01847   }
01848   else
01849   {
01850     status = HAL_BUSY;
01851   }
01852 
01853   /* Process unlocked */
01854   __HAL_UNLOCK(hqspi);
01855 
01856   /* Return function status */
01857   return status;
01858 }
01859 
01860 /**
01861   * @brief  Transfer Error callback.
01862   * @param  hqspi QSPI handle
01863   * @retval None
01864   */
01865 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
01866 {
01867   /* Prevent unused argument(s) compilation warning */
01868   UNUSED(hqspi);
01869 
01870   /* NOTE : This function should not be modified, when the callback is needed,
01871             the HAL_QSPI_ErrorCallback could be implemented in the user file
01872    */
01873 }
01874 
01875 /**
01876   * @brief  Abort completed callback.
01877   * @param  hqspi QSPI handle
01878   * @retval None
01879   */
01880 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
01881 {
01882   /* Prevent unused argument(s) compilation warning */
01883   UNUSED(hqspi);
01884 
01885   /* NOTE: This function should not be modified, when the callback is needed,
01886            the HAL_QSPI_AbortCpltCallback could be implemented in the user file
01887    */
01888 }
01889 
01890 /**
01891   * @brief  Command completed callback.
01892   * @param  hqspi QSPI handle
01893   * @retval None
01894   */
01895 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
01896 {
01897   /* Prevent unused argument(s) compilation warning */
01898   UNUSED(hqspi);
01899 
01900   /* NOTE: This function should not be modified, when the callback is needed,
01901            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
01902    */
01903 }
01904 
01905 /**
01906   * @brief  Rx Transfer completed callback.
01907   * @param  hqspi QSPI handle
01908   * @retval None
01909   */
01910 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
01911 {
01912   /* Prevent unused argument(s) compilation warning */
01913   UNUSED(hqspi);
01914 
01915   /* NOTE: This function should not be modified, when the callback is needed,
01916            the HAL_QSPI_RxCpltCallback could be implemented in the user file
01917    */
01918 }
01919 
01920 /**
01921   * @brief  Tx Transfer completed callback.
01922   * @param  hqspi QSPI handle
01923   * @retval None
01924   */
01925 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
01926 {
01927   /* Prevent unused argument(s) compilation warning */
01928   UNUSED(hqspi);
01929 
01930   /* NOTE: This function should not be modified, when the callback is needed,
01931            the HAL_QSPI_TxCpltCallback could be implemented in the user file
01932    */
01933 }
01934 
01935 /**
01936   * @brief  Rx Half Transfer completed callback.
01937   * @param  hqspi QSPI handle
01938   * @retval None
01939   */
01940 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01941 {
01942   /* Prevent unused argument(s) compilation warning */
01943   UNUSED(hqspi);
01944 
01945   /* NOTE: This function should not be modified, when the callback is needed,
01946            the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
01947    */
01948 }
01949 
01950 /**
01951   * @brief  Tx Half Transfer completed callback.
01952   * @param  hqspi QSPI handle
01953   * @retval None
01954   */
01955 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01956 {
01957   /* Prevent unused argument(s) compilation warning */
01958   UNUSED(hqspi);
01959 
01960   /* NOTE: This function should not be modified, when the callback is needed,
01961            the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
01962    */
01963 }
01964 
01965 /**
01966   * @brief  FIFO Threshold callback.
01967   * @param  hqspi QSPI handle
01968   * @retval None
01969   */
01970 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
01971 {
01972   /* Prevent unused argument(s) compilation warning */
01973   UNUSED(hqspi);
01974 
01975   /* NOTE : This function should not be modified, when the callback is needed,
01976             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
01977    */
01978 }
01979 
01980 /**
01981   * @brief  Status Match callback.
01982   * @param  hqspi QSPI handle
01983   * @retval None
01984   */
01985 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
01986 {
01987   /* Prevent unused argument(s) compilation warning */
01988   UNUSED(hqspi);
01989 
01990   /* NOTE : This function should not be modified, when the callback is needed,
01991             the HAL_QSPI_StatusMatchCallback could be implemented in the user file
01992    */
01993 }
01994 
01995 /**
01996   * @brief  Timeout callback.
01997   * @param  hqspi QSPI handle
01998   * @retval None
01999   */
02000 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
02001 {
02002   /* Prevent unused argument(s) compilation warning */
02003   UNUSED(hqspi);
02004 
02005   /* NOTE : This function should not be modified, when the callback is needed,
02006             the HAL_QSPI_TimeOutCallback could be implemented in the user file
02007    */
02008 }
02009 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
02010 /**
02011   * @brief  Register a User QSPI Callback
02012   *         To be used instead of the weak (surcharged) predefined callback
02013   * @param hqspi QSPI handle
02014   * @param CallbackId ID of the callback to be registered
02015   *        This parameter can be one of the following values:
02016   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
02017   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
02018   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
02019   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
02020   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
02021   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
02022   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
02023   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
02024   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
02025   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
02026   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
02027   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
02028   * @param pCallback pointer to the Callback function
02029   * @retval status
02030   */
02031 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
02032 {
02033   HAL_StatusTypeDef status = HAL_OK;
02034 
02035   if(pCallback == NULL)
02036   {
02037     /* Update the error code */
02038     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02039     return HAL_ERROR;
02040   }
02041 
02042   /* Process locked */
02043   __HAL_LOCK(hqspi);
02044 
02045   if(hqspi->State == HAL_QSPI_STATE_READY)
02046   {
02047     switch (CallbackId)
02048     {
02049     case  HAL_QSPI_ERROR_CB_ID :
02050       hqspi->ErrorCallback = pCallback;
02051       break;
02052     case HAL_QSPI_ABORT_CB_ID :
02053       hqspi->AbortCpltCallback = pCallback;
02054       break;
02055     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
02056       hqspi->FifoThresholdCallback = pCallback;
02057       break;
02058     case HAL_QSPI_CMD_CPLT_CB_ID :
02059       hqspi->CmdCpltCallback = pCallback;
02060       break;
02061     case HAL_QSPI_RX_CPLT_CB_ID :
02062       hqspi->RxCpltCallback = pCallback;
02063       break;
02064     case HAL_QSPI_TX_CPLT_CB_ID :
02065       hqspi->TxCpltCallback = pCallback;
02066       break;
02067     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
02068       hqspi->RxHalfCpltCallback = pCallback;
02069       break;
02070     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
02071       hqspi->TxHalfCpltCallback = pCallback;
02072       break;
02073     case HAL_QSPI_STATUS_MATCH_CB_ID :
02074       hqspi->StatusMatchCallback = pCallback;
02075       break;
02076     case HAL_QSPI_TIMEOUT_CB_ID :
02077       hqspi->TimeOutCallback = pCallback;
02078       break;
02079     case HAL_QSPI_MSP_INIT_CB_ID :
02080       hqspi->MspInitCallback = pCallback;
02081       break;
02082     case HAL_QSPI_MSP_DEINIT_CB_ID :
02083       hqspi->MspDeInitCallback = pCallback;
02084       break;
02085     default :
02086       /* Update the error code */
02087       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02088       /* update return status */
02089       status =  HAL_ERROR;
02090       break;
02091     }
02092   }
02093   else if (hqspi->State == HAL_QSPI_STATE_RESET)
02094   {
02095     switch (CallbackId)
02096     {
02097     case HAL_QSPI_MSP_INIT_CB_ID :
02098       hqspi->MspInitCallback = pCallback;
02099       break;
02100     case HAL_QSPI_MSP_DEINIT_CB_ID :
02101       hqspi->MspDeInitCallback = pCallback;
02102       break;
02103     default :
02104       /* Update the error code */
02105       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02106       /* update return status */
02107       status =  HAL_ERROR;
02108       break;
02109     }
02110   }
02111   else
02112   {
02113     /* Update the error code */
02114     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02115     /* update return status */
02116     status =  HAL_ERROR;
02117   }
02118 
02119   /* Release Lock */
02120   __HAL_UNLOCK(hqspi);
02121   return status;
02122 }
02123 
02124 /**
02125   * @brief  Unregister a User QSPI Callback
02126   *         QSPI Callback is redirected to the weak (surcharged) predefined callback
02127   * @param hqspi QSPI handle
02128   * @param CallbackId ID of the callback to be unregistered
02129   *        This parameter can be one of the following values:
02130   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
02131   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
02132   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
02133   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
02134   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
02135   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
02136   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
02137   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
02138   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
02139   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
02140   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
02141   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
02142   * @retval status
02143   */
02144 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
02145 {
02146   HAL_StatusTypeDef status = HAL_OK;
02147 
02148   /* Process locked */
02149   __HAL_LOCK(hqspi);
02150 
02151   if(hqspi->State == HAL_QSPI_STATE_READY)
02152   {
02153     switch (CallbackId)
02154     {
02155     case  HAL_QSPI_ERROR_CB_ID :
02156       hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
02157       break;
02158     case HAL_QSPI_ABORT_CB_ID :
02159       hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
02160       break;
02161     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
02162       hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
02163       break;
02164     case HAL_QSPI_CMD_CPLT_CB_ID :
02165       hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
02166       break;
02167     case HAL_QSPI_RX_CPLT_CB_ID :
02168       hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
02169       break;
02170     case HAL_QSPI_TX_CPLT_CB_ID :
02171       hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
02172       break;
02173     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
02174       hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
02175       break;
02176     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
02177       hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
02178       break;
02179     case HAL_QSPI_STATUS_MATCH_CB_ID :
02180       hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
02181       break;
02182     case HAL_QSPI_TIMEOUT_CB_ID :
02183       hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
02184       break;
02185     case HAL_QSPI_MSP_INIT_CB_ID :
02186       hqspi->MspInitCallback = HAL_QSPI_MspInit;
02187       break;
02188     case HAL_QSPI_MSP_DEINIT_CB_ID :
02189       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
02190       break;
02191     default :
02192       /* Update the error code */
02193       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02194       /* update return status */
02195       status =  HAL_ERROR;
02196       break;
02197     }
02198   }
02199   else if (hqspi->State == HAL_QSPI_STATE_RESET)
02200   {
02201     switch (CallbackId)
02202     {
02203     case HAL_QSPI_MSP_INIT_CB_ID :
02204       hqspi->MspInitCallback = HAL_QSPI_MspInit;
02205       break;
02206     case HAL_QSPI_MSP_DEINIT_CB_ID :
02207       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
02208       break;
02209     default :
02210       /* Update the error code */
02211       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02212       /* update return status */
02213       status =  HAL_ERROR;
02214       break;
02215     }
02216   }
02217   else
02218   {
02219     /* Update the error code */
02220     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
02221     /* update return status */
02222     status =  HAL_ERROR;
02223   }
02224 
02225   /* Release Lock */
02226   __HAL_UNLOCK(hqspi);
02227   return status;
02228 }
02229 #endif
02230 
02231 /**
02232   * @}
02233   */
02234 
02235 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
02236   *  @brief   QSPI control and State functions
02237   *
02238 @verbatim
02239  ===============================================================================
02240                   ##### Peripheral Control and State functions #####
02241  ===============================================================================
02242     [..]
02243     This subsection provides a set of functions allowing to :
02244       (+) Check in run-time the state of the driver.
02245       (+) Check the error code set during last operation.
02246       (+) Abort any operation.
02247 
02248 
02249 @endverbatim
02250   * @{
02251   */
02252 
02253 /**
02254   * @brief  Return the QSPI handle state.
02255   * @param  hqspi QSPI handle
02256   * @retval HAL state
02257   */
02258 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
02259 {
02260   /* Return QSPI handle state */
02261   return hqspi->State;
02262 }
02263 
02264 /**
02265 * @brief  Return the QSPI error code.
02266 * @param  hqspi QSPI handle
02267 * @retval QSPI Error Code
02268 */
02269 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
02270 {
02271   return hqspi->ErrorCode;
02272 }
02273 
02274 /**
02275 * @brief  Abort the current transmission.
02276 * @param  hqspi QSPI handle
02277 * @retval HAL status
02278 */
02279 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
02280 {
02281   HAL_StatusTypeDef status = HAL_OK;
02282   uint32_t tickstart = HAL_GetTick();
02283 
02284   /* Check if the state is in one of the busy states */
02285   if (((uint32_t)hqspi->State & 0x2U) != 0U)
02286   {
02287     /* Process unlocked */
02288     __HAL_UNLOCK(hqspi);
02289 
02290     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
02291     {
02292       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
02293       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
02294 
02295       /* Abort DMA channel */
02296       status = HAL_DMA_Abort(hqspi->hdma);
02297       if(status != HAL_OK)
02298       {
02299         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
02300       }
02301     }
02302 
02303     /* Configure QSPI: CR register with Abort request */
02304     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
02305 
02306     /* Wait until TC flag is set to go back in idle state */
02307     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
02308 
02309     if (status == HAL_OK)
02310     {
02311       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02312 
02313       /* Wait until BUSY flag is reset */
02314       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
02315     }
02316 
02317     if (status == HAL_OK)
02318     {
02319       /* Reset functional mode configuration to indirect write mode by default */
02320       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
02321 
02322       /* Update state */
02323       hqspi->State = HAL_QSPI_STATE_READY;
02324     }
02325   }
02326 
02327   return status;
02328 }
02329 
02330 /**
02331 * @brief  Abort the current transmission (non-blocking function)
02332 * @param  hqspi QSPI handle
02333 * @retval HAL status
02334 */
02335 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
02336 {
02337   HAL_StatusTypeDef status = HAL_OK;
02338 
02339   /* Check if the state is in one of the busy states */
02340   if (((uint32_t)hqspi->State & 0x2U) != 0U)
02341   {
02342     /* Process unlocked */
02343     __HAL_UNLOCK(hqspi);
02344 
02345     /* Update QSPI state */
02346     hqspi->State = HAL_QSPI_STATE_ABORT;
02347 
02348     /* Disable all interrupts */
02349     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
02350 
02351     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
02352     {
02353       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
02354       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
02355 
02356       /* Abort DMA channel */
02357       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
02358       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
02359       {
02360         /* Change state of QSPI */
02361         hqspi->State = HAL_QSPI_STATE_READY;
02362 
02363         /* Abort Complete callback */
02364 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
02365         hqspi->AbortCpltCallback(hqspi);
02366 #else
02367         HAL_QSPI_AbortCpltCallback(hqspi);
02368 #endif
02369       }
02370     }
02371     else
02372     {
02373       /* Clear interrupt */
02374       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02375 
02376       /* Enable the QSPI Transfer Complete Interrupt */
02377       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02378 
02379       /* Configure QSPI: CR register with Abort request */
02380       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
02381     }
02382   }
02383   return status;
02384 }
02385 
02386 /** @brief Set QSPI timeout.
02387   * @param  hqspi QSPI handle.
02388   * @param  Timeout Timeout for the QSPI memory access.
02389   * @retval None
02390   */
02391 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
02392 {
02393   hqspi->Timeout = Timeout;
02394 }
02395 
02396 /** @brief Set QSPI Fifo threshold.
02397   * @param  hqspi QSPI handle.
02398   * @param  Threshold Threshold of the Fifo (value between 1 and 16).
02399   * @retval HAL status
02400   */
02401 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
02402 {
02403   HAL_StatusTypeDef status = HAL_OK;
02404 
02405   /* Process locked */
02406   __HAL_LOCK(hqspi);
02407 
02408   if(hqspi->State == HAL_QSPI_STATE_READY)
02409   {
02410     /* Synchronize init structure with new FIFO threshold value */
02411     hqspi->Init.FifoThreshold = Threshold;
02412 
02413     /* Configure QSPI FIFO Threshold */
02414     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
02415                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
02416   }
02417   else
02418   {
02419     status = HAL_BUSY;
02420   }
02421 
02422   /* Process unlocked */
02423   __HAL_UNLOCK(hqspi);
02424 
02425   /* Return function status */
02426   return status;
02427 }
02428 
02429 /** @brief Get QSPI Fifo threshold.
02430   * @param  hqspi QSPI handle.
02431   * @retval Fifo threshold (value between 1 and 16)
02432   */
02433 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
02434 {
02435   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
02436 }
02437 
02438 #if defined(QUADSPI_CR_DFM)
02439 /** @brief  Set FlashID.
02440   * @param  hqspi QSPI handle.
02441   * @param  FlashID Index of the flash memory to be accessed.
02442   *                   This parameter can be a value of @ref QSPI_Flash_Select.
02443   * @note   The FlashID is ignored when dual flash mode is enabled.
02444   * @retval HAL status
02445   */
02446 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
02447 {
02448   HAL_StatusTypeDef status = HAL_OK;
02449 
02450   /* Check the parameter */
02451   assert_param(IS_QSPI_FLASH_ID(FlashID));
02452 
02453   /* Process locked */
02454   __HAL_LOCK(hqspi);
02455 
02456   if(hqspi->State == HAL_QSPI_STATE_READY)
02457   {
02458     /* Synchronize init structure with new FlashID value */
02459     hqspi->Init.FlashID = FlashID;
02460 
02461     /* Configure QSPI FlashID */
02462     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
02463   }
02464   else
02465   {
02466     status = HAL_BUSY;
02467   }
02468 
02469   /* Process unlocked */
02470   __HAL_UNLOCK(hqspi);
02471 
02472   /* Return function status */
02473   return status;
02474 }
02475 
02476 #endif
02477 /**
02478   * @}
02479   */
02480 
02481 /**
02482   * @}
02483   */
02484 
02485 /** @defgroup QSPI_Private_Functions QSPI Private Functions
02486   * @{
02487   */
02488 
02489 /**
02490   * @brief  DMA QSPI receive process complete callback.
02491   * @param  hdma DMA handle
02492   * @retval None
02493   */
02494 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
02495 {
02496   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
02497   hqspi->RxXferCount = 0U;
02498 
02499   /* Enable the QSPI transfer complete Interrupt */
02500   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02501 }
02502 
02503 /**
02504   * @brief  DMA QSPI transmit process complete callback.
02505   * @param  hdma DMA handle
02506   * @retval None
02507   */
02508 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
02509 {
02510   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
02511   hqspi->TxXferCount = 0U;
02512 
02513   /* Enable the QSPI transfer complete Interrupt */
02514   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02515 }
02516 
02517 /**
02518   * @brief  DMA QSPI receive process half complete callback.
02519   * @param  hdma DMA handle
02520   * @retval None
02521   */
02522 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
02523 {
02524   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
02525 
02526 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
02527   hqspi->RxHalfCpltCallback(hqspi);
02528 #else
02529   HAL_QSPI_RxHalfCpltCallback(hqspi);
02530 #endif
02531 }
02532 
02533 /**
02534   * @brief  DMA QSPI transmit process half complete callback.
02535   * @param  hdma DMA handle
02536   * @retval None
02537   */
02538 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
02539 {
02540   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
02541 
02542 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
02543   hqspi->TxHalfCpltCallback(hqspi);
02544 #else
02545   HAL_QSPI_TxHalfCpltCallback(hqspi);
02546 #endif
02547 }
02548 
02549 /**
02550   * @brief  DMA QSPI communication error callback.
02551   * @param  hdma DMA handle
02552   * @retval None
02553   */
02554 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
02555 {
02556   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
02557 
02558   hqspi->RxXferCount = 0U;
02559   hqspi->TxXferCount = 0U;
02560   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
02561 
02562   /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
02563   CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
02564 
02565   /* Abort the QSPI */
02566   (void)HAL_QSPI_Abort_IT(hqspi);
02567 
02568 }
02569 
02570 /**
02571   * @brief  DMA QSPI abort complete callback.
02572   * @param  hdma DMA handle
02573   * @retval None
02574   */
02575 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
02576 {
02577   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
02578 
02579   hqspi->RxXferCount = 0U;
02580   hqspi->TxXferCount = 0U;
02581 
02582   if(hqspi->State == HAL_QSPI_STATE_ABORT)
02583   {
02584     /* DMA Abort called by QSPI abort */
02585     /* Clear interrupt */
02586     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02587 
02588     /* Enable the QSPI Transfer Complete Interrupt */
02589     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02590 
02591     /* Configure QSPI: CR register with Abort request */
02592     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
02593   }
02594   else
02595   {
02596     /* DMA Abort called due to a transfer error interrupt */
02597     /* Change state of QSPI */
02598     hqspi->State = HAL_QSPI_STATE_READY;
02599 
02600     /* Error callback */
02601 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
02602     hqspi->ErrorCallback(hqspi);
02603 #else
02604     HAL_QSPI_ErrorCallback(hqspi);
02605 #endif
02606   }
02607 }
02608 
02609 /**
02610   * @brief  Wait for a flag state until timeout.
02611   * @param  hqspi QSPI handle
02612   * @param  Flag Flag checked
02613   * @param  State Value of the flag expected
02614   * @param  Tickstart Tick start value
02615   * @param  Timeout Duration of the timeout
02616   * @retval HAL status
02617   */
02618 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
02619                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
02620 {
02621   /* Wait until flag is in expected state */
02622   while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
02623   {
02624     /* Check for the Timeout */
02625     if (Timeout != HAL_MAX_DELAY)
02626     {
02627       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
02628       {
02629         hqspi->State     = HAL_QSPI_STATE_ERROR;
02630         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
02631 
02632         return HAL_ERROR;
02633       }
02634     }
02635   }
02636   return HAL_OK;
02637 }
02638 
02639 /**
02640   * @brief  Configure the communication registers.
02641   * @param  hqspi QSPI handle
02642   * @param  cmd structure that contains the command configuration information
02643   * @param  FunctionalMode functional mode to configured
02644   *           This parameter can be one of the following values:
02645   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
02646   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
02647   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
02648   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
02649   * @retval None
02650   */
02651 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
02652 {
02653   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
02654 
02655   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
02656   {
02657     /* Configure QSPI: DLR register with the number of data to read or write */
02658     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
02659   }
02660 
02661   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
02662   {
02663     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
02664     {
02665       /* Configure QSPI: ABR register with alternate bytes value */
02666       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
02667 
02668       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02669       {
02670         /*---- Command with instruction, address and alternate bytes ----*/
02671         /* Configure QSPI: CCR register with all communications parameters */
02672         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02673                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02674                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
02675                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
02676                                          cmd->Instruction | FunctionalMode));
02677 
02678         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02679         {
02680           /* Configure QSPI: AR register with address value */
02681           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02682         }
02683       }
02684       else
02685       {
02686         /*---- Command with instruction and alternate bytes ----*/
02687         /* Configure QSPI: CCR register with all communications parameters */
02688         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02689                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02690                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
02691                                          cmd->AddressMode | cmd->InstructionMode |
02692                                          cmd->Instruction | FunctionalMode));
02693       }
02694     }
02695     else
02696     {
02697       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02698       {
02699         /*---- Command with instruction and address ----*/
02700         /* Configure QSPI: CCR register with all communications parameters */
02701         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02702                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02703                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
02704                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
02705 
02706         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02707         {
02708           /* Configure QSPI: AR register with address value */
02709           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02710         }
02711       }
02712       else
02713       {
02714         /*---- Command with only instruction ----*/
02715         /* Configure QSPI: CCR register with all communications parameters */
02716         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02717                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02718                                          cmd->AlternateByteMode | cmd->AddressMode |
02719                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
02720       }
02721     }
02722   }
02723   else
02724   {
02725     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
02726     {
02727       /* Configure QSPI: ABR register with alternate bytes value */
02728       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
02729 
02730       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02731       {
02732         /*---- Command with address and alternate bytes ----*/
02733         /* Configure QSPI: CCR register with all communications parameters */
02734         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02735                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02736                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
02737                                          cmd->AddressSize | cmd->AddressMode |
02738                                          cmd->InstructionMode | FunctionalMode));
02739 
02740         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02741         {
02742           /* Configure QSPI: AR register with address value */
02743           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02744         }
02745       }
02746       else
02747       {
02748         /*---- Command with only alternate bytes ----*/
02749         /* Configure QSPI: CCR register with all communications parameters */
02750         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02751                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02752                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
02753                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
02754       }
02755     }
02756     else
02757     {
02758       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02759       {
02760         /*---- Command with only address ----*/
02761         /* Configure QSPI: CCR register with all communications parameters */
02762         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02763                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02764                                          cmd->AlternateByteMode | cmd->AddressSize |
02765                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
02766 
02767         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02768         {
02769           /* Configure QSPI: AR register with address value */
02770           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02771         }
02772       }
02773       else
02774       {
02775         /*---- Command with only data phase ----*/
02776         if (cmd->DataMode != QSPI_DATA_NONE)
02777         {
02778           /* Configure QSPI: CCR register with all communications parameters */
02779           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02780                                            cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
02781                                            cmd->AlternateByteMode | cmd->AddressMode |
02782                                            cmd->InstructionMode | FunctionalMode));
02783         }
02784       }
02785     }
02786   }
02787 }
02788 
02789 /**
02790   * @}
02791   */
02792 
02793 /**
02794   * @}
02795   */
02796 
02797 #endif /* HAL_QSPI_MODULE_ENABLED */
02798 /**
02799   * @}
02800   */
02801 
02802 /**
02803   * @}
02804   */
02805 
02806 #endif /* defined(QUADSPI) */