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