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