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