Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_qspi.c
0004   * @author  MCD Application Team
0005   * @brief   QSPI HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the QuadSPI interface (QSPI).
0008   *           + Initialization and de-initialization functions
0009   *           + Indirect functional mode management
0010   *           + Memory-mapped functional mode management
0011   *           + Auto-polling functional mode management
0012   *           + Interrupts and flags management
0013   *           + MDMA channel configuration for indirect functional mode
0014   *           + Errors management and abort functionality
0015   *
0016   *
0017   ******************************************************************************
0018   * @attention
0019   *
0020   * Copyright (c) 2017 STMicroelectronics.
0021   * All rights reserved.
0022   *
0023   * This software is licensed under terms that can be found in the LICENSE file
0024   * in the root directory of this software component.
0025   * If no LICENSE file comes with this software, it is provided AS-IS.
0026   *
0027   ******************************************************************************
0028   @verbatim
0029  ===============================================================================
0030                         ##### How to use this driver #####
0031  ===============================================================================
0032   [..]
0033     *** Initialization ***
0034     ======================
0035     [..]
0036       (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
0037         (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
0038         (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
0039         (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
0040         (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
0041         (++) If interrupt mode is used, enable and configure QuadSPI global
0042             interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
0043         (++) If DMA mode is used, enable the clocks for the QuadSPI MDMA
0044             with __HAL_RCC_MDMA_CLK_ENABLE(), configure MDMA with HAL_MDMA_Init(),
0045             link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
0046             MDMA global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
0047       (#) Configure the flash size, the clock prescaler, the fifo threshold, the
0048           clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
0049 
0050     *** Indirect functional mode ***
0051     ================================
0052     [..]
0053       (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
0054           functions :
0055          (++) Instruction phase : the mode used and if present the instruction opcode.
0056          (++) Address phase : the mode used and if present the size and the address value.
0057          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
0058              bytes values.
0059          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
0060          (++) Data phase : the mode used and if present the number of bytes.
0061          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
0062              if activated.
0063          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
0064       (#) If no data is required for the command, it is sent directly to the memory :
0065          (++) In polling mode, the output of the function is done when the transfer is complete.
0066          (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
0067       (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
0068           HAL_QSPI_Transmit_IT() after the command configuration :
0069          (++) In polling mode, the output of the function is done when the transfer is complete.
0070          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
0071              is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
0072          (++) In DMA mode,HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
0073       (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
0074           HAL_QSPI_Receive_IT() after the command configuration :
0075          (++) In polling mode, the output of the function is done when the transfer is complete.
0076          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
0077              is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
0078          (++) In DMA mode,HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
0079 
0080     *** Auto-polling functional mode ***
0081     ====================================
0082     [..]
0083       (#) Configure the command sequence and the auto-polling functional mode using the
0084           HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
0085          (++) Instruction phase : the mode used and if present the instruction opcode.
0086          (++) Address phase : the mode used and if present the size and the address value.
0087          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
0088              bytes values.
0089          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
0090          (++) Data phase : the mode used.
0091          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
0092              if activated.
0093          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
0094          (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
0095              the polling interval and the automatic stop activation.
0096       (#) After the configuration :
0097          (++) In polling mode, the output of the function is done when the status match is reached. The
0098              automatic stop is activated to avoid an infinite loop.
0099          (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
0100 
0101     *** MDMA functional mode ***
0102     ====================================
0103     [..]
0104       (#) Configure the SourceInc and DestinationInc of MDMA parameters in the HAL_QSPI_MspInit() function :
0105          (++) MDMA settings for write operation :
0106           (+) The DestinationInc should be MDMA_DEST_INC_DISABLE
0107           (+) The SourceInc must be a value of MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
0108           (+) The SourceDataSize must be a value of MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
0109               aligned with MDMA_Source_increment_mode .
0110           (+) The DestDataSize must be a value of MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
0111          (++) MDMA settings for read operation :
0112           (+) The SourceInc should be MDMA_SRC_INC_DISABLE
0113           (+) The DestinationInc must be a value of MDMA_Destination_increment_mode (Except the MDMA_DEST_INC_DOUBLEWORD).
0114           (+) The SourceDataSize must be a value of MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
0115           (+) The DestDataSize must be a value of MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
0116               aligned with MDMA_Destination_increment_mode.
0117          (++)The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Quadspi.
0118       (#)In case of wrong MDMA setting
0119         (++) For write operation :
0120          (+) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled by the HAL_QSPI_Transmit_DMA().
0121         (++) For read operation :
0122          (+) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled by the HAL_QSPI_Receive_DMA().
0123 
0124     *** Memory-mapped functional mode ***
0125     =====================================
0126     [..]
0127       (#) Configure the command sequence and the memory-mapped functional mode using the
0128           HAL_QSPI_MemoryMapped() functions :
0129          (++) Instruction phase : the mode used and if present the instruction opcode.
0130          (++) Address phase : the mode used and the size.
0131          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
0132              bytes values.
0133          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
0134          (++) Data phase : the mode used.
0135          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
0136              if activated.
0137          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
0138          (++) The timeout activation and the timeout period.
0139       (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
0140           the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
0141 
0142     *** Errors management and abort functionality ***
0143     =================================================
0144     [..]
0145       (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
0146       (#) HAL_QSPI_Abort() and HAL_QSPI_Abort_IT() functions aborts any on-going operation and
0147           flushes the fifo :
0148          (++) In polling mode, the output of the function is done when the transfer
0149               complete bit is set and the busy bit cleared.
0150          (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
0151               the transfer complete bit is set.
0152 
0153     *** Control functions ***
0154     =========================
0155     [..]
0156       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
0157       (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
0158       (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
0159       (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
0160       (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
0161 
0162     *** Callback registration ***
0163     =============================================
0164     [..]
0165       The compilation define  USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
0166       allows the user to configure dynamically the driver callbacks.
0167 
0168       Use Functions HAL_QSPI_RegisterCallback() to register a user callback,
0169       it allows to register following callbacks:
0170         (+) ErrorCallback : callback when error occurs.
0171         (+) AbortCpltCallback : callback when abort is completed.
0172         (+) FifoThresholdCallback : callback when the fifo threshold is reached.
0173         (+) CmdCpltCallback : callback when a command without data is completed.
0174         (+) RxCpltCallback : callback when a reception transfer is completed.
0175         (+) TxCpltCallback : callback when a transmission transfer is completed.
0176         (+) StatusMatchCallback : callback when a status match occurs.
0177         (+) TimeOutCallback : callback when the timeout perioed expires.
0178         (+) MspInitCallback    : QSPI MspInit.
0179         (+) MspDeInitCallback  : QSPI MspDeInit.
0180       This function takes as parameters the HAL peripheral handle, the Callback ID
0181       and a pointer to the user callback function.
0182 
0183       Use function HAL_QSPI_UnRegisterCallback() to reset a callback to the default
0184       weak (overridden) function. It allows to reset following callbacks:
0185         (+) ErrorCallback : callback when error occurs.
0186         (+) AbortCpltCallback : callback when abort is completed.
0187         (+) FifoThresholdCallback : callback when the fifo threshold is reached.
0188         (+) CmdCpltCallback : callback when a command without data is completed.
0189         (+) RxCpltCallback : callback when a reception transfer is completed.
0190         (+) TxCpltCallback : callback when a transmission transfer is completed.
0191         (+) StatusMatchCallback : callback when a status match occurs.
0192         (+) TimeOutCallback : callback when the timeout perioed expires.
0193         (+) MspInitCallback    : QSPI MspInit.
0194         (+) MspDeInitCallback  : QSPI MspDeInit.
0195       This function) takes as parameters the HAL peripheral handle and the Callback ID.
0196 
0197       By default, after the HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
0198       all callbacks are reset to the corresponding legacy weak (overridden) functions.
0199       Exception done for MspInit and MspDeInit callbacks that are respectively
0200       reset to the legacy weak (overridden) functions in the HAL_QSPI_Init
0201       and  HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
0202       If not, MspInit or MspDeInit are not null, the HAL_QSPI_Init and HAL_QSPI_DeInit
0203       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0204 
0205       Callbacks can be registered/unregistered in READY state only.
0206       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0207       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0208       during the Init/DeInit.
0209       In that case first register the MspInit/MspDeInit user callbacks
0210       using HAL_QSPI_RegisterCallback before calling HAL_QSPI_DeInit
0211       or HAL_QSPI_Init function.
0212 
0213       When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
0214       not defined, the callback registering feature is not available
0215       and weak (overridden) callbacks are used.
0216 
0217     *** Workarounds linked to Silicon Limitation ***
0218     ====================================================
0219     [..]
0220       (#) Workarounds Implemented inside HAL Driver
0221          (++) Extra data written in the FIFO at the end of a read transfer
0222 
0223   @endverbatim
0224   ******************************************************************************
0225   */
0226 
0227 /* Includes ------------------------------------------------------------------*/
0228 #include "stm32h7xx_hal.h"
0229 
0230 #if defined(QUADSPI)
0231 
0232 /** @addtogroup STM32H7xx_HAL_Driver
0233   * @{
0234   */
0235 
0236 /** @defgroup QSPI QSPI
0237   * @ingroup RTEMSBSPsARMSTM32H7
0238   * @brief QSPI HAL module driver
0239   * @{
0240   */
0241 #ifdef HAL_QSPI_MODULE_ENABLED
0242 
0243 /* Private typedef -----------------------------------------------------------*/
0244 
0245 /* Private define ------------------------------------------------------------*/
0246 /** @defgroup QSPI_Private_Constants QSPI Private Constants
0247   * @ingroup RTEMSBSPsARMSTM32H7
0248   * @{
0249   */
0250 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U                     /*!<Indirect write mode*/
0251 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
0252 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
0253 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/
0254 /**
0255   * @}
0256   */
0257 
0258 /* Private macro -------------------------------------------------------------*/
0259 /** @defgroup QSPI_Private_Macros QSPI Private Macros
0260   * @ingroup RTEMSBSPsARMSTM32H7
0261   * @{
0262   */
0263 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
0264                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
0265                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
0266                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
0267 /**
0268   * @}
0269   */
0270 
0271 /* Private variables ---------------------------------------------------------*/
0272 
0273 /* Private function prototypes -----------------------------------------------*/
0274 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma);
0275 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma);
0276 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma);
0277 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma);
0278 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
0279 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
0280 
0281 /* Exported functions --------------------------------------------------------*/
0282 
0283 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
0284   * @ingroup RTEMSBSPsARMSTM32H7
0285   * @{
0286   */
0287 
0288 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
0289   * @ingroup RTEMSBSPsARMSTM32H7
0290   *  @brief    Initialization and Configuration functions
0291   *
0292 @verbatim
0293 ===============================================================================
0294             ##### Initialization and Configuration functions #####
0295  ===============================================================================
0296     [..]
0297     This subsection provides a set of functions allowing to :
0298       (+) Initialize the QuadSPI.
0299       (+) De-initialize the QuadSPI.
0300 
0301 @endverbatim
0302   * @{
0303   */
0304 
0305 /**
0306   * @brief Initialize the QSPI mode according to the specified parameters
0307   *        in the QSPI_InitTypeDef and initialize the associated handle.
0308   * @param hqspi QSPI handle
0309   * @retval HAL status
0310   */
0311 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
0312 {
0313   HAL_StatusTypeDef status;
0314   uint32_t tickstart = HAL_GetTick();
0315 
0316   /* Check the QSPI handle allocation */
0317   if(hqspi == NULL)
0318   {
0319     return HAL_ERROR;
0320   }
0321 
0322   /* Check the parameters */
0323   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
0324   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
0325   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
0326   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
0327   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
0328   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
0329   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
0330   assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
0331 
0332   if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
0333   {
0334     assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
0335   }
0336 
0337   if(hqspi->State == HAL_QSPI_STATE_RESET)
0338   {
0339 
0340 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0341     /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
0342     hqspi->ErrorCallback         = HAL_QSPI_ErrorCallback;
0343     hqspi->AbortCpltCallback     = HAL_QSPI_AbortCpltCallback;
0344     hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
0345     hqspi->CmdCpltCallback       = HAL_QSPI_CmdCpltCallback;
0346     hqspi->RxCpltCallback        = HAL_QSPI_RxCpltCallback;
0347     hqspi->TxCpltCallback        = HAL_QSPI_TxCpltCallback;
0348     hqspi->StatusMatchCallback   = HAL_QSPI_StatusMatchCallback;
0349     hqspi->TimeOutCallback       = HAL_QSPI_TimeOutCallback;
0350 
0351     if(hqspi->MspInitCallback == NULL)
0352     {
0353       hqspi->MspInitCallback = HAL_QSPI_MspInit;
0354     }
0355 
0356     /* Init the low level hardware */
0357     hqspi->MspInitCallback(hqspi);
0358 #else
0359     /* Init the low level hardware : GPIO, CLOCK */
0360     HAL_QSPI_MspInit(hqspi);
0361 #endif
0362 
0363     /* Configure the default timeout for the QSPI memory access */
0364     HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
0365   }
0366 
0367   /* Configure QSPI FIFO Threshold */
0368   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
0369              ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
0370 
0371   /* Wait till BUSY flag reset */
0372   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
0373 
0374   if(status == HAL_OK)
0375   {
0376     /* Configure QSPI Clock Prescaler and Sample Shift */
0377     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
0378                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
0379                 hqspi->Init.SampleShifting  | hqspi->Init.FlashID | hqspi->Init.DualFlash));
0380 
0381     /* Configure QSPI Flash Size, CS High Time and Clock Mode */
0382     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
0383                ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
0384                 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
0385 
0386     /* Enable the QSPI peripheral */
0387     __HAL_QSPI_ENABLE(hqspi);
0388 
0389     /* Set QSPI error code to none */
0390     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
0391 
0392     /* Initialize the QSPI state */
0393     hqspi->State = HAL_QSPI_STATE_READY;
0394   }
0395 
0396   /* Return function status */
0397   return status;
0398 }
0399 
0400 /**
0401   * @brief De-Initialize the QSPI peripheral.
0402   * @param hqspi QSPI handle
0403   * @retval HAL status
0404   */
0405 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
0406 {
0407   /* Check the QSPI handle allocation */
0408   if(hqspi == NULL)
0409   {
0410     return HAL_ERROR;
0411   }
0412 
0413   /* Disable the QSPI Peripheral Clock */
0414   __HAL_QSPI_DISABLE(hqspi);
0415 
0416 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0417   if(hqspi->MspDeInitCallback == NULL)
0418   {
0419     hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
0420   }
0421 
0422   /* DeInit the low level hardware */
0423   hqspi->MspDeInitCallback(hqspi);
0424 #else
0425   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
0426   HAL_QSPI_MspDeInit(hqspi);
0427 #endif
0428 
0429   /* Set QSPI error code to none */
0430   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
0431 
0432   /* Initialize the QSPI state */
0433   hqspi->State = HAL_QSPI_STATE_RESET;
0434 
0435   return HAL_OK;
0436 }
0437 
0438 /**
0439   * @brief Initialize the QSPI MSP.
0440   * @param hqspi QSPI handle
0441   * @retval None
0442   */
0443 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
0444 {
0445   /* Prevent unused argument(s) compilation warning */
0446   UNUSED(hqspi);
0447 
0448   /* NOTE : This function should not be modified, when the callback is needed,
0449             the HAL_QSPI_MspInit can be implemented in the user file
0450    */
0451 }
0452 
0453 /**
0454   * @brief DeInitialize the QSPI MSP.
0455   * @param hqspi QSPI handle
0456   * @retval None
0457   */
0458 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
0459 {
0460   /* Prevent unused argument(s) compilation warning */
0461   UNUSED(hqspi);
0462 
0463   /* NOTE : This function should not be modified, when the callback is needed,
0464             the HAL_QSPI_MspDeInit can be implemented in the user file
0465    */
0466 }
0467 
0468 /**
0469   * @}
0470   */
0471 
0472 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
0473   * @ingroup RTEMSBSPsARMSTM32H7
0474   *  @brief QSPI Transmit/Receive functions
0475   *
0476 @verbatim
0477  ===============================================================================
0478                       ##### IO operation functions #####
0479  ===============================================================================
0480     [..]
0481     This subsection provides a set of functions allowing to :
0482       (+) Handle the interrupts.
0483       (+) Handle the command sequence.
0484       (+) Transmit data in blocking, interrupt or DMA mode.
0485       (+) Receive data in blocking, interrupt or DMA mode.
0486       (+) Manage the auto-polling functional mode.
0487       (+) Manage the memory-mapped functional mode.
0488 
0489 @endverbatim
0490   * @{
0491   */
0492 
0493 /**
0494   * @brief Handle QSPI interrupt request.
0495   * @param hqspi QSPI handle
0496   * @retval None
0497   */
0498 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
0499 {
0500   __IO uint32_t *data_reg;
0501   uint32_t flag = READ_REG(hqspi->Instance->SR);
0502   uint32_t itsource = READ_REG(hqspi->Instance->CR);
0503 
0504   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
0505   if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
0506   {
0507     data_reg = &hqspi->Instance->DR;
0508 
0509     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
0510     {
0511       /* Transmission process */
0512       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
0513       {
0514         if (hqspi->TxXferCount > 0U)
0515         {
0516           /* Fill the FIFO until the threshold is reached */
0517           *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
0518           hqspi->pTxBuffPtr++;
0519           hqspi->TxXferCount--;
0520         }
0521         else
0522         {
0523           /* No more data available for the transfer */
0524           /* Disable the QSPI FIFO Threshold Interrupt */
0525           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
0526           break;
0527         }
0528       }
0529     }
0530     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
0531     {
0532       /* Receiving Process */
0533       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
0534       {
0535         if (hqspi->RxXferCount > 0U)
0536         {
0537           /* Read the FIFO until the threshold is reached */
0538           *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
0539           hqspi->pRxBuffPtr++;
0540           hqspi->RxXferCount--;
0541         }
0542         else
0543         {
0544           /* All data have been received for the transfer */
0545           /* Disable the QSPI FIFO Threshold Interrupt */
0546           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
0547           break;
0548         }
0549       }
0550     }
0551     else
0552     {
0553       /* Nothing to do */
0554     }
0555 
0556     /* FIFO Threshold callback */
0557 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0558     hqspi->FifoThresholdCallback(hqspi);
0559 #else
0560     HAL_QSPI_FifoThresholdCallback(hqspi);
0561 #endif
0562   }
0563 
0564   /* QSPI Transfer Complete interrupt occurred -------------------------------*/
0565   else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
0566   {
0567     /* Clear interrupt */
0568     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
0569 
0570     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
0571     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
0572 
0573     /* Transfer complete callback */
0574     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
0575     {
0576       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
0577       {
0578         /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
0579            but no impact on H7 HW and it minimize the cost in the footprint */
0580         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
0581 
0582         /* Disable the MDMA channel */
0583         __HAL_MDMA_DISABLE(hqspi->hmdma);
0584       }
0585 
0586 
0587       /* Change state of QSPI */
0588       hqspi->State = HAL_QSPI_STATE_READY;
0589 
0590       /* TX Complete callback */
0591 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0592       hqspi->TxCpltCallback(hqspi);
0593 #else
0594       HAL_QSPI_TxCpltCallback(hqspi);
0595 #endif
0596     }
0597     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
0598     {
0599       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
0600       {
0601         /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
0602            but no impact on H7 HW and it minimize the cost in the footprint */
0603         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
0604 
0605         /* Disable the MDMA channel */
0606         __HAL_MDMA_DISABLE(hqspi->hmdma);
0607       }
0608       else
0609       {
0610         data_reg = &hqspi->Instance->DR;
0611         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
0612         {
0613           if (hqspi->RxXferCount > 0U)
0614           {
0615             /* Read the last data received in the FIFO until it is empty */
0616             *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
0617             hqspi->pRxBuffPtr++;
0618             hqspi->RxXferCount--;
0619           }
0620           else
0621           {
0622             /* All data have been received for the transfer */
0623             break;
0624           }
0625         }
0626       }
0627 
0628 
0629       /* Change state of QSPI */
0630       hqspi->State = HAL_QSPI_STATE_READY;
0631 
0632       /* RX Complete callback */
0633 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0634       hqspi->RxCpltCallback(hqspi);
0635 #else
0636       HAL_QSPI_RxCpltCallback(hqspi);
0637 #endif
0638     }
0639     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
0640     {
0641       /* Change state of QSPI */
0642       hqspi->State = HAL_QSPI_STATE_READY;
0643 
0644       /* Command Complete callback */
0645 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0646       hqspi->CmdCpltCallback(hqspi);
0647 #else
0648       HAL_QSPI_CmdCpltCallback(hqspi);
0649 #endif
0650     }
0651     else if(hqspi->State == HAL_QSPI_STATE_ABORT)
0652     {
0653       /* Reset functional mode configuration to indirect write mode by default */
0654       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
0655 
0656       /* Change state of QSPI */
0657       hqspi->State = HAL_QSPI_STATE_READY;
0658 
0659       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
0660       {
0661         /* Abort called by the user */
0662 
0663         /* Abort Complete callback */
0664 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0665         hqspi->AbortCpltCallback(hqspi);
0666 #else
0667         HAL_QSPI_AbortCpltCallback(hqspi);
0668 #endif
0669       }
0670       else
0671       {
0672         /* Abort due to an error (eg :  MDMA error) */
0673 
0674         /* Error callback */
0675 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0676         hqspi->ErrorCallback(hqspi);
0677 #else
0678         HAL_QSPI_ErrorCallback(hqspi);
0679 #endif
0680       }
0681     }
0682     else
0683     {
0684      /* Nothing to do */
0685     }
0686   }
0687 
0688   /* QSPI Status Match interrupt occurred ------------------------------------*/
0689   else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
0690   {
0691     /* Clear interrupt */
0692     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
0693 
0694     /* Check if the automatic poll mode stop is activated */
0695     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
0696     {
0697       /* Disable the QSPI Transfer Error and Status Match Interrupts */
0698       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
0699 
0700       /* Change state of QSPI */
0701       hqspi->State = HAL_QSPI_STATE_READY;
0702     }
0703 
0704     /* Status match callback */
0705 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0706     hqspi->StatusMatchCallback(hqspi);
0707 #else
0708     HAL_QSPI_StatusMatchCallback(hqspi);
0709 #endif
0710   }
0711 
0712   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
0713   else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
0714   {
0715     /* Clear interrupt */
0716     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
0717 
0718     /* Disable all the QSPI Interrupts */
0719     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
0720 
0721     /* Set error code */
0722     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
0723 
0724     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
0725     {
0726       /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
0727          but no impact on H7 HW and it minimize the cost in the footprint */
0728       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
0729 
0730       /* Disable the MDMA channel */
0731       hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
0732       if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
0733       {
0734         /* Set error code to DMA */
0735         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
0736 
0737         /* Change state of QSPI */
0738         hqspi->State = HAL_QSPI_STATE_READY;
0739 
0740         /* Error callback */
0741 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0742         hqspi->ErrorCallback(hqspi);
0743 #else
0744         HAL_QSPI_ErrorCallback(hqspi);
0745 #endif
0746       }
0747     }
0748     else
0749     {
0750       /* Change state of QSPI */
0751       hqspi->State = HAL_QSPI_STATE_READY;
0752 
0753       /* Error callback */
0754 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0755       hqspi->ErrorCallback(hqspi);
0756 #else
0757       HAL_QSPI_ErrorCallback(hqspi);
0758 #endif
0759     }
0760   }
0761 
0762   /* QSPI Timeout interrupt occurred -----------------------------------------*/
0763   else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
0764   {
0765     /* Clear interrupt */
0766     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
0767 
0768     /* Timeout callback */
0769 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0770     hqspi->TimeOutCallback(hqspi);
0771 #else
0772     HAL_QSPI_TimeOutCallback(hqspi);
0773 #endif
0774   }
0775 
0776    else
0777   {
0778    /* Nothing to do */
0779   }
0780 }
0781 
0782 /**
0783   * @brief Set the command configuration.
0784   * @param hqspi QSPI handle
0785   * @param cmd : structure that contains the command configuration information
0786   * @param Timeout Timeout duration
0787   * @note   This function is used only in Indirect Read or Write Modes
0788   * @retval HAL status
0789   */
0790 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
0791 {
0792   HAL_StatusTypeDef status;
0793   uint32_t tickstart = HAL_GetTick();
0794 
0795   /* Check the parameters */
0796   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
0797   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
0798   {
0799     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
0800   }
0801 
0802   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
0803   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
0804   {
0805     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
0806   }
0807 
0808   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
0809   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
0810   {
0811     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
0812   }
0813 
0814   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
0815   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
0816 
0817   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
0818   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
0819   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
0820 
0821   /* Process locked */
0822   __HAL_LOCK(hqspi);
0823 
0824   if(hqspi->State == HAL_QSPI_STATE_READY)
0825   {
0826     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
0827 
0828     /* Update QSPI state */
0829     hqspi->State = HAL_QSPI_STATE_BUSY;
0830 
0831     /* Wait till BUSY flag reset */
0832     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
0833 
0834     if (status == HAL_OK)
0835     {
0836       /* Call the configuration function */
0837       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
0838 
0839       if (cmd->DataMode == QSPI_DATA_NONE)
0840       {
0841         /* When there is no data phase, the transfer start as soon as the configuration is done
0842         so wait until TC flag is set to go back in idle state */
0843         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
0844 
0845         if (status == HAL_OK)
0846         {
0847           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
0848 
0849           /* Update QSPI state */
0850           hqspi->State = HAL_QSPI_STATE_READY;
0851         }
0852       }
0853       else
0854       {
0855         /* Update QSPI state */
0856         hqspi->State = HAL_QSPI_STATE_READY;
0857       }
0858     }
0859   }
0860   else
0861   {
0862     status = HAL_BUSY;
0863   }
0864 
0865   /* Process unlocked */
0866   __HAL_UNLOCK(hqspi);
0867 
0868   /* Return function status */
0869   return status;
0870 }
0871 
0872 /**
0873   * @brief Set the command configuration in interrupt mode.
0874   * @param hqspi QSPI handle
0875   * @param cmd structure that contains the command configuration information
0876   * @note   This function is used only in Indirect Read or Write Modes
0877   * @retval HAL status
0878   */
0879 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
0880 {
0881   HAL_StatusTypeDef status;
0882   uint32_t tickstart = HAL_GetTick();
0883 
0884   /* Check the parameters */
0885   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
0886   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
0887   {
0888     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
0889   }
0890 
0891   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
0892   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
0893   {
0894     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
0895   }
0896 
0897   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
0898   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
0899   {
0900     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
0901   }
0902 
0903   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
0904   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
0905 
0906   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
0907   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
0908   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
0909 
0910   /* Process locked */
0911   __HAL_LOCK(hqspi);
0912 
0913   if(hqspi->State == HAL_QSPI_STATE_READY)
0914   {
0915     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
0916 
0917     /* Update QSPI state */
0918     hqspi->State = HAL_QSPI_STATE_BUSY;
0919 
0920     /* Wait till BUSY flag reset */
0921     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
0922 
0923     if (status == HAL_OK)
0924     {
0925       if (cmd->DataMode == QSPI_DATA_NONE)
0926       {
0927         /* Clear interrupt */
0928         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
0929       }
0930 
0931       /* Call the configuration function */
0932       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
0933 
0934       if (cmd->DataMode == QSPI_DATA_NONE)
0935       {
0936         /* When there is no data phase, the transfer start as soon as the configuration is done
0937         so activate TC and TE interrupts */
0938         /* Process unlocked */
0939         __HAL_UNLOCK(hqspi);
0940 
0941         /* Enable the QSPI Transfer Error Interrupt */
0942         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
0943       }
0944       else
0945       {
0946         /* Update QSPI state */
0947         hqspi->State = HAL_QSPI_STATE_READY;
0948 
0949         /* Process unlocked */
0950         __HAL_UNLOCK(hqspi);
0951       }
0952     }
0953     else
0954     {
0955       /* Process unlocked */
0956       __HAL_UNLOCK(hqspi);
0957     }
0958   }
0959   else
0960   {
0961     status = HAL_BUSY;
0962 
0963     /* Process unlocked */
0964     __HAL_UNLOCK(hqspi);
0965   }
0966 
0967   /* Return function status */
0968   return status;
0969 }
0970 
0971 /**
0972   * @brief Transmit an amount of data in blocking mode.
0973   * @param hqspi QSPI handle
0974   * @param pData pointer to data buffer
0975   * @param Timeout Timeout duration
0976   * @note   This function is used only in Indirect Write Mode
0977   * @retval HAL status
0978   */
0979 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
0980 {
0981   HAL_StatusTypeDef status = HAL_OK;
0982   uint32_t tickstart = HAL_GetTick();
0983   __IO uint32_t *data_reg = &hqspi->Instance->DR;
0984 
0985   /* Process locked */
0986   __HAL_LOCK(hqspi);
0987 
0988   if(hqspi->State == HAL_QSPI_STATE_READY)
0989   {
0990     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
0991 
0992     if(pData != NULL )
0993     {
0994       /* Update state */
0995       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
0996 
0997       /* Configure counters and size of the handle */
0998       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
0999       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1000       hqspi->pTxBuffPtr = pData;
1001 
1002       /* Configure QSPI: CCR register with functional as indirect write */
1003       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1004 
1005       while(hqspi->TxXferCount > 0U)
1006       {
1007         /* Wait until FT flag is set to send data */
1008         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
1009 
1010         if (status != HAL_OK)
1011         {
1012           break;
1013         }
1014 
1015         *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
1016         hqspi->pTxBuffPtr++;
1017         hqspi->TxXferCount--;
1018       }
1019 
1020       if (status == HAL_OK)
1021       {
1022         /* Wait until TC flag is set to go back in idle state */
1023         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1024 
1025         if (status == HAL_OK)
1026         {
1027           /* Clear Transfer Complete bit */
1028           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1029 
1030         }
1031       }
1032 
1033       /* Update QSPI state */
1034       hqspi->State = HAL_QSPI_STATE_READY;
1035     }
1036     else
1037     {
1038       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1039       status = HAL_ERROR;
1040     }
1041   }
1042   else
1043   {
1044     status = HAL_BUSY;
1045   }
1046 
1047   /* Process unlocked */
1048   __HAL_UNLOCK(hqspi);
1049 
1050   return status;
1051 }
1052 
1053 
1054 /**
1055   * @brief Receive an amount of data in blocking mode.
1056   * @param hqspi QSPI handle
1057   * @param pData pointer to data buffer
1058   * @param Timeout Timeout duration
1059   * @note   This function is used only in Indirect Read Mode
1060   * @retval HAL status
1061   */
1062 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1063 {
1064   HAL_StatusTypeDef status = HAL_OK;
1065   uint32_t tickstart = HAL_GetTick();
1066   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1067   __IO uint32_t *data_reg = &hqspi->Instance->DR;
1068 
1069   /* Process locked */
1070   __HAL_LOCK(hqspi);
1071 
1072   if(hqspi->State == HAL_QSPI_STATE_READY)
1073   {
1074     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1075 
1076     if(pData != NULL )
1077     {
1078       /* Update state */
1079       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1080 
1081       /* Configure counters and size of the handle */
1082       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1083       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1084       hqspi->pRxBuffPtr = pData;
1085 
1086       /* Configure QSPI: CCR register with functional as indirect read */
1087       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1088 
1089       /* Start the transfer by re-writing the address in AR register */
1090       WRITE_REG(hqspi->Instance->AR, addr_reg);
1091 
1092       while(hqspi->RxXferCount > 0U)
1093       {
1094         /* Wait until FT or TC flag is set to read received data */
1095         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1096 
1097         if  (status != HAL_OK)
1098         {
1099           break;
1100         }
1101 
1102         *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
1103         hqspi->pRxBuffPtr++;
1104         hqspi->RxXferCount--;
1105       }
1106 
1107       if (status == HAL_OK)
1108       {
1109         /* Wait until TC flag is set to go back in idle state */
1110         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1111 
1112         if  (status == HAL_OK)
1113         {
1114           /* Clear Transfer Complete bit */
1115           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1116 
1117         }
1118       }
1119 
1120       /* Update QSPI state */
1121       hqspi->State = HAL_QSPI_STATE_READY;
1122     }
1123     else
1124     {
1125       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1126       status = HAL_ERROR;
1127     }
1128   }
1129   else
1130   {
1131     status = HAL_BUSY;
1132   }
1133 
1134   /* Process unlocked */
1135   __HAL_UNLOCK(hqspi);
1136 
1137   return status;
1138 }
1139 
1140 /**
1141   * @brief  Send an amount of data in non-blocking mode with interrupt.
1142   * @param  hqspi QSPI handle
1143   * @param  pData pointer to data buffer
1144   * @note   This function is used only in Indirect Write Mode
1145   * @retval HAL status
1146   */
1147 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1148 {
1149   HAL_StatusTypeDef status = HAL_OK;
1150 
1151   /* Process locked */
1152   __HAL_LOCK(hqspi);
1153 
1154   if(hqspi->State == HAL_QSPI_STATE_READY)
1155   {
1156     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1157 
1158     if(pData != NULL )
1159     {
1160       /* Update state */
1161       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1162 
1163       /* Configure counters and size of the handle */
1164       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1165       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1166       hqspi->pTxBuffPtr = pData;
1167 
1168       /* Clear interrupt */
1169       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1170 
1171       /* Configure QSPI: CCR register with functional as indirect write */
1172       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1173 
1174       /* Process unlocked */
1175       __HAL_UNLOCK(hqspi);
1176 
1177       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1178       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1179     }
1180     else
1181     {
1182       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1183       status = HAL_ERROR;
1184 
1185       /* Process unlocked */
1186       __HAL_UNLOCK(hqspi);
1187     }
1188   }
1189   else
1190   {
1191     status = HAL_BUSY;
1192 
1193     /* Process unlocked */
1194     __HAL_UNLOCK(hqspi);
1195   }
1196 
1197   return status;
1198 }
1199 
1200 /**
1201   * @brief  Receive an amount of data in non-blocking mode with interrupt.
1202   * @param  hqspi QSPI handle
1203   * @param  pData pointer to data buffer
1204   * @note   This function is used only in Indirect Read Mode
1205   * @retval HAL status
1206   */
1207 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1208 {
1209   HAL_StatusTypeDef status = HAL_OK;
1210   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1211 
1212   /* Process locked */
1213   __HAL_LOCK(hqspi);
1214 
1215   if(hqspi->State == HAL_QSPI_STATE_READY)
1216   {
1217     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1218 
1219     if(pData != NULL )
1220     {
1221       /* Update state */
1222       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1223 
1224       /* Configure counters and size of the handle */
1225       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1226       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1227       hqspi->pRxBuffPtr = pData;
1228 
1229       /* Clear interrupt */
1230       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1231 
1232       /* Configure QSPI: CCR register with functional as indirect read */
1233       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1234 
1235       /* Start the transfer by re-writing the address in AR register */
1236       WRITE_REG(hqspi->Instance->AR, addr_reg);
1237 
1238       /* Process unlocked */
1239       __HAL_UNLOCK(hqspi);
1240 
1241       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1242       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1243     }
1244     else
1245     {
1246       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1247       status = HAL_ERROR;
1248 
1249       /* Process unlocked */
1250       __HAL_UNLOCK(hqspi);
1251     }
1252   }
1253   else
1254   {
1255     status = HAL_BUSY;
1256 
1257     /* Process unlocked */
1258     __HAL_UNLOCK(hqspi);
1259   }
1260 
1261   return status;
1262 }
1263 
1264 /**
1265   * @brief  Send an amount of data in non-blocking mode with DMA.
1266   * @param  hqspi QSPI handle
1267   * @param  pData pointer to data buffer
1268   * @note   This function is used only in Indirect Write Mode
1269   * @retval HAL status
1270   */
1271 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1272 {
1273   HAL_StatusTypeDef status = HAL_OK;
1274   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1275 
1276   /* Process locked */
1277   __HAL_LOCK(hqspi);
1278 
1279   if(hqspi->State == HAL_QSPI_STATE_READY)
1280   {
1281     /* Clear the error code */
1282     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1283 
1284     if(pData != NULL )
1285     {
1286       /* Configure counters of the handle */
1287       hqspi->TxXferCount = data_size;
1288 
1289         /* Update state */
1290         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1291 
1292         /* Clear interrupt */
1293         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1294 
1295         /* Configure size and pointer of the handle */
1296         hqspi->TxXferSize = hqspi->TxXferCount;
1297         hqspi->pTxBuffPtr = pData;
1298 
1299         /* Configure QSPI: CCR register with functional mode as indirect write */
1300         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1301 
1302         /* Set the QSPI MDMA transfer complete callback */
1303         hqspi->hmdma->XferCpltCallback = QSPI_DMATxCplt;
1304 
1305         /* Set the MDMA error callback */
1306         hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1307 
1308         /* Clear the MDMA abort callback */
1309         hqspi->hmdma->XferAbortCallback = NULL;
1310 
1311         /* In Transmit mode , the MDMA destination is the QSPI DR register : Force the MDMA Destination Increment to disable */
1312         MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE);
1313 
1314         /* Update MDMA configuration with the correct SourceInc field for Write operation */
1315         if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
1316         {
1317           MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE);
1318         }
1319         else if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
1320         {
1321           MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD);
1322         }
1323         else if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
1324         {
1325           MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD);
1326         }
1327         else
1328         {
1329           /* in case of incorrect source data size */
1330           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1331           status = HAL_ERROR;
1332         }
1333 
1334         /* Enable the QSPI transmit MDMA */
1335         if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize, 1) == HAL_OK)
1336         {
1337           /* Process unlocked */
1338           __HAL_UNLOCK(hqspi);
1339 
1340           /* Enable the QSPI transfer error Interrupt */
1341           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1342 
1343           /* Enable using MDMA by setting DMAEN, note that DMAEN bit is "reserved"
1344              but no impact on H7 HW and it minimize the cost in the footprint */
1345           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1346         }
1347         else
1348         {
1349           status = HAL_ERROR;
1350           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1351           hqspi->State = HAL_QSPI_STATE_READY;
1352 
1353           /* Process unlocked */
1354           __HAL_UNLOCK(hqspi);
1355         }
1356     }
1357     else
1358     {
1359       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1360       status = HAL_ERROR;
1361 
1362       /* Process unlocked */
1363       __HAL_UNLOCK(hqspi);
1364     }
1365   }
1366   else
1367   {
1368     status = HAL_BUSY;
1369 
1370     /* Process unlocked */
1371     __HAL_UNLOCK(hqspi);
1372   }
1373 
1374   return status;
1375 }
1376 
1377 /**
1378   * @brief  Receive an amount of data in non-blocking mode with DMA.
1379   * @param  hqspi QSPI handle
1380   * @param  pData pointer to data buffer.
1381   * @note   This function is used only in Indirect Read Mode
1382   * @retval HAL status
1383   */
1384 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1385 {
1386   HAL_StatusTypeDef status = HAL_OK;
1387   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1388   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1389 
1390   /* Process locked */
1391   __HAL_LOCK(hqspi);
1392 
1393   if(hqspi->State == HAL_QSPI_STATE_READY)
1394   {
1395     /* Clear the error code */
1396     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1397 
1398     if(pData != NULL )
1399     {
1400       /* Configure counters of the handle */
1401       hqspi->RxXferCount = data_size;
1402         /* Update state */
1403         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1404 
1405         /* Clear interrupt */
1406         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1407 
1408         /* Configure size and pointer of the handle */
1409         hqspi->RxXferSize = hqspi->RxXferCount;
1410         hqspi->pRxBuffPtr = pData;
1411 
1412         /* Set the QSPI MDMA transfer complete callback */
1413         hqspi->hmdma->XferCpltCallback = QSPI_DMARxCplt;
1414 
1415         /* Set the MDMA error callback */
1416         hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1417 
1418         /* Clear the MDMA abort callback */
1419         hqspi->hmdma->XferAbortCallback = NULL;
1420 
1421       /* In Receive mode , the MDMA source is the QSPI DR register : Force the MDMA Source Increment to disable */
1422       MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE);
1423 
1424       /* Update MDMA configuration with the correct DestinationInc field for read operation */
1425       if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
1426       {
1427         MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE);
1428       }
1429       else if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
1430       {
1431         MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD);
1432       }
1433       else if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
1434       {
1435         MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD);
1436       }
1437       else
1438       {
1439        /* in case of incorrect destination data size */
1440         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1441         status = HAL_ERROR;
1442       }
1443           /* Configure QSPI: CCR register with functional as indirect read */
1444           MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1445 
1446           /* Start the transfer by re-writing the address in AR register */
1447           WRITE_REG(hqspi->Instance->AR, addr_reg);
1448 
1449         /* Enable the MDMA */
1450         if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize, 1) == HAL_OK)
1451         {
1452           /* Process unlocked */
1453           __HAL_UNLOCK(hqspi);
1454 
1455           /* Enable the QSPI transfer error Interrupt */
1456           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1457 
1458           /* Enable using MDMA by setting DMAEN, note that DMAEN bit is "reserved"
1459              but no impact on H7 HW and it minimize the cost in the footprint */
1460           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1461         }
1462         else
1463         {
1464           status = HAL_ERROR;
1465           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1466           hqspi->State = HAL_QSPI_STATE_READY;
1467 
1468           /* Process unlocked */
1469           __HAL_UNLOCK(hqspi);
1470         }
1471     }
1472     else
1473     {
1474       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1475       status = HAL_ERROR;
1476 
1477       /* Process unlocked */
1478       __HAL_UNLOCK(hqspi);
1479     }
1480   }
1481   else
1482   {
1483     status = HAL_BUSY;
1484 
1485     /* Process unlocked */
1486     __HAL_UNLOCK(hqspi);
1487   }
1488 
1489   return status;
1490 }
1491 
1492 /**
1493   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode.
1494   * @param  hqspi QSPI handle
1495   * @param  cmd structure that contains the command configuration information.
1496   * @param  cfg structure that contains the polling configuration information.
1497   * @param  Timeout Timeout duration
1498   * @note   This function is used only in Automatic Polling Mode
1499   * @retval HAL status
1500   */
1501 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1502 {
1503   HAL_StatusTypeDef status;
1504   uint32_t tickstart = HAL_GetTick();
1505 
1506   /* Check the parameters */
1507   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1508   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1509   {
1510     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1511   }
1512 
1513   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1514   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1515   {
1516     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1517   }
1518 
1519   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1520   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1521   {
1522     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1523   }
1524 
1525   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1526   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1527 
1528   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1529   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1530   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1531 
1532   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1533   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1534   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1535 
1536   /* Process locked */
1537   __HAL_LOCK(hqspi);
1538 
1539   if(hqspi->State == HAL_QSPI_STATE_READY)
1540   {
1541     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1542 
1543     /* Update state */
1544     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1545 
1546     /* Wait till BUSY flag reset */
1547     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1548 
1549     if (status == HAL_OK)
1550     {
1551       /* Configure QSPI: PSMAR register with the status match value */
1552       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1553 
1554       /* Configure QSPI: PSMKR register with the status mask value */
1555       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1556 
1557       /* Configure QSPI: PIR register with the interval value */
1558       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1559 
1560       /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1561       (otherwise there will be an infinite loop in blocking mode) */
1562       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1563                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1564 
1565       /* Call the configuration function */
1566       cmd->NbData = cfg->StatusBytesSize;
1567       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1568 
1569       /* Wait until SM flag is set to go back in idle state */
1570       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1571 
1572       if (status == HAL_OK)
1573       {
1574         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1575 
1576         /* Update state */
1577         hqspi->State = HAL_QSPI_STATE_READY;
1578       }
1579     }
1580   }
1581   else
1582   {
1583     status = HAL_BUSY;
1584   }
1585 
1586   /* Process unlocked */
1587   __HAL_UNLOCK(hqspi);
1588 
1589   /* Return function status */
1590   return status;
1591 }
1592 
1593 /**
1594   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode.
1595   * @param  hqspi QSPI handle
1596   * @param  cmd structure that contains the command configuration information.
1597   * @param  cfg structure that contains the polling configuration information.
1598   * @note   This function is used only in Automatic Polling Mode
1599   * @retval HAL status
1600   */
1601 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1602 {
1603   HAL_StatusTypeDef status;
1604   uint32_t tickstart = HAL_GetTick();
1605 
1606   /* Check the parameters */
1607   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1608   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1609   {
1610     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1611   }
1612 
1613   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1614   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1615   {
1616     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1617   }
1618 
1619   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1620   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1621   {
1622     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1623   }
1624 
1625   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1626   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1627 
1628   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1629   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1630   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1631 
1632   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1633   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1634   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1635   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1636 
1637   /* Process locked */
1638   __HAL_LOCK(hqspi);
1639 
1640   if(hqspi->State == HAL_QSPI_STATE_READY)
1641   {
1642     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1643 
1644     /* Update state */
1645     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1646 
1647     /* Wait till BUSY flag reset */
1648     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1649 
1650     if (status == HAL_OK)
1651     {
1652       /* Configure QSPI: PSMAR register with the status match value */
1653       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1654 
1655       /* Configure QSPI: PSMKR register with the status mask value */
1656       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1657 
1658       /* Configure QSPI: PIR register with the interval value */
1659       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1660 
1661       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1662       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1663                (cfg->MatchMode | cfg->AutomaticStop));
1664 
1665       /* Clear interrupt */
1666       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1667 
1668       /* Call the configuration function */
1669       cmd->NbData = cfg->StatusBytesSize;
1670       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1671 
1672       /* Process unlocked */
1673       __HAL_UNLOCK(hqspi);
1674 
1675       /* Enable the QSPI Transfer Error and status match Interrupt */
1676       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1677 
1678     }
1679     else
1680     {
1681       /* Process unlocked */
1682       __HAL_UNLOCK(hqspi);
1683     }
1684   }
1685   else
1686   {
1687     status = HAL_BUSY;
1688 
1689     /* Process unlocked */
1690     __HAL_UNLOCK(hqspi);
1691   }
1692 
1693   /* Return function status */
1694   return status;
1695 }
1696 
1697 /**
1698   * @brief  Configure the Memory Mapped mode.
1699   * @param  hqspi QSPI handle
1700   * @param  cmd structure that contains the command configuration information.
1701   * @param  cfg structure that contains the memory mapped configuration information.
1702   * @note   This function is used only in Memory mapped Mode
1703   * @retval HAL status
1704   */
1705 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1706 {
1707   HAL_StatusTypeDef status;
1708   uint32_t tickstart = HAL_GetTick();
1709 
1710   /* Check the parameters */
1711   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1712   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1713   {
1714   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1715   }
1716 
1717   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1718   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1719   {
1720     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1721   }
1722 
1723   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1724   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1725   {
1726     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1727   }
1728 
1729   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1730   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1731 
1732   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1733   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1734   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1735 
1736   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1737 
1738   /* Process locked */
1739   __HAL_LOCK(hqspi);
1740 
1741   if(hqspi->State == HAL_QSPI_STATE_READY)
1742   {
1743     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1744 
1745     /* Update state */
1746     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1747 
1748     /* Wait till BUSY flag reset */
1749     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1750 
1751     if (status == HAL_OK)
1752     {
1753       /* Configure QSPI: CR register with timeout counter enable */
1754     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1755 
1756     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1757       {
1758         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1759 
1760         /* Configure QSPI: LPTR register with the low-power timeout value */
1761         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1762 
1763         /* Clear interrupt */
1764         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1765 
1766         /* Enable the QSPI TimeOut Interrupt */
1767         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1768       }
1769 
1770       /* Call the configuration function */
1771       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1772     }
1773   }
1774   else
1775   {
1776     status = HAL_BUSY;
1777   }
1778 
1779   /* Process unlocked */
1780   __HAL_UNLOCK(hqspi);
1781 
1782   /* Return function status */
1783   return status;
1784 }
1785 
1786 /**
1787   * @brief  Transfer Error callback.
1788   * @param  hqspi QSPI handle
1789   * @retval None
1790   */
1791 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1792 {
1793   /* Prevent unused argument(s) compilation warning */
1794   UNUSED(hqspi);
1795 
1796   /* NOTE : This function should not be modified, when the callback is needed,
1797             the HAL_QSPI_ErrorCallback could be implemented in the user file
1798    */
1799 }
1800 
1801 /**
1802   * @brief  Abort completed callback.
1803   * @param  hqspi QSPI handle
1804   * @retval None
1805   */
1806 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1807 {
1808   /* Prevent unused argument(s) compilation warning */
1809   UNUSED(hqspi);
1810 
1811   /* NOTE: This function should not be modified, when the callback is needed,
1812            the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1813    */
1814 }
1815 
1816 /**
1817   * @brief  Command completed callback.
1818   * @param  hqspi QSPI handle
1819   * @retval None
1820   */
1821 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1822 {
1823   /* Prevent unused argument(s) compilation warning */
1824   UNUSED(hqspi);
1825 
1826   /* NOTE: This function should not be modified, when the callback is needed,
1827            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1828    */
1829 }
1830 
1831 /**
1832   * @brief  Rx Transfer completed callback.
1833   * @param  hqspi QSPI handle
1834   * @retval None
1835   */
1836 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1837 {
1838   /* Prevent unused argument(s) compilation warning */
1839   UNUSED(hqspi);
1840 
1841   /* NOTE: This function should not be modified, when the callback is needed,
1842            the HAL_QSPI_RxCpltCallback could be implemented in the user file
1843    */
1844 }
1845 
1846 /**
1847   * @brief  Tx Transfer completed callback.
1848   * @param  hqspi QSPI handle
1849   * @retval None
1850   */
1851 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1852 {
1853   /* Prevent unused argument(s) compilation warning */
1854   UNUSED(hqspi);
1855 
1856   /* NOTE: This function should not be modified, when the callback is needed,
1857            the HAL_QSPI_TxCpltCallback could be implemented in the user file
1858    */
1859 }
1860 
1861 
1862 /**
1863   * @brief  FIFO Threshold callback.
1864   * @param  hqspi QSPI handle
1865   * @retval None
1866   */
1867 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1868 {
1869   /* Prevent unused argument(s) compilation warning */
1870   UNUSED(hqspi);
1871 
1872   /* NOTE : This function should not be modified, when the callback is needed,
1873             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1874    */
1875 }
1876 
1877 /**
1878   * @brief  Status Match callback.
1879   * @param  hqspi QSPI handle
1880   * @retval None
1881   */
1882 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1883 {
1884   /* Prevent unused argument(s) compilation warning */
1885   UNUSED(hqspi);
1886 
1887   /* NOTE : This function should not be modified, when the callback is needed,
1888             the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1889    */
1890 }
1891 
1892 /**
1893   * @brief  Timeout callback.
1894   * @param  hqspi QSPI handle
1895   * @retval None
1896   */
1897 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1898 {
1899   /* Prevent unused argument(s) compilation warning */
1900   UNUSED(hqspi);
1901 
1902   /* NOTE : This function should not be modified, when the callback is needed,
1903             the HAL_QSPI_TimeOutCallback could be implemented in the user file
1904    */
1905 }
1906 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
1907 /**
1908   * @brief  Register a User QSPI Callback
1909   *         To be used to override the weak predefined callback
1910   * @param hqspi QSPI handle
1911   * @param CallbackId ID of the callback to be registered
1912   *        This parameter can be one of the following values:
1913   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
1914   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
1915   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
1916   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
1917   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
1918   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
1919   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
1920   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
1921   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
1922   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
1923   * @param pCallback pointer to the Callback function
1924   * @retval status
1925   */
1926 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
1927 {
1928   HAL_StatusTypeDef status = HAL_OK;
1929 
1930   if(pCallback == NULL)
1931   {
1932     /* Update the error code */
1933     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1934     return HAL_ERROR;
1935   }
1936 
1937   /* Process locked */
1938   __HAL_LOCK(hqspi);
1939 
1940   if(hqspi->State == HAL_QSPI_STATE_READY)
1941   {
1942     switch (CallbackId)
1943     {
1944     case  HAL_QSPI_ERROR_CB_ID :
1945       hqspi->ErrorCallback = pCallback;
1946       break;
1947     case HAL_QSPI_ABORT_CB_ID :
1948       hqspi->AbortCpltCallback = pCallback;
1949       break;
1950     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
1951       hqspi->FifoThresholdCallback = pCallback;
1952       break;
1953     case HAL_QSPI_CMD_CPLT_CB_ID :
1954       hqspi->CmdCpltCallback = pCallback;
1955       break;
1956     case HAL_QSPI_RX_CPLT_CB_ID :
1957       hqspi->RxCpltCallback = pCallback;
1958       break;
1959     case HAL_QSPI_TX_CPLT_CB_ID :
1960       hqspi->TxCpltCallback = pCallback;
1961       break;
1962     case HAL_QSPI_STATUS_MATCH_CB_ID :
1963       hqspi->StatusMatchCallback = pCallback;
1964       break;
1965     case HAL_QSPI_TIMEOUT_CB_ID :
1966       hqspi->TimeOutCallback = pCallback;
1967       break;
1968     case HAL_QSPI_MSP_INIT_CB_ID :
1969       hqspi->MspInitCallback = pCallback;
1970       break;
1971     case HAL_QSPI_MSP_DEINIT_CB_ID :
1972       hqspi->MspDeInitCallback = pCallback;
1973       break;
1974     default :
1975       /* Update the error code */
1976       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1977       /* update return status */
1978       status =  HAL_ERROR;
1979       break;
1980     }
1981   }
1982   else if (hqspi->State == HAL_QSPI_STATE_RESET)
1983   {
1984     switch (CallbackId)
1985     {
1986     case HAL_QSPI_MSP_INIT_CB_ID :
1987       hqspi->MspInitCallback = pCallback;
1988       break;
1989     case HAL_QSPI_MSP_DEINIT_CB_ID :
1990       hqspi->MspDeInitCallback = pCallback;
1991       break;
1992     default :
1993       /* Update the error code */
1994       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1995       /* update return status */
1996       status =  HAL_ERROR;
1997       break;
1998     }
1999   }
2000   else
2001   {
2002     /* Update the error code */
2003     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2004     /* update return status */
2005     status =  HAL_ERROR;
2006   }
2007 
2008   /* Release Lock */
2009   __HAL_UNLOCK(hqspi);
2010   return status;
2011 }
2012 
2013 /**
2014   * @brief  Unregister a User QSPI Callback
2015   *         QSPI Callback is redirected to the weak predefined callback
2016   * @param hqspi QSPI handle
2017   * @param CallbackId ID of the callback to be unregistered
2018   *        This parameter can be one of the following values:
2019   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
2020   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
2021   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2022   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
2023   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
2024   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
2025   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
2026   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
2027   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
2028   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
2029   * @retval status
2030   */
2031 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2032 {
2033   HAL_StatusTypeDef status = HAL_OK;
2034 
2035   /* Process locked */
2036   __HAL_LOCK(hqspi);
2037 
2038   if(hqspi->State == HAL_QSPI_STATE_READY)
2039   {
2040     switch (CallbackId)
2041     {
2042     case  HAL_QSPI_ERROR_CB_ID :
2043       hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2044       break;
2045     case HAL_QSPI_ABORT_CB_ID :
2046       hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2047       break;
2048     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2049       hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2050       break;
2051     case HAL_QSPI_CMD_CPLT_CB_ID :
2052       hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2053       break;
2054     case HAL_QSPI_RX_CPLT_CB_ID :
2055       hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2056       break;
2057     case HAL_QSPI_TX_CPLT_CB_ID :
2058       hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2059       break;
2060     case HAL_QSPI_STATUS_MATCH_CB_ID :
2061       hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2062       break;
2063     case HAL_QSPI_TIMEOUT_CB_ID :
2064       hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2065       break;
2066     case HAL_QSPI_MSP_INIT_CB_ID :
2067       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2068       break;
2069     case HAL_QSPI_MSP_DEINIT_CB_ID :
2070       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2071       break;
2072     default :
2073       /* Update the error code */
2074       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2075       /* update return status */
2076       status =  HAL_ERROR;
2077       break;
2078     }
2079   }
2080   else if (hqspi->State == HAL_QSPI_STATE_RESET)
2081   {
2082     switch (CallbackId)
2083     {
2084     case HAL_QSPI_MSP_INIT_CB_ID :
2085       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2086       break;
2087     case HAL_QSPI_MSP_DEINIT_CB_ID :
2088       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2089       break;
2090     default :
2091       /* Update the error code */
2092       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2093       /* update return status */
2094       status =  HAL_ERROR;
2095       break;
2096     }
2097   }
2098   else
2099   {
2100     /* Update the error code */
2101     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2102     /* update return status */
2103     status =  HAL_ERROR;
2104   }
2105 
2106   /* Release Lock */
2107   __HAL_UNLOCK(hqspi);
2108   return status;
2109 }
2110 #endif
2111 
2112 /**
2113   * @}
2114   */
2115 
2116 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2117   * @ingroup RTEMSBSPsARMSTM32H7
2118   *  @brief   QSPI control and State functions
2119   *
2120 @verbatim
2121  ===============================================================================
2122                   ##### Peripheral Control and State functions #####
2123  ===============================================================================
2124     [..]
2125     This subsection provides a set of functions allowing to :
2126       (+) Check in run-time the state of the driver.
2127       (+) Check the error code set during last operation.
2128       (+) Abort any operation.
2129 
2130 
2131 @endverbatim
2132   * @{
2133   */
2134 
2135 /**
2136   * @brief  Return the QSPI handle state.
2137   * @param  hqspi QSPI handle
2138   * @retval HAL state
2139   */
2140 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(const QSPI_HandleTypeDef *hqspi)
2141 {
2142   /* Return QSPI handle state */
2143   return hqspi->State;
2144 }
2145 
2146 /**
2147 * @brief  Return the QSPI error code.
2148 * @param  hqspi QSPI handle
2149 * @retval QSPI Error Code
2150 */
2151 uint32_t HAL_QSPI_GetError(const QSPI_HandleTypeDef *hqspi)
2152 {
2153   return hqspi->ErrorCode;
2154 }
2155 
2156 /**
2157 * @brief  Abort the current transmission.
2158 * @param  hqspi QSPI handle
2159 * @retval HAL status
2160 */
2161 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2162 {
2163   HAL_StatusTypeDef status = HAL_OK;
2164   uint32_t tickstart = HAL_GetTick();
2165 
2166   /* Check if the state is in one of the busy states */
2167   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2168   {
2169     /* Process unlocked */
2170     __HAL_UNLOCK(hqspi);
2171 
2172     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2173     {
2174       /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
2175          but no impact on H7 HW and it minimize the cost in the footprint */
2176       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2177 
2178       /* Abort MDMA */
2179       status = HAL_MDMA_Abort(hqspi->hmdma);
2180       if(status != HAL_OK)
2181       {
2182         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2183       }
2184     }
2185 
2186     if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2187     {
2188       /* Configure QSPI: CR register with Abort request */
2189       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2190       
2191       /* Wait until TC flag is set to go back in idle state */
2192       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2193       
2194       if (status == HAL_OK)
2195       {
2196         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2197         
2198         /* Wait until BUSY flag is reset */
2199         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2200       }
2201 
2202       if (status == HAL_OK)
2203       {
2204         /* Reset functional mode configuration to indirect write mode by default */
2205         CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2206         
2207         /* Update state */
2208         hqspi->State = HAL_QSPI_STATE_READY;
2209       }
2210     }
2211     else
2212     {
2213       /* Update state */
2214       hqspi->State = HAL_QSPI_STATE_READY;
2215     }
2216   }
2217 
2218   return status;
2219 }
2220 
2221 /**
2222 * @brief  Abort the current transmission (non-blocking function)
2223 * @param  hqspi QSPI handle
2224 * @retval HAL status
2225 */
2226 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2227 {
2228   HAL_StatusTypeDef status = HAL_OK;
2229 
2230   /* Check if the state is in one of the busy states */
2231   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2232   {
2233     /* Process unlocked */
2234     __HAL_UNLOCK(hqspi);
2235 
2236     /* Update QSPI state */
2237     hqspi->State = HAL_QSPI_STATE_ABORT;
2238 
2239     /* Disable all interrupts */
2240     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2241 
2242     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2243     {
2244       /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
2245          but no impact on H7 HW and it minimize the cost in the footprint */
2246       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2247 
2248       /* Abort MDMA channel */
2249       hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
2250       if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
2251       {
2252         /* Change state of QSPI */
2253         hqspi->State = HAL_QSPI_STATE_READY;
2254 
2255         /* Abort Complete callback */
2256 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2257         hqspi->AbortCpltCallback(hqspi);
2258 #else
2259         HAL_QSPI_AbortCpltCallback(hqspi);
2260 #endif
2261       }
2262     }
2263     else
2264     {
2265       if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2266       {
2267         /* Clear interrupt */
2268         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2269         
2270         /* Enable the QSPI Transfer Complete Interrupt */
2271         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2272         
2273         /* Configure QSPI: CR register with Abort request */
2274         SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2275       }    
2276       else
2277       {
2278         /* Change state of QSPI */
2279         hqspi->State = HAL_QSPI_STATE_READY;
2280       }
2281     }
2282   }
2283   return status;
2284 }
2285 
2286 /** @brief Set QSPI timeout.
2287   * @param  hqspi QSPI handle.
2288   * @param  Timeout Timeout for the QSPI memory access.
2289   * @retval None
2290   */
2291 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2292 {
2293   hqspi->Timeout = Timeout;
2294 }
2295 
2296 /** @brief Set QSPI Fifo threshold.
2297   * @param  hqspi QSPI handle.
2298   * @param  Threshold Threshold of the Fifo (value between 1 and 16).
2299   * @retval HAL status
2300   */
2301 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2302 {
2303   HAL_StatusTypeDef status = HAL_OK;
2304 
2305   /* Process locked */
2306   __HAL_LOCK(hqspi);
2307 
2308   if(hqspi->State == HAL_QSPI_STATE_READY)
2309   {
2310     /* Synchronize init structure with new FIFO threshold value */
2311     hqspi->Init.FifoThreshold = Threshold;
2312 
2313     /* Configure QSPI FIFO Threshold */
2314     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2315                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2316   }
2317   else
2318   {
2319     status = HAL_BUSY;
2320   }
2321 
2322   /* Process unlocked */
2323   __HAL_UNLOCK(hqspi);
2324 
2325   /* Return function status */
2326   return status;
2327 }
2328 
2329 /** @brief Get QSPI Fifo threshold.
2330   * @param  hqspi QSPI handle.
2331   * @retval Fifo threshold (value between 1 and 16)
2332   */
2333 uint32_t HAL_QSPI_GetFifoThreshold(const QSPI_HandleTypeDef *hqspi)
2334 {
2335   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2336 }
2337 
2338 /** @brief  Set FlashID.
2339   * @param  hqspi QSPI handle.
2340   * @param  FlashID Index of the flash memory to be accessed.
2341   *                   This parameter can be a value of @ref QSPI_Flash_Select.
2342   * @note   The FlashID is ignored when dual flash mode is enabled.
2343   * @retval HAL status
2344   */
2345 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2346 {
2347   HAL_StatusTypeDef status = HAL_OK;
2348 
2349   /* Check the parameter */
2350   assert_param(IS_QSPI_FLASH_ID(FlashID));
2351 
2352   /* Process locked */
2353   __HAL_LOCK(hqspi);
2354 
2355   if(hqspi->State == HAL_QSPI_STATE_READY)
2356   {
2357     /* Synchronize init structure with new FlashID value */
2358     hqspi->Init.FlashID = FlashID;
2359 
2360     /* Configure QSPI FlashID */
2361     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2362   }
2363   else
2364   {
2365     status = HAL_BUSY;
2366   }
2367 
2368   /* Process unlocked */
2369   __HAL_UNLOCK(hqspi);
2370 
2371   /* Return function status */
2372   return status;
2373 }
2374 
2375 /**
2376   * @}
2377   */
2378 
2379 /**
2380   * @}
2381   */
2382 
2383 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2384   * @ingroup RTEMSBSPsARMSTM32H7
2385   * @{
2386   */
2387 
2388 /**
2389   * @brief  DMA QSPI receive process complete callback.
2390   * @param  hmdma MDMA handle
2391   * @retval None
2392   */
2393 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma)
2394 {
2395   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2396   hqspi->RxXferCount = 0U;
2397 
2398   /* Enable the QSPI transfer complete Interrupt */
2399   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2400 }
2401 
2402 /**
2403   * @brief  DMA QSPI transmit process complete callback.
2404   * @param  hmdma MDMA handle
2405   * @retval None
2406   */
2407 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma)
2408 {
2409   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2410   hqspi->TxXferCount = 0U;
2411 
2412   /* Enable the QSPI transfer complete Interrupt */
2413   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2414 }
2415 
2416 /**
2417   * @brief  DMA QSPI communication error callback.
2418   * @param  hmdma MDMA handle
2419   * @retval None
2420   */
2421 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2422 {
2423   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2424 
2425   hqspi->RxXferCount = 0U;
2426   hqspi->TxXferCount = 0U;
2427   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
2428 
2429   /* Disable using MDMA by clearing DMAEN, note that DMAEN bit is "reserved"
2430      but no impact on H7 HW and it minimize the cost in the footprint */
2431   CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2432 
2433   /* Abort the QSPI */
2434   (void)HAL_QSPI_Abort_IT(hqspi);
2435 
2436 }
2437 
2438 /**
2439   * @brief  MDMA QSPI abort complete callback.
2440   * @param  hmdma MDMA handle
2441   * @retval None
2442   */
2443 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2444 {
2445   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2446 
2447   hqspi->RxXferCount = 0U;
2448   hqspi->TxXferCount = 0U;
2449 
2450   if(hqspi->State == HAL_QSPI_STATE_ABORT)
2451   {
2452     /* MDMA Abort called by QSPI abort */
2453     /* Clear interrupt */
2454     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2455 
2456     /* Enable the QSPI Transfer Complete Interrupt */
2457     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2458 
2459     /* Configure QSPI: CR register with Abort request */
2460     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2461   }
2462   else
2463   {
2464     /* MDMA Abort called due to a transfer error interrupt */
2465     /* Change state of QSPI */
2466     hqspi->State = HAL_QSPI_STATE_READY;
2467 
2468     /* Error callback */
2469 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2470     hqspi->ErrorCallback(hqspi);
2471 #else
2472     HAL_QSPI_ErrorCallback(hqspi);
2473 #endif
2474   }
2475 }
2476 
2477 /**
2478   * @brief  Wait for a flag state until timeout.
2479   * @param  hqspi QSPI handle
2480   * @param  Flag Flag checked
2481   * @param  State Value of the flag expected
2482   * @param  Tickstart Tick start value
2483   * @param  Timeout Duration of the timeout
2484   * @retval HAL status
2485   */
2486 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2487                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2488 {
2489   /* Wait until flag is in expected state */
2490   while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2491   {
2492     /* Check for the Timeout */
2493     if (Timeout != HAL_MAX_DELAY)
2494     {
2495       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2496       {
2497         hqspi->State     = HAL_QSPI_STATE_ERROR;
2498         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2499 
2500         return HAL_ERROR;
2501       }
2502     }
2503   }
2504   return HAL_OK;
2505 }
2506 
2507 /**
2508   * @brief  Configure the communication registers.
2509   * @param  hqspi QSPI handle
2510   * @param  cmd structure that contains the command configuration information
2511   * @param  FunctionalMode functional mode to configured
2512   *           This parameter can be one of the following values:
2513   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2514   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2515   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2516   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2517   * @retval None
2518   */
2519 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2520 {
2521   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2522 
2523   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2524   {
2525     /* Configure QSPI: DLR register with the number of data to read or write */
2526     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2527   }
2528 
2529   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2530   {
2531     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2532     {
2533       /* Configure QSPI: ABR register with alternate bytes value */
2534       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2535 
2536       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2537       {
2538         /*---- Command with instruction, address and alternate bytes ----*/
2539         /* Configure QSPI: CCR register with all communications parameters */
2540         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2541                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2542                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2543                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2544                                          cmd->Instruction | FunctionalMode));
2545 
2546         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2547         {
2548           /* Configure QSPI: AR register with address value */
2549           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2550         }
2551       }
2552       else
2553       {
2554         /*---- Command with instruction and alternate bytes ----*/
2555         /* Configure QSPI: CCR register with all communications parameters */
2556         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2557                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2558                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2559                                          cmd->AddressMode | cmd->InstructionMode |
2560                                          cmd->Instruction | FunctionalMode));
2561       }
2562     }
2563     else
2564     {
2565       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2566       {
2567         /*---- Command with instruction and address ----*/
2568         /* Configure QSPI: CCR register with all communications parameters */
2569         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2570                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2571                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2572                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2573 
2574         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2575         {
2576           /* Configure QSPI: AR register with address value */
2577           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2578         }
2579       }
2580       else
2581       {
2582         /*---- Command with only instruction ----*/
2583         /* Configure QSPI: CCR register with all communications parameters */
2584         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2585                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2586                                          cmd->AlternateByteMode | cmd->AddressMode |
2587                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2588       }
2589     }
2590   }
2591   else
2592   {
2593     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2594     {
2595       /* Configure QSPI: ABR register with alternate bytes value */
2596       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2597 
2598       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2599       {
2600         /*---- Command with address and alternate bytes ----*/
2601         /* Configure QSPI: CCR register with all communications parameters */
2602         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2603                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2604                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2605                                          cmd->AddressSize | cmd->AddressMode |
2606                                          cmd->InstructionMode | FunctionalMode));
2607 
2608         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2609         {
2610           /* Configure QSPI: AR register with address value */
2611           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2612         }
2613       }
2614       else
2615       {
2616         /*---- Command with only alternate bytes ----*/
2617         /* Configure QSPI: CCR register with all communications parameters */
2618         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2619                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2620                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2621                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2622       }
2623     }
2624     else
2625     {
2626       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2627       {
2628         /*---- Command with only address ----*/
2629         /* Configure QSPI: CCR register with all communications parameters */
2630         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2631                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2632                                          cmd->AlternateByteMode | cmd->AddressSize |
2633                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2634 
2635         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2636         {
2637           /* Configure QSPI: AR register with address value */
2638           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2639         }
2640       }
2641       else
2642       {
2643         /*---- Command with only data phase ----*/
2644         if (cmd->DataMode != QSPI_DATA_NONE)
2645         {
2646           /* Configure QSPI: CCR register with all communications parameters */
2647           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2648                                            cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2649                                            cmd->AlternateByteMode | cmd->AddressMode |
2650                                            cmd->InstructionMode | FunctionalMode));
2651         }
2652       }
2653     }
2654   }
2655 }
2656 
2657 /**
2658   * @}
2659   */
2660 
2661 /**
2662   * @}
2663   */
2664 
2665 #endif /* HAL_QSPI_MODULE_ENABLED */
2666 /**
2667   * @}
2668   */
2669 
2670 /**
2671   * @}
2672   */
2673 
2674 #endif /* defined(QUADSPI) */