1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_qspi.c
4   * @author  MCD Application Team
5   * @brief   QSPI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the QuadSPI interface (QSPI).
8   *           + Initialization and de-initialization functions
9   *           + Indirect functional mode management
10   *           + Memory-mapped functional mode management
11   *           + Auto-polling functional mode management
12   *           + Interrupts and flags management
13   *           + DMA channel configuration for indirect functional mode
14   *           + Errors management and abort functionality
15   *
16   *
17   ******************************************************************************
18   * @attention
19   *
20   * Copyright (c) 2016 STMicroelectronics.
21   * All rights reserved.
22   *
23   * This software is licensed under terms that can be found in the LICENSE file
24   * in the root directory of this software component.
25   * If no LICENSE file comes with this software, it is provided AS-IS.
26   *
27   ******************************************************************************
28   @verbatim
29  ===============================================================================
30                         ##### How to use this driver #####
31  ===============================================================================
32   [..]
33     *** Initialization ***
34     ======================
35     [..]
36       (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
37         (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
38         (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
39         (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
40         (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
41         (++) If interrupt mode is used, enable and configure QuadSPI global
42             interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
43         (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
44             with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
45             link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
46             DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
47       (#) Configure the flash size, the clock prescaler, the fifo threshold, the
48           clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
49 
50     *** Indirect functional mode ***
51     ================================
52     [..]
53       (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
54           functions :
55          (++) Instruction phase : the mode used and if present the instruction opcode.
56          (++) Address phase : the mode used and if present the size and the address value.
57          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
58              bytes values.
59          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
60          (++) Data phase : the mode used and if present the number of bytes.
61          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
62              if activated.
63          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
64       (#) If no data is required for the command, it is sent directly to the memory :
65          (++) In polling mode, the output of the function is done when the transfer is complete.
66          (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
67       (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
68           HAL_QSPI_Transmit_IT() after the command configuration :
69          (++) In polling mode, the output of the function is done when the transfer is complete.
70          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
71              is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
72          (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
73              HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
74       (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
75           HAL_QSPI_Receive_IT() after the command configuration :
76          (++) In polling mode, the output of the function is done when the transfer is complete.
77          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
78              is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
79          (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
80              HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
81 
82     *** Auto-polling functional mode ***
83     ====================================
84     [..]
85       (#) Configure the command sequence and the auto-polling functional mode using the
86           HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
87          (++) Instruction phase : the mode used and if present the instruction opcode.
88          (++) Address phase : the mode used and if present the size and the address value.
89          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
90              bytes values.
91          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
92          (++) Data phase : the mode used.
93          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
94              if activated.
95          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
96          (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
97              the polling interval and the automatic stop activation.
98       (#) After the configuration :
99          (++) In polling mode, the output of the function is done when the status match is reached. The
100              automatic stop is activated to avoid an infinite loop.
101          (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
102 
103     *** Memory-mapped functional mode ***
104     =====================================
105     [..]
106       (#) Configure the command sequence and the memory-mapped functional mode using the
107           HAL_QSPI_MemoryMapped() functions :
108          (++) Instruction phase : the mode used and if present the instruction opcode.
109          (++) Address phase : the mode used and the size.
110          (++) Alternate-bytes phase : the mode used and if present the size and the alternate
111              bytes values.
112          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
113          (++) Data phase : the mode used.
114          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
115              if activated.
116          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
117          (++) The timeout activation and the timeout period.
118       (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
119           the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
120 
121     *** Errors management and abort functionality ***
122     =================================================
123     [..]
124       (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
125       (#) HAL_QSPI_Abort() and HAL_QSPI_Abort_IT() functions aborts any on-going operation and
126           flushes the fifo :
127          (++) In polling mode, the output of the function is done when the transfer
128               complete bit is set and the busy bit cleared.
129          (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
130               the transfer complete bit is set.
131 
132     *** Control functions ***
133     =========================
134     [..]
135       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
136       (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
137       (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
138       (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
139       (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
140 
141     *** Callback registration ***
142     =============================================
143     [..]
144       The compilation define  USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
145       allows the user to configure dynamically the driver callbacks.
146 
147       Use Functions HAL_QSPI_RegisterCallback() to register a user callback,
148       it allows to register following callbacks:
149         (+) ErrorCallback : callback when error occurs.
150         (+) AbortCpltCallback : callback when abort is completed.
151         (+) FifoThresholdCallback : callback when the fifo threshold is reached.
152         (+) CmdCpltCallback : callback when a command without data is completed.
153         (+) RxCpltCallback : callback when a reception transfer is completed.
154         (+) TxCpltCallback : callback when a transmission transfer is completed.
155         (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
156         (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
157         (+) StatusMatchCallback : callback when a status match occurs.
158         (+) TimeOutCallback : callback when the timeout perioed expires.
159         (+) MspInitCallback    : QSPI MspInit.
160         (+) MspDeInitCallback  : QSPI MspDeInit.
161       This function takes as parameters the HAL peripheral handle, the Callback ID
162       and a pointer to the user callback function.
163 
164       Use function HAL_QSPI_UnRegisterCallback() to reset a callback to the default
165       weak (surcharged) function. It allows to reset following callbacks:
166         (+) ErrorCallback : callback when error occurs.
167         (+) AbortCpltCallback : callback when abort is completed.
168         (+) FifoThresholdCallback : callback when the fifo threshold is reached.
169         (+) CmdCpltCallback : callback when a command without data is completed.
170         (+) RxCpltCallback : callback when a reception transfer is completed.
171         (+) TxCpltCallback : callback when a transmission transfer is completed.
172         (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
173         (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
174         (+) StatusMatchCallback : callback when a status match occurs.
175         (+) TimeOutCallback : callback when the timeout perioed expires.
176         (+) MspInitCallback    : QSPI MspInit.
177         (+) MspDeInitCallback  : QSPI MspDeInit.
178       This function) takes as parameters the HAL peripheral handle and the Callback ID.
179 
180       By default, after the HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
181       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
182       Exception done for MspInit and MspDeInit callbacks that are respectively
183       reset to the legacy weak (surcharged) functions in the HAL_QSPI_Init
184       and  HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
185       If not, MspInit or MspDeInit are not null, the HAL_QSPI_Init and HAL_QSPI_DeInit
186       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
187 
188       Callbacks can be registered/unregistered in READY state only.
189       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
190       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
191       during the Init/DeInit.
192       In that case first register the MspInit/MspDeInit user callbacks
193       using HAL_QSPI_RegisterCallback before calling HAL_QSPI_DeInit
194       or HAL_QSPI_Init function.
195 
196       When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
197       not defined, the callback registering feature is not available
198       and weak (surcharged) callbacks are used.
199 
200     *** Workarounds linked to Silicon Limitation ***
201     ====================================================
202     [..]
203       (#) Workarounds Implemented inside HAL Driver
204          (++) Extra data written in the FIFO at the end of a read transfer
205 
206   @endverbatim
207   ******************************************************************************
208   */
209 
210 /* Includes ------------------------------------------------------------------*/
211 #include "stm32f4xx_hal.h"
212 
213 #if defined(QUADSPI)
214 
215 /** @addtogroup STM32F4xx_HAL_Driver
216   * @{
217   */
218 
219 /** @defgroup QSPI QSPI
220   * @brief QSPI HAL module driver
221   * @{
222   */
223 #ifdef HAL_QSPI_MODULE_ENABLED
224 
225 /* Private typedef -----------------------------------------------------------*/
226 
227 /* Private define ------------------------------------------------------------*/
228 /** @defgroup QSPI_Private_Constants QSPI Private Constants
229   * @{
230   */
231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U                     /*!<Indirect write mode*/
232 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
233 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
234 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/
235 /**
236   * @}
237   */
238 
239 /* Private macro -------------------------------------------------------------*/
240 /** @defgroup QSPI_Private_Macros QSPI Private Macros
241   * @{
242   */
243 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
244                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
245                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
246                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
247 /**
248   * @}
249   */
250 
251 /* Private variables ---------------------------------------------------------*/
252 
253 /* Private function prototypes -----------------------------------------------*/
254 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
255 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
256 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
257 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
258 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
259 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
260 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
261 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout_CPUCycle(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout);
262 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
263 
264 /* Exported functions --------------------------------------------------------*/
265 
266 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
267   * @{
268   */
269 
270 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
271   *  @brief    Initialization and Configuration functions
272   *
273 @verbatim
274 ===============================================================================
275             ##### Initialization and Configuration functions #####
276  ===============================================================================
277     [..]
278     This subsection provides a set of functions allowing to :
279       (+) Initialize the QuadSPI.
280       (+) De-initialize the QuadSPI.
281 
282 @endverbatim
283   * @{
284   */
285 
286 /**
287   * @brief Initialize the QSPI mode according to the specified parameters
288   *        in the QSPI_InitTypeDef and initialize the associated handle.
289   * @param hqspi QSPI handle
290   * @retval HAL status
291   */
HAL_QSPI_Init(QSPI_HandleTypeDef * hqspi)292 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
293 {
294   HAL_StatusTypeDef status;
295   uint32_t tickstart = HAL_GetTick();
296 
297   /* Check the QSPI handle allocation */
298   if(hqspi == NULL)
299   {
300     return HAL_ERROR;
301   }
302 
303   /* Check the parameters */
304   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
305   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
306   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
307   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
308   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
309   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
310   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
311   assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
312 
313   if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
314   {
315     assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
316   }
317 
318   if(hqspi->State == HAL_QSPI_STATE_RESET)
319   {
320     /* Allocate lock resource and initialize it */
321     hqspi->Lock = HAL_UNLOCKED;
322 
323 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
324     /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
325     hqspi->ErrorCallback         = HAL_QSPI_ErrorCallback;
326     hqspi->AbortCpltCallback     = HAL_QSPI_AbortCpltCallback;
327     hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
328     hqspi->CmdCpltCallback       = HAL_QSPI_CmdCpltCallback;
329     hqspi->RxCpltCallback        = HAL_QSPI_RxCpltCallback;
330     hqspi->TxCpltCallback        = HAL_QSPI_TxCpltCallback;
331     hqspi->RxHalfCpltCallback    = HAL_QSPI_RxHalfCpltCallback;
332     hqspi->TxHalfCpltCallback    = HAL_QSPI_TxHalfCpltCallback;
333     hqspi->StatusMatchCallback   = HAL_QSPI_StatusMatchCallback;
334     hqspi->TimeOutCallback       = HAL_QSPI_TimeOutCallback;
335 
336     if(hqspi->MspInitCallback == NULL)
337     {
338       hqspi->MspInitCallback = HAL_QSPI_MspInit;
339     }
340 
341     /* Init the low level hardware */
342     hqspi->MspInitCallback(hqspi);
343 #else
344     /* Init the low level hardware : GPIO, CLOCK */
345     HAL_QSPI_MspInit(hqspi);
346 #endif
347 
348     /* Configure the default timeout for the QSPI memory access */
349     HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
350   }
351 
352   /* Configure QSPI FIFO Threshold */
353   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
354              ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
355 
356   /* Wait till BUSY flag reset */
357   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
358 
359   if(status == HAL_OK)
360   {
361     /* Configure QSPI Clock Prescaler and Sample Shift */
362     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
363                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
364                 hqspi->Init.SampleShifting  | hqspi->Init.FlashID | hqspi->Init.DualFlash));
365 
366     /* Configure QSPI Flash Size, CS High Time and Clock Mode */
367     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
368                ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
369                 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
370 
371     /* Enable the QSPI peripheral */
372     __HAL_QSPI_ENABLE(hqspi);
373 
374     /* Set QSPI error code to none */
375     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
376 
377     /* Initialize the QSPI state */
378     hqspi->State = HAL_QSPI_STATE_READY;
379   }
380 
381   /* Release Lock */
382   __HAL_UNLOCK(hqspi);
383 
384   /* Return function status */
385   return status;
386 }
387 
388 /**
389   * @brief De-Initialize the QSPI peripheral.
390   * @param hqspi QSPI handle
391   * @retval HAL status
392   */
HAL_QSPI_DeInit(QSPI_HandleTypeDef * hqspi)393 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
394 {
395   /* Check the QSPI handle allocation */
396   if(hqspi == NULL)
397   {
398     return HAL_ERROR;
399   }
400 
401   /* Disable the QSPI Peripheral Clock */
402   __HAL_QSPI_DISABLE(hqspi);
403 
404 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
405   if(hqspi->MspDeInitCallback == NULL)
406   {
407     hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
408   }
409 
410   /* DeInit the low level hardware */
411   hqspi->MspDeInitCallback(hqspi);
412 #else
413   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
414   HAL_QSPI_MspDeInit(hqspi);
415 #endif
416 
417   /* Set QSPI error code to none */
418   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
419 
420   /* Initialize the QSPI state */
421   hqspi->State = HAL_QSPI_STATE_RESET;
422 
423   /* Release Lock */
424   __HAL_UNLOCK(hqspi);
425 
426   return HAL_OK;
427 }
428 
429 /**
430   * @brief Initialize the QSPI MSP.
431   * @param hqspi QSPI handle
432   * @retval None
433   */
HAL_QSPI_MspInit(QSPI_HandleTypeDef * hqspi)434 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
435 {
436   /* Prevent unused argument(s) compilation warning */
437   UNUSED(hqspi);
438 
439   /* NOTE : This function should not be modified, when the callback is needed,
440             the HAL_QSPI_MspInit can be implemented in the user file
441    */
442 }
443 
444 /**
445   * @brief DeInitialize the QSPI MSP.
446   * @param hqspi QSPI handle
447   * @retval None
448   */
HAL_QSPI_MspDeInit(QSPI_HandleTypeDef * hqspi)449 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
450 {
451   /* Prevent unused argument(s) compilation warning */
452   UNUSED(hqspi);
453 
454   /* NOTE : This function should not be modified, when the callback is needed,
455             the HAL_QSPI_MspDeInit can be implemented in the user file
456    */
457 }
458 
459 /**
460   * @}
461   */
462 
463 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
464   *  @brief QSPI Transmit/Receive functions
465   *
466 @verbatim
467  ===============================================================================
468                       ##### IO operation functions #####
469  ===============================================================================
470     [..]
471     This subsection provides a set of functions allowing to :
472       (+) Handle the interrupts.
473       (+) Handle the command sequence.
474       (+) Transmit data in blocking, interrupt or DMA mode.
475       (+) Receive data in blocking, interrupt or DMA mode.
476       (+) Manage the auto-polling functional mode.
477       (+) Manage the memory-mapped functional mode.
478 
479 @endverbatim
480   * @{
481   */
482 
483 /**
484   * @brief Handle QSPI interrupt request.
485   * @param hqspi QSPI handle
486   * @retval None
487   */
HAL_QSPI_IRQHandler(QSPI_HandleTypeDef * hqspi)488 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
489 {
490   __IO uint32_t *data_reg;
491   uint32_t flag = READ_REG(hqspi->Instance->SR);
492   uint32_t itsource = READ_REG(hqspi->Instance->CR);
493 
494   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
495   if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
496   {
497     data_reg = &hqspi->Instance->DR;
498 
499     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
500     {
501       /* Transmission process */
502       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
503       {
504         if (hqspi->TxXferCount > 0U)
505         {
506           /* Fill the FIFO until the threshold is reached */
507           *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
508           hqspi->pTxBuffPtr++;
509           hqspi->TxXferCount--;
510         }
511         else
512         {
513           /* No more data available for the transfer */
514           /* Disable the QSPI FIFO Threshold Interrupt */
515           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
516           break;
517         }
518       }
519     }
520     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
521     {
522       /* Receiving Process */
523       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
524       {
525         if (hqspi->RxXferCount > 0U)
526         {
527           /* Read the FIFO until the threshold is reached */
528           *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
529           hqspi->pRxBuffPtr++;
530           hqspi->RxXferCount--;
531         }
532         else
533         {
534           /* All data have been received for the transfer */
535           /* Disable the QSPI FIFO Threshold Interrupt */
536           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
537           break;
538         }
539       }
540     }
541     else
542     {
543       /* Nothing to do */
544     }
545 
546     /* FIFO Threshold callback */
547 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
548     hqspi->FifoThresholdCallback(hqspi);
549 #else
550     HAL_QSPI_FifoThresholdCallback(hqspi);
551 #endif
552   }
553 
554   /* QSPI Transfer Complete interrupt occurred -------------------------------*/
555   else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
556   {
557     /* Clear interrupt */
558     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
559 
560     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
561     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
562 
563     /* Transfer complete callback */
564     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
565     {
566       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
567       {
568         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
569         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
570 
571         /* Disable the DMA channel */
572         __HAL_DMA_DISABLE(hqspi->hdma);
573       }
574 
575       /* Clear Busy bit */
576       HAL_QSPI_Abort_IT(hqspi);
577 
578       /* Change state of QSPI */
579       hqspi->State = HAL_QSPI_STATE_READY;
580 
581       /* TX Complete callback */
582 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
583       hqspi->TxCpltCallback(hqspi);
584 #else
585       HAL_QSPI_TxCpltCallback(hqspi);
586 #endif
587     }
588     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
589     {
590       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
591       {
592         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
593         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
594 
595         /* Disable the DMA channel */
596         __HAL_DMA_DISABLE(hqspi->hdma);
597       }
598       else
599       {
600         data_reg = &hqspi->Instance->DR;
601         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
602         {
603           if (hqspi->RxXferCount > 0U)
604           {
605             /* Read the last data received in the FIFO until it is empty */
606             *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
607             hqspi->pRxBuffPtr++;
608             hqspi->RxXferCount--;
609           }
610           else
611           {
612             /* All data have been received for the transfer */
613             break;
614           }
615         }
616       }
617 
618       /* Workaround - Extra data written in the FIFO at the end of a read transfer */
619       HAL_QSPI_Abort_IT(hqspi);
620 
621       /* Change state of QSPI */
622       hqspi->State = HAL_QSPI_STATE_READY;
623 
624       /* RX Complete callback */
625 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
626       hqspi->RxCpltCallback(hqspi);
627 #else
628       HAL_QSPI_RxCpltCallback(hqspi);
629 #endif
630     }
631     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
632     {
633       /* Change state of QSPI */
634       hqspi->State = HAL_QSPI_STATE_READY;
635 
636       /* Command Complete callback */
637 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
638       hqspi->CmdCpltCallback(hqspi);
639 #else
640       HAL_QSPI_CmdCpltCallback(hqspi);
641 #endif
642     }
643     else if(hqspi->State == HAL_QSPI_STATE_ABORT)
644     {
645       /* Reset functional mode configuration to indirect write mode by default */
646       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
647 
648       /* Change state of QSPI */
649       hqspi->State = HAL_QSPI_STATE_READY;
650 
651       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
652       {
653         /* Abort called by the user */
654 
655         /* Abort Complete callback */
656 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
657         hqspi->AbortCpltCallback(hqspi);
658 #else
659         HAL_QSPI_AbortCpltCallback(hqspi);
660 #endif
661       }
662       else
663       {
664         /* Abort due to an error (eg :  DMA error) */
665 
666         /* Error callback */
667 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
668         hqspi->ErrorCallback(hqspi);
669 #else
670         HAL_QSPI_ErrorCallback(hqspi);
671 #endif
672       }
673     }
674     else
675     {
676      /* Nothing to do */
677     }
678   }
679 
680   /* QSPI Status Match interrupt occurred ------------------------------------*/
681   else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
682   {
683     /* Clear interrupt */
684     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
685 
686     /* Check if the automatic poll mode stop is activated */
687     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
688     {
689       /* Disable the QSPI Transfer Error and Status Match Interrupts */
690       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
691 
692       /* Change state of QSPI */
693       hqspi->State = HAL_QSPI_STATE_READY;
694     }
695 
696     /* Status match callback */
697 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
698     hqspi->StatusMatchCallback(hqspi);
699 #else
700     HAL_QSPI_StatusMatchCallback(hqspi);
701 #endif
702   }
703 
704   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
705   else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
706   {
707     /* Clear interrupt */
708     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
709 
710     /* Disable all the QSPI Interrupts */
711     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
712 
713     /* Set error code */
714     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
715 
716     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
717     {
718       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
719       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
720 
721       /* Disable the DMA channel */
722       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
723       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
724       {
725         /* Set error code to DMA */
726         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
727 
728         /* Change state of QSPI */
729         hqspi->State = HAL_QSPI_STATE_READY;
730 
731         /* Error callback */
732 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
733         hqspi->ErrorCallback(hqspi);
734 #else
735         HAL_QSPI_ErrorCallback(hqspi);
736 #endif
737       }
738     }
739     else
740     {
741       /* Change state of QSPI */
742       hqspi->State = HAL_QSPI_STATE_READY;
743 
744       /* Error callback */
745 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
746       hqspi->ErrorCallback(hqspi);
747 #else
748       HAL_QSPI_ErrorCallback(hqspi);
749 #endif
750     }
751   }
752 
753   /* QSPI Timeout interrupt occurred -----------------------------------------*/
754   else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
755   {
756     /* Clear interrupt */
757     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
758 
759     /* Timeout callback */
760 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
761     hqspi->TimeOutCallback(hqspi);
762 #else
763     HAL_QSPI_TimeOutCallback(hqspi);
764 #endif
765   }
766 
767    else
768   {
769    /* Nothing to do */
770   }
771 }
772 
773 /**
774   * @brief Set the command configuration.
775   * @param hqspi QSPI handle
776   * @param cmd : structure that contains the command configuration information
777   * @param Timeout Timeout duration
778   * @note   This function is used only in Indirect Read or Write Modes
779   * @retval HAL status
780   */
HAL_QSPI_Command(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t Timeout)781 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
782 {
783   HAL_StatusTypeDef status;
784   uint32_t tickstart = HAL_GetTick();
785 
786   /* Check the parameters */
787   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
788   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
789   {
790     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
791   }
792 
793   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
794   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
795   {
796     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
797   }
798 
799   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
800   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
801   {
802     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
803   }
804 
805   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
806   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
807 
808   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
809   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
810   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
811 
812   /* Process locked */
813   __HAL_LOCK(hqspi);
814 
815   if(hqspi->State == HAL_QSPI_STATE_READY)
816   {
817     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
818 
819     /* Update QSPI state */
820     hqspi->State = HAL_QSPI_STATE_BUSY;
821 
822     /* Wait till BUSY flag reset */
823     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
824 
825     if (status == HAL_OK)
826     {
827       /* Call the configuration function */
828       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
829 
830       if (cmd->DataMode == QSPI_DATA_NONE)
831       {
832         /* When there is no data phase, the transfer start as soon as the configuration is done
833         so wait until TC flag is set to go back in idle state */
834         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
835 
836         if (status == HAL_OK)
837         {
838           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
839 
840           /* Update QSPI state */
841           hqspi->State = HAL_QSPI_STATE_READY;
842         }
843       }
844       else
845       {
846         /* Update QSPI state */
847         hqspi->State = HAL_QSPI_STATE_READY;
848       }
849     }
850   }
851   else
852   {
853     status = HAL_BUSY;
854   }
855 
856   /* Process unlocked */
857   __HAL_UNLOCK(hqspi);
858 
859   /* Return function status */
860   return status;
861 }
862 
863 /**
864   * @brief Set the command configuration in interrupt mode.
865   * @param hqspi QSPI handle
866   * @param cmd structure that contains the command configuration information
867   * @note   This function is used only in Indirect Read or Write Modes
868   * @retval HAL status
869   */
HAL_QSPI_Command_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd)870 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
871 {
872   HAL_StatusTypeDef status;
873 
874   /* Check the parameters */
875   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
876   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
877   {
878     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
879   }
880 
881   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
882   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
883   {
884     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
885   }
886 
887   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
888   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
889   {
890     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
891   }
892 
893   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
894   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
895 
896   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
897   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
898   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
899 
900   /* Process locked */
901   __HAL_LOCK(hqspi);
902 
903   if(hqspi->State == HAL_QSPI_STATE_READY)
904   {
905     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
906 
907     /* Update QSPI state */
908     hqspi->State = HAL_QSPI_STATE_BUSY;
909 
910     /* Wait till BUSY flag reset */
911     status = QSPI_WaitFlagStateUntilTimeout_CPUCycle(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
912 
913     if (status == HAL_OK)
914     {
915       if (cmd->DataMode == QSPI_DATA_NONE)
916       {
917         /* Clear interrupt */
918         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
919       }
920 
921       /* Call the configuration function */
922       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
923 
924       if (cmd->DataMode == QSPI_DATA_NONE)
925       {
926         /* When there is no data phase, the transfer start as soon as the configuration is done
927         so activate TC and TE interrupts */
928         /* Process unlocked */
929         __HAL_UNLOCK(hqspi);
930 
931         /* Enable the QSPI Transfer Error Interrupt */
932         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
933       }
934       else
935       {
936         /* Update QSPI state */
937         hqspi->State = HAL_QSPI_STATE_READY;
938 
939         /* Process unlocked */
940         __HAL_UNLOCK(hqspi);
941       }
942     }
943     else
944     {
945       /* Process unlocked */
946       __HAL_UNLOCK(hqspi);
947     }
948   }
949   else
950   {
951     status = HAL_BUSY;
952 
953     /* Process unlocked */
954     __HAL_UNLOCK(hqspi);
955   }
956 
957   /* Return function status */
958   return status;
959 }
960 
961 /**
962   * @brief Transmit an amount of data in blocking mode.
963   * @param hqspi QSPI handle
964   * @param pData pointer to data buffer
965   * @param Timeout Timeout duration
966   * @note   This function is used only in Indirect Write Mode
967   * @retval HAL status
968   */
HAL_QSPI_Transmit(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)969 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
970 {
971   HAL_StatusTypeDef status = HAL_OK;
972   uint32_t tickstart = HAL_GetTick();
973   __IO uint32_t *data_reg = &hqspi->Instance->DR;
974 
975   /* Process locked */
976   __HAL_LOCK(hqspi);
977 
978   if(hqspi->State == HAL_QSPI_STATE_READY)
979   {
980     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
981 
982     if(pData != NULL )
983     {
984       /* Update state */
985       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
986 
987       /* Configure counters and size of the handle */
988       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
989       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
990       hqspi->pTxBuffPtr = pData;
991 
992       /* Configure QSPI: CCR register with functional as indirect write */
993       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
994 
995       while(hqspi->TxXferCount > 0U)
996       {
997         /* Wait until FT flag is set to send data */
998         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
999 
1000         if (status != HAL_OK)
1001         {
1002           break;
1003         }
1004 
1005         *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
1006         hqspi->pTxBuffPtr++;
1007         hqspi->TxXferCount--;
1008       }
1009 
1010       if (status == HAL_OK)
1011       {
1012         /* Wait until TC flag is set to go back in idle state */
1013         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1014 
1015         if (status == HAL_OK)
1016         {
1017           /* Clear Transfer Complete bit */
1018           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1019 
1020           /* Clear Busy bit */
1021           status = HAL_QSPI_Abort(hqspi);
1022         }
1023       }
1024 
1025       /* Update QSPI state */
1026       hqspi->State = HAL_QSPI_STATE_READY;
1027     }
1028     else
1029     {
1030       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1031       status = HAL_ERROR;
1032     }
1033   }
1034   else
1035   {
1036     status = HAL_BUSY;
1037   }
1038 
1039   /* Process unlocked */
1040   __HAL_UNLOCK(hqspi);
1041 
1042   return status;
1043 }
1044 
1045 
1046 /**
1047   * @brief Receive an amount of data in blocking mode.
1048   * @param hqspi QSPI handle
1049   * @param pData pointer to data buffer
1050   * @param Timeout Timeout duration
1051   * @note   This function is used only in Indirect Read Mode
1052   * @retval HAL status
1053   */
HAL_QSPI_Receive(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)1054 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1055 {
1056   HAL_StatusTypeDef status = HAL_OK;
1057   uint32_t tickstart = HAL_GetTick();
1058   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1059   __IO uint32_t *data_reg = &hqspi->Instance->DR;
1060 
1061   /* Process locked */
1062   __HAL_LOCK(hqspi);
1063 
1064   if(hqspi->State == HAL_QSPI_STATE_READY)
1065   {
1066     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1067 
1068     if(pData != NULL )
1069     {
1070       /* Update state */
1071       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1072 
1073       /* Configure counters and size of the handle */
1074       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1075       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1076       hqspi->pRxBuffPtr = pData;
1077 
1078       /* Configure QSPI: CCR register with functional as indirect read */
1079       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1080 
1081       /* Start the transfer by re-writing the address in AR register */
1082       WRITE_REG(hqspi->Instance->AR, addr_reg);
1083 
1084       while(hqspi->RxXferCount > 0U)
1085       {
1086         /* Wait until FT or TC flag is set to read received data */
1087         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1088 
1089         if  (status != HAL_OK)
1090         {
1091           break;
1092         }
1093 
1094         *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
1095         hqspi->pRxBuffPtr++;
1096         hqspi->RxXferCount--;
1097       }
1098 
1099       if (status == HAL_OK)
1100       {
1101         /* Wait until TC flag is set to go back in idle state */
1102         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1103 
1104         if  (status == HAL_OK)
1105         {
1106           /* Clear Transfer Complete bit */
1107           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1108 
1109           /* Workaround - Extra data written in the FIFO at the end of a read transfer */
1110           status = HAL_QSPI_Abort(hqspi);
1111         }
1112       }
1113 
1114       /* Update QSPI state */
1115       hqspi->State = HAL_QSPI_STATE_READY;
1116     }
1117     else
1118     {
1119       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1120       status = HAL_ERROR;
1121     }
1122   }
1123   else
1124   {
1125     status = HAL_BUSY;
1126   }
1127 
1128   /* Process unlocked */
1129   __HAL_UNLOCK(hqspi);
1130 
1131   return status;
1132 }
1133 
1134 /**
1135   * @brief  Send an amount of data in non-blocking mode with interrupt.
1136   * @param  hqspi QSPI handle
1137   * @param  pData pointer to data buffer
1138   * @note   This function is used only in Indirect Write Mode
1139   * @retval HAL status
1140   */
HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1141 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1142 {
1143   HAL_StatusTypeDef status = HAL_OK;
1144 
1145   /* Process locked */
1146   __HAL_LOCK(hqspi);
1147 
1148   if(hqspi->State == HAL_QSPI_STATE_READY)
1149   {
1150     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1151 
1152     if(pData != NULL )
1153     {
1154       /* Update state */
1155       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1156 
1157       /* Configure counters and size of the handle */
1158       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1159       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1160       hqspi->pTxBuffPtr = pData;
1161 
1162       /* Clear interrupt */
1163       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1164 
1165       /* Configure QSPI: CCR register with functional as indirect write */
1166       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1167 
1168       /* Process unlocked */
1169       __HAL_UNLOCK(hqspi);
1170 
1171       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1172       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1173     }
1174     else
1175     {
1176       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1177       status = HAL_ERROR;
1178 
1179       /* Process unlocked */
1180       __HAL_UNLOCK(hqspi);
1181     }
1182   }
1183   else
1184   {
1185     status = HAL_BUSY;
1186 
1187     /* Process unlocked */
1188     __HAL_UNLOCK(hqspi);
1189   }
1190 
1191   return status;
1192 }
1193 
1194 /**
1195   * @brief  Receive an amount of data in non-blocking mode with interrupt.
1196   * @param  hqspi QSPI handle
1197   * @param  pData pointer to data buffer
1198   * @note   This function is used only in Indirect Read Mode
1199   * @retval HAL status
1200   */
HAL_QSPI_Receive_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1201 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1202 {
1203   HAL_StatusTypeDef status = HAL_OK;
1204   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1205 
1206   /* Process locked */
1207   __HAL_LOCK(hqspi);
1208 
1209   if(hqspi->State == HAL_QSPI_STATE_READY)
1210   {
1211     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1212 
1213     if(pData != NULL )
1214     {
1215       /* Update state */
1216       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1217 
1218       /* Configure counters and size of the handle */
1219       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1220       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1221       hqspi->pRxBuffPtr = pData;
1222 
1223       /* Clear interrupt */
1224       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1225 
1226       /* Configure QSPI: CCR register with functional as indirect read */
1227       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1228 
1229       /* Start the transfer by re-writing the address in AR register */
1230       WRITE_REG(hqspi->Instance->AR, addr_reg);
1231 
1232       /* Process unlocked */
1233       __HAL_UNLOCK(hqspi);
1234 
1235       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1236       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1237     }
1238     else
1239     {
1240       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1241       status = HAL_ERROR;
1242 
1243       /* Process unlocked */
1244       __HAL_UNLOCK(hqspi);
1245     }
1246   }
1247   else
1248   {
1249     status = HAL_BUSY;
1250 
1251     /* Process unlocked */
1252     __HAL_UNLOCK(hqspi);
1253   }
1254 
1255   return status;
1256 }
1257 
1258 /**
1259   * @brief  Send an amount of data in non-blocking mode with DMA.
1260   * @param  hqspi QSPI handle
1261   * @param  pData pointer to data buffer
1262   * @note   This function is used only in Indirect Write Mode
1263   * @note   If DMA peripheral access is configured as halfword, the number
1264   *         of data and the fifo threshold should be aligned on halfword
1265   * @note   If DMA peripheral access is configured as word, the number
1266   *         of data and the fifo threshold should be aligned on word
1267   * @retval HAL status
1268   */
HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1269 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1270 {
1271   HAL_StatusTypeDef status = HAL_OK;
1272   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1273 
1274   /* Process locked */
1275   __HAL_LOCK(hqspi);
1276 
1277   if(hqspi->State == HAL_QSPI_STATE_READY)
1278   {
1279     /* Clear the error code */
1280     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1281 
1282     if(pData != NULL )
1283     {
1284       /* Configure counters of the handle */
1285       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1286       {
1287         hqspi->TxXferCount = data_size;
1288       }
1289       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1290       {
1291         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1292         {
1293           /* The number of data or the fifo threshold is not aligned on halfword
1294           => no transfer possible with DMA peripheral access configured as halfword */
1295           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1296           status = HAL_ERROR;
1297 
1298           /* Process unlocked */
1299           __HAL_UNLOCK(hqspi);
1300         }
1301         else
1302         {
1303           hqspi->TxXferCount = (data_size >> 1U);
1304         }
1305       }
1306       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1307       {
1308         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1309         {
1310           /* The number of data or the fifo threshold is not aligned on word
1311           => no transfer possible with DMA peripheral access configured as word */
1312           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1313           status = HAL_ERROR;
1314 
1315           /* Process unlocked */
1316           __HAL_UNLOCK(hqspi);
1317         }
1318         else
1319         {
1320           hqspi->TxXferCount = (data_size >> 2U);
1321         }
1322       }
1323       else
1324       {
1325         /* Nothing to do */
1326       }
1327 
1328       if (status == HAL_OK)
1329       {
1330         /* Update state */
1331         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1332 
1333         /* Clear interrupt */
1334         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1335 
1336         /* Configure size and pointer of the handle */
1337         hqspi->TxXferSize = hqspi->TxXferCount;
1338         hqspi->pTxBuffPtr = pData;
1339 
1340         /* Configure QSPI: CCR register with functional mode as indirect write */
1341         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1342 
1343         /* Set the QSPI DMA transfer complete callback */
1344         hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
1345 
1346         /* Set the QSPI DMA Half transfer complete callback */
1347         hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
1348 
1349         /* Set the DMA error callback */
1350         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1351 
1352         /* Clear the DMA abort callback */
1353         hqspi->hdma->XferAbortCallback = NULL;
1354 
1355 #if defined (QSPI1_V2_1L)
1356         /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
1357            AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
1358            Change the following configuration of DMA peripheral
1359              - Enable peripheral increment
1360              - Disable memory increment
1361              - Set DMA direction as peripheral to memory mode */
1362 
1363         /* Enable peripheral increment mode of the DMA */
1364         hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
1365 
1366         /* Disable memory increment mode of the DMA */
1367         hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
1368 
1369         /* Update peripheral/memory increment mode bits */
1370         MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
1371 
1372         /* Configure the direction of the DMA */
1373         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1374 #else
1375         /* Configure the direction of the DMA */
1376         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1377 #endif /* QSPI1_V2_1L */
1378 
1379         /* Update direction mode bit */
1380         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1381 
1382         /* Enable the QSPI transmit DMA Channel */
1383         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
1384         {
1385           /* Process unlocked */
1386           __HAL_UNLOCK(hqspi);
1387 
1388           /* Enable the QSPI transfer error Interrupt */
1389           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1390 
1391           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1392           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1393         }
1394         else
1395         {
1396           status = HAL_ERROR;
1397           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1398           hqspi->State = HAL_QSPI_STATE_READY;
1399 
1400           /* Process unlocked */
1401           __HAL_UNLOCK(hqspi);
1402         }
1403      }
1404     }
1405     else
1406     {
1407       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1408       status = HAL_ERROR;
1409 
1410       /* Process unlocked */
1411       __HAL_UNLOCK(hqspi);
1412     }
1413   }
1414   else
1415   {
1416     status = HAL_BUSY;
1417 
1418     /* Process unlocked */
1419     __HAL_UNLOCK(hqspi);
1420   }
1421 
1422   return status;
1423 }
1424 
1425 /**
1426   * @brief  Receive an amount of data in non-blocking mode with DMA.
1427   * @param  hqspi QSPI handle
1428   * @param  pData pointer to data buffer.
1429   * @note   This function is used only in Indirect Read Mode
1430   * @note   If DMA peripheral access is configured as halfword, the number
1431   *         of data and the fifo threshold should be aligned on halfword
1432   * @note   If DMA peripheral access is configured as word, the number
1433   *         of data and the fifo threshold should be aligned on word
1434   * @retval HAL status
1435   */
HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1436 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1437 {
1438   HAL_StatusTypeDef status = HAL_OK;
1439   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1440   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1441 
1442   /* Process locked */
1443   __HAL_LOCK(hqspi);
1444 
1445   if(hqspi->State == HAL_QSPI_STATE_READY)
1446   {
1447     /* Clear the error code */
1448     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1449 
1450     if(pData != NULL )
1451     {
1452       /* Configure counters of the handle */
1453       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1454       {
1455         hqspi->RxXferCount = data_size;
1456       }
1457       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1458       {
1459         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1460         {
1461           /* The number of data or the fifo threshold is not aligned on halfword
1462              => no transfer possible with DMA peripheral access configured as halfword */
1463           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1464           status = HAL_ERROR;
1465 
1466           /* Process unlocked */
1467           __HAL_UNLOCK(hqspi);
1468         }
1469         else
1470         {
1471           hqspi->RxXferCount = (data_size >> 1U);
1472         }
1473       }
1474       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1475       {
1476         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1477         {
1478           /* The number of data or the fifo threshold is not aligned on word
1479              => no transfer possible with DMA peripheral access configured as word */
1480           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1481           status = HAL_ERROR;
1482 
1483           /* Process unlocked */
1484           __HAL_UNLOCK(hqspi);
1485         }
1486         else
1487         {
1488           hqspi->RxXferCount = (data_size >> 2U);
1489         }
1490       }
1491       else
1492       {
1493         /* Nothing to do */
1494       }
1495 
1496       if (status == HAL_OK)
1497       {
1498         /* Update state */
1499         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1500 
1501         /* Clear interrupt */
1502         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1503 
1504         /* Configure size and pointer of the handle */
1505         hqspi->RxXferSize = hqspi->RxXferCount;
1506         hqspi->pRxBuffPtr = pData;
1507 
1508         /* Set the QSPI DMA transfer complete callback */
1509         hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
1510 
1511         /* Set the QSPI DMA Half transfer complete callback */
1512         hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
1513 
1514         /* Set the DMA error callback */
1515         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1516 
1517         /* Clear the DMA abort callback */
1518         hqspi->hdma->XferAbortCallback = NULL;
1519 
1520 #if defined (QSPI1_V2_1L)
1521       /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
1522          AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
1523          Change the following configuration of DMA peripheral
1524            - Enable peripheral increment
1525            - Disable memory increment
1526            - Set DMA direction as memory to peripheral mode
1527            - 4 Extra words (32-bits) are added for read operation to guarantee
1528               the last data is transferred from DMA FIFO to RAM memory */
1529 
1530         /* Enable peripheral increment of the DMA */
1531         hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
1532 
1533         /* Disable memory increment of the DMA */
1534         hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
1535 
1536         /* Update peripheral/memory increment mode bits */
1537         MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
1538 
1539         /* Configure the direction of the DMA */
1540         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1541 
1542         /* 4 Extra words (32-bits) are needed for read operation to guarantee
1543         the last data is transferred from DMA FIFO to RAM memory */
1544         WRITE_REG(hqspi->Instance->DLR, (data_size - 1U + 16U));
1545 
1546         /* Update direction mode bit */
1547         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1548 
1549         /* Configure QSPI: CCR register with functional as indirect read */
1550         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1551 
1552         /* Start the transfer by re-writing the address in AR register */
1553         WRITE_REG(hqspi->Instance->AR, addr_reg);
1554 
1555         /* Enable the DMA Channel */
1556         if(HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
1557         {
1558           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1559           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1560 
1561           /* Process unlocked */
1562           __HAL_UNLOCK(hqspi);
1563 
1564           /* Enable the QSPI transfer error Interrupt */
1565           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1566         }
1567         else
1568         {
1569           status = HAL_ERROR;
1570           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1571           hqspi->State = HAL_QSPI_STATE_READY;
1572 
1573           /* Process unlocked */
1574           __HAL_UNLOCK(hqspi);
1575         }
1576 #else
1577         /* Configure the direction of the DMA */
1578         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1579 
1580         /* Update direction mode bit */
1581         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1582 
1583         /* Enable the DMA Channel */
1584         if(HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize)== HAL_OK)
1585         {
1586           /* Configure QSPI: CCR register with functional as indirect read */
1587           MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1588 
1589           /* Start the transfer by re-writing the address in AR register */
1590           WRITE_REG(hqspi->Instance->AR, addr_reg);
1591 
1592           /* Process unlocked */
1593           __HAL_UNLOCK(hqspi);
1594 
1595           /* Enable the QSPI transfer error Interrupt */
1596           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1597 
1598           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1599           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1600         }
1601         else
1602         {
1603           status = HAL_ERROR;
1604           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1605           hqspi->State = HAL_QSPI_STATE_READY;
1606 
1607           /* Process unlocked */
1608           __HAL_UNLOCK(hqspi);
1609         }
1610 #endif /* QSPI1_V2_1L */
1611       }
1612     }
1613     else
1614     {
1615       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1616       status = HAL_ERROR;
1617 
1618       /* Process unlocked */
1619       __HAL_UNLOCK(hqspi);
1620     }
1621   }
1622   else
1623   {
1624     status = HAL_BUSY;
1625 
1626     /* Process unlocked */
1627     __HAL_UNLOCK(hqspi);
1628   }
1629 
1630   return status;
1631 }
1632 
1633 /**
1634   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode.
1635   * @param  hqspi QSPI handle
1636   * @param  cmd structure that contains the command configuration information.
1637   * @param  cfg structure that contains the polling configuration information.
1638   * @param  Timeout Timeout duration
1639   * @note   This function is used only in Automatic Polling Mode
1640   * @retval HAL status
1641   */
HAL_QSPI_AutoPolling(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg,uint32_t Timeout)1642 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1643 {
1644   HAL_StatusTypeDef status;
1645   uint32_t tickstart = HAL_GetTick();
1646 
1647   /* Check the parameters */
1648   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1649   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1650   {
1651     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1652   }
1653 
1654   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1655   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1656   {
1657     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1658   }
1659 
1660   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1661   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1662   {
1663     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1664   }
1665 
1666   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1667   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1668 
1669   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1670   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1671   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1672 
1673   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1674   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1675   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1676 
1677   /* Process locked */
1678   __HAL_LOCK(hqspi);
1679 
1680   if(hqspi->State == HAL_QSPI_STATE_READY)
1681   {
1682     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1683 
1684     /* Update state */
1685     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1686 
1687     /* Wait till BUSY flag reset */
1688     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1689 
1690     if (status == HAL_OK)
1691     {
1692       /* Configure QSPI: PSMAR register with the status match value */
1693       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1694 
1695       /* Configure QSPI: PSMKR register with the status mask value */
1696       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1697 
1698       /* Configure QSPI: PIR register with the interval value */
1699       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1700 
1701       /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1702       (otherwise there will be an infinite loop in blocking mode) */
1703       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1704                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1705 
1706       /* Call the configuration function */
1707       cmd->NbData = cfg->StatusBytesSize;
1708       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1709 
1710       /* Wait until SM flag is set to go back in idle state */
1711       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1712 
1713       if (status == HAL_OK)
1714       {
1715         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1716 
1717         /* Update state */
1718         hqspi->State = HAL_QSPI_STATE_READY;
1719       }
1720     }
1721   }
1722   else
1723   {
1724     status = HAL_BUSY;
1725   }
1726 
1727   /* Process unlocked */
1728   __HAL_UNLOCK(hqspi);
1729 
1730   /* Return function status */
1731   return status;
1732 }
1733 
1734 /**
1735   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode.
1736   * @param  hqspi QSPI handle
1737   * @param  cmd structure that contains the command configuration information.
1738   * @param  cfg structure that contains the polling configuration information.
1739   * @note   This function is used only in Automatic Polling Mode
1740   * @retval HAL status
1741   */
HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg)1742 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1743 {
1744   HAL_StatusTypeDef status;
1745 
1746   /* Check the parameters */
1747   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1748   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1749   {
1750     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1751   }
1752 
1753   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1754   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1755   {
1756     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1757   }
1758 
1759   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1760   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1761   {
1762     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1763   }
1764 
1765   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1766   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1767 
1768   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1769   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1770   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1771 
1772   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1773   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1774   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1775   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1776 
1777   /* Process locked */
1778   __HAL_LOCK(hqspi);
1779 
1780   if(hqspi->State == HAL_QSPI_STATE_READY)
1781   {
1782     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1783 
1784     /* Update state */
1785     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1786 
1787     /* Wait till BUSY flag reset */
1788     status = QSPI_WaitFlagStateUntilTimeout_CPUCycle(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
1789 
1790     if (status == HAL_OK)
1791     {
1792       /* Configure QSPI: PSMAR register with the status match value */
1793       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1794 
1795       /* Configure QSPI: PSMKR register with the status mask value */
1796       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1797 
1798       /* Configure QSPI: PIR register with the interval value */
1799       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1800 
1801       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1802       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1803                (cfg->MatchMode | cfg->AutomaticStop));
1804 
1805       /* Clear interrupt */
1806       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1807 
1808       /* Call the configuration function */
1809       cmd->NbData = cfg->StatusBytesSize;
1810       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1811 
1812       /* Process unlocked */
1813       __HAL_UNLOCK(hqspi);
1814 
1815       /* Enable the QSPI Transfer Error and status match Interrupt */
1816       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1817 
1818     }
1819     else
1820     {
1821       /* Process unlocked */
1822       __HAL_UNLOCK(hqspi);
1823     }
1824   }
1825   else
1826   {
1827     status = HAL_BUSY;
1828 
1829     /* Process unlocked */
1830     __HAL_UNLOCK(hqspi);
1831   }
1832 
1833   /* Return function status */
1834   return status;
1835 }
1836 
1837 /**
1838   * @brief  Configure the Memory Mapped mode.
1839   * @param  hqspi QSPI handle
1840   * @param  cmd structure that contains the command configuration information.
1841   * @param  cfg structure that contains the memory mapped configuration information.
1842   * @note   This function is used only in Memory mapped Mode
1843   * @retval HAL status
1844   */
HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_MemoryMappedTypeDef * cfg)1845 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1846 {
1847   HAL_StatusTypeDef status;
1848   uint32_t tickstart = HAL_GetTick();
1849 
1850   /* Check the parameters */
1851   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1852   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1853   {
1854   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1855   }
1856 
1857   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1858   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1859   {
1860     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1861   }
1862 
1863   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1864   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1865   {
1866     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1867   }
1868 
1869   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1870   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1871 
1872   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1873   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1874   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1875 
1876   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1877 
1878   /* Process locked */
1879   __HAL_LOCK(hqspi);
1880 
1881   if(hqspi->State == HAL_QSPI_STATE_READY)
1882   {
1883     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1884 
1885     /* Update state */
1886     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1887 
1888     /* Wait till BUSY flag reset */
1889     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1890 
1891     if (status == HAL_OK)
1892     {
1893       /* Configure QSPI: CR register with timeout counter enable */
1894     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1895 
1896     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1897       {
1898         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1899 
1900         /* Configure QSPI: LPTR register with the low-power timeout value */
1901         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1902 
1903         /* Clear interrupt */
1904         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1905 
1906         /* Enable the QSPI TimeOut Interrupt */
1907         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1908       }
1909 
1910       /* Call the configuration function */
1911       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1912     }
1913   }
1914   else
1915   {
1916     status = HAL_BUSY;
1917   }
1918 
1919   /* Process unlocked */
1920   __HAL_UNLOCK(hqspi);
1921 
1922   /* Return function status */
1923   return status;
1924 }
1925 
1926 /**
1927   * @brief  Transfer Error callback.
1928   * @param  hqspi QSPI handle
1929   * @retval None
1930   */
HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef * hqspi)1931 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1932 {
1933   /* Prevent unused argument(s) compilation warning */
1934   UNUSED(hqspi);
1935 
1936   /* NOTE : This function should not be modified, when the callback is needed,
1937             the HAL_QSPI_ErrorCallback could be implemented in the user file
1938    */
1939 }
1940 
1941 /**
1942   * @brief  Abort completed callback.
1943   * @param  hqspi QSPI handle
1944   * @retval None
1945   */
HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef * hqspi)1946 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1947 {
1948   /* Prevent unused argument(s) compilation warning */
1949   UNUSED(hqspi);
1950 
1951   /* NOTE: This function should not be modified, when the callback is needed,
1952            the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1953    */
1954 }
1955 
1956 /**
1957   * @brief  Command completed callback.
1958   * @param  hqspi QSPI handle
1959   * @retval None
1960   */
HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef * hqspi)1961 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1962 {
1963   /* Prevent unused argument(s) compilation warning */
1964   UNUSED(hqspi);
1965 
1966   /* NOTE: This function should not be modified, when the callback is needed,
1967            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1968    */
1969 }
1970 
1971 /**
1972   * @brief  Rx Transfer completed callback.
1973   * @param  hqspi QSPI handle
1974   * @retval None
1975   */
HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef * hqspi)1976 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1977 {
1978   /* Prevent unused argument(s) compilation warning */
1979   UNUSED(hqspi);
1980 
1981   /* NOTE: This function should not be modified, when the callback is needed,
1982            the HAL_QSPI_RxCpltCallback could be implemented in the user file
1983    */
1984 }
1985 
1986 /**
1987   * @brief  Tx Transfer completed callback.
1988   * @param  hqspi QSPI handle
1989   * @retval None
1990   */
HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef * hqspi)1991 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1992 {
1993   /* Prevent unused argument(s) compilation warning */
1994   UNUSED(hqspi);
1995 
1996   /* NOTE: This function should not be modified, when the callback is needed,
1997            the HAL_QSPI_TxCpltCallback could be implemented in the user file
1998    */
1999 }
2000 
2001 /**
2002   * @brief  Rx Half Transfer completed callback.
2003   * @param  hqspi QSPI handle
2004   * @retval None
2005   */
HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)2006 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
2007 {
2008   /* Prevent unused argument(s) compilation warning */
2009   UNUSED(hqspi);
2010 
2011   /* NOTE: This function should not be modified, when the callback is needed,
2012            the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
2013    */
2014 }
2015 
2016 /**
2017   * @brief  Tx Half Transfer completed callback.
2018   * @param  hqspi QSPI handle
2019   * @retval None
2020   */
HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)2021 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
2022 {
2023   /* Prevent unused argument(s) compilation warning */
2024   UNUSED(hqspi);
2025 
2026   /* NOTE: This function should not be modified, when the callback is needed,
2027            the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
2028    */
2029 }
2030 
2031 /**
2032   * @brief  FIFO Threshold callback.
2033   * @param  hqspi QSPI handle
2034   * @retval None
2035   */
HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef * hqspi)2036 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
2037 {
2038   /* Prevent unused argument(s) compilation warning */
2039   UNUSED(hqspi);
2040 
2041   /* NOTE : This function should not be modified, when the callback is needed,
2042             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
2043    */
2044 }
2045 
2046 /**
2047   * @brief  Status Match callback.
2048   * @param  hqspi QSPI handle
2049   * @retval None
2050   */
HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef * hqspi)2051 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
2052 {
2053   /* Prevent unused argument(s) compilation warning */
2054   UNUSED(hqspi);
2055 
2056   /* NOTE : This function should not be modified, when the callback is needed,
2057             the HAL_QSPI_StatusMatchCallback could be implemented in the user file
2058    */
2059 }
2060 
2061 /**
2062   * @brief  Timeout callback.
2063   * @param  hqspi QSPI handle
2064   * @retval None
2065   */
HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef * hqspi)2066 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
2067 {
2068   /* Prevent unused argument(s) compilation warning */
2069   UNUSED(hqspi);
2070 
2071   /* NOTE : This function should not be modified, when the callback is needed,
2072             the HAL_QSPI_TimeOutCallback could be implemented in the user file
2073    */
2074 }
2075 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2076 /**
2077   * @brief  Register a User QSPI Callback
2078   *         To be used instead of the weak (surcharged) predefined callback
2079   * @param hqspi QSPI handle
2080   * @param CallbackId ID of the callback to be registered
2081   *        This parameter can be one of the following values:
2082   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
2083   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
2084   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2085   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
2086   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
2087   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
2088   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
2089   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
2090   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
2091   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
2092   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
2093   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
2094   * @param pCallback pointer to the Callback function
2095   * @retval status
2096   */
HAL_QSPI_RegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId,pQSPI_CallbackTypeDef pCallback)2097 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
2098 {
2099   HAL_StatusTypeDef status = HAL_OK;
2100 
2101   if(pCallback == NULL)
2102   {
2103     /* Update the error code */
2104     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2105     return HAL_ERROR;
2106   }
2107 
2108   /* Process locked */
2109   __HAL_LOCK(hqspi);
2110 
2111   if(hqspi->State == HAL_QSPI_STATE_READY)
2112   {
2113     switch (CallbackId)
2114     {
2115     case  HAL_QSPI_ERROR_CB_ID :
2116       hqspi->ErrorCallback = pCallback;
2117       break;
2118     case HAL_QSPI_ABORT_CB_ID :
2119       hqspi->AbortCpltCallback = pCallback;
2120       break;
2121     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2122       hqspi->FifoThresholdCallback = pCallback;
2123       break;
2124     case HAL_QSPI_CMD_CPLT_CB_ID :
2125       hqspi->CmdCpltCallback = pCallback;
2126       break;
2127     case HAL_QSPI_RX_CPLT_CB_ID :
2128       hqspi->RxCpltCallback = pCallback;
2129       break;
2130     case HAL_QSPI_TX_CPLT_CB_ID :
2131       hqspi->TxCpltCallback = pCallback;
2132       break;
2133     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2134       hqspi->RxHalfCpltCallback = pCallback;
2135       break;
2136     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2137       hqspi->TxHalfCpltCallback = pCallback;
2138       break;
2139     case HAL_QSPI_STATUS_MATCH_CB_ID :
2140       hqspi->StatusMatchCallback = pCallback;
2141       break;
2142     case HAL_QSPI_TIMEOUT_CB_ID :
2143       hqspi->TimeOutCallback = pCallback;
2144       break;
2145     case HAL_QSPI_MSP_INIT_CB_ID :
2146       hqspi->MspInitCallback = pCallback;
2147       break;
2148     case HAL_QSPI_MSP_DEINIT_CB_ID :
2149       hqspi->MspDeInitCallback = pCallback;
2150       break;
2151     default :
2152       /* Update the error code */
2153       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2154       /* update return status */
2155       status =  HAL_ERROR;
2156       break;
2157     }
2158   }
2159   else if (hqspi->State == HAL_QSPI_STATE_RESET)
2160   {
2161     switch (CallbackId)
2162     {
2163     case HAL_QSPI_MSP_INIT_CB_ID :
2164       hqspi->MspInitCallback = pCallback;
2165       break;
2166     case HAL_QSPI_MSP_DEINIT_CB_ID :
2167       hqspi->MspDeInitCallback = pCallback;
2168       break;
2169     default :
2170       /* Update the error code */
2171       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2172       /* update return status */
2173       status =  HAL_ERROR;
2174       break;
2175     }
2176   }
2177   else
2178   {
2179     /* Update the error code */
2180     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2181     /* update return status */
2182     status =  HAL_ERROR;
2183   }
2184 
2185   /* Release Lock */
2186   __HAL_UNLOCK(hqspi);
2187   return status;
2188 }
2189 
2190 /**
2191   * @brief  Unregister a User QSPI Callback
2192   *         QSPI Callback is redirected to the weak (surcharged) predefined callback
2193   * @param hqspi QSPI handle
2194   * @param CallbackId ID of the callback to be unregistered
2195   *        This parameter can be one of the following values:
2196   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
2197   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
2198   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2199   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
2200   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
2201   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
2202   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
2203   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
2204   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
2205   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
2206   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
2207   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
2208   * @retval status
2209   */
HAL_QSPI_UnRegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId)2210 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2211 {
2212   HAL_StatusTypeDef status = HAL_OK;
2213 
2214   /* Process locked */
2215   __HAL_LOCK(hqspi);
2216 
2217   if(hqspi->State == HAL_QSPI_STATE_READY)
2218   {
2219     switch (CallbackId)
2220     {
2221     case  HAL_QSPI_ERROR_CB_ID :
2222       hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2223       break;
2224     case HAL_QSPI_ABORT_CB_ID :
2225       hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2226       break;
2227     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2228       hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2229       break;
2230     case HAL_QSPI_CMD_CPLT_CB_ID :
2231       hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2232       break;
2233     case HAL_QSPI_RX_CPLT_CB_ID :
2234       hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2235       break;
2236     case HAL_QSPI_TX_CPLT_CB_ID :
2237       hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2238       break;
2239     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2240       hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
2241       break;
2242     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2243       hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
2244       break;
2245     case HAL_QSPI_STATUS_MATCH_CB_ID :
2246       hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2247       break;
2248     case HAL_QSPI_TIMEOUT_CB_ID :
2249       hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2250       break;
2251     case HAL_QSPI_MSP_INIT_CB_ID :
2252       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2253       break;
2254     case HAL_QSPI_MSP_DEINIT_CB_ID :
2255       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2256       break;
2257     default :
2258       /* Update the error code */
2259       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2260       /* update return status */
2261       status =  HAL_ERROR;
2262       break;
2263     }
2264   }
2265   else if (hqspi->State == HAL_QSPI_STATE_RESET)
2266   {
2267     switch (CallbackId)
2268     {
2269     case HAL_QSPI_MSP_INIT_CB_ID :
2270       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2271       break;
2272     case HAL_QSPI_MSP_DEINIT_CB_ID :
2273       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2274       break;
2275     default :
2276       /* Update the error code */
2277       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2278       /* update return status */
2279       status =  HAL_ERROR;
2280       break;
2281     }
2282   }
2283   else
2284   {
2285     /* Update the error code */
2286     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2287     /* update return status */
2288     status =  HAL_ERROR;
2289   }
2290 
2291   /* Release Lock */
2292   __HAL_UNLOCK(hqspi);
2293   return status;
2294 }
2295 #endif
2296 
2297 /**
2298   * @}
2299   */
2300 
2301 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2302   *  @brief   QSPI control and State functions
2303   *
2304 @verbatim
2305  ===============================================================================
2306                   ##### Peripheral Control and State functions #####
2307  ===============================================================================
2308     [..]
2309     This subsection provides a set of functions allowing to :
2310       (+) Check in run-time the state of the driver.
2311       (+) Check the error code set during last operation.
2312       (+) Abort any operation.
2313 
2314 
2315 @endverbatim
2316   * @{
2317   */
2318 
2319 /**
2320   * @brief  Return the QSPI handle state.
2321   * @param  hqspi QSPI handle
2322   * @retval HAL state
2323   */
HAL_QSPI_GetState(QSPI_HandleTypeDef * hqspi)2324 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2325 {
2326   /* Return QSPI handle state */
2327   return hqspi->State;
2328 }
2329 
2330 /**
2331 * @brief  Return the QSPI error code.
2332 * @param  hqspi QSPI handle
2333 * @retval QSPI Error Code
2334 */
HAL_QSPI_GetError(QSPI_HandleTypeDef * hqspi)2335 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2336 {
2337   return hqspi->ErrorCode;
2338 }
2339 
2340 /**
2341 * @brief  Abort the current transmission.
2342 * @param  hqspi QSPI handle
2343 * @retval HAL status
2344 */
HAL_QSPI_Abort(QSPI_HandleTypeDef * hqspi)2345 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2346 {
2347   HAL_StatusTypeDef status = HAL_OK;
2348   uint32_t tickstart = HAL_GetTick();
2349 
2350   /* Check if the state is in one of the busy states */
2351   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2352   {
2353     /* Process unlocked */
2354     __HAL_UNLOCK(hqspi);
2355 
2356     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2357     {
2358       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2359       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2360 
2361       /* Abort DMA channel */
2362       status = HAL_DMA_Abort(hqspi->hdma);
2363       if(status != HAL_OK)
2364       {
2365         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2366       }
2367     }
2368 
2369     if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2370     {
2371       /* Configure QSPI: CR register with Abort request */
2372       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2373 
2374       /* Wait until TC flag is set to go back in idle state */
2375       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2376 
2377       if (status == HAL_OK)
2378       {
2379         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2380 
2381         /* Wait until BUSY flag is reset */
2382         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2383       }
2384 
2385       if (status == HAL_OK)
2386       {
2387         /* Reset functional mode configuration to indirect write mode by default */
2388         CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2389 
2390         /* Update state */
2391         hqspi->State = HAL_QSPI_STATE_READY;
2392       }
2393     }
2394     else
2395     {
2396       /* Update state */
2397       hqspi->State = HAL_QSPI_STATE_READY;
2398     }
2399   }
2400 
2401   return status;
2402 }
2403 
2404 /**
2405 * @brief  Abort the current transmission (non-blocking function)
2406 * @param  hqspi QSPI handle
2407 * @retval HAL status
2408 */
HAL_QSPI_Abort_IT(QSPI_HandleTypeDef * hqspi)2409 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2410 {
2411   HAL_StatusTypeDef status = HAL_OK;
2412 
2413   /* Check if the state is in one of the busy states */
2414   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2415   {
2416     /* Process unlocked */
2417     __HAL_UNLOCK(hqspi);
2418 
2419     /* Update QSPI state */
2420     hqspi->State = HAL_QSPI_STATE_ABORT;
2421 
2422     /* Disable all interrupts */
2423     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2424 
2425     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2426     {
2427       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2428       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2429 
2430       /* Abort DMA channel */
2431       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
2432       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
2433       {
2434         /* Change state of QSPI */
2435         hqspi->State = HAL_QSPI_STATE_READY;
2436 
2437         /* Abort Complete callback */
2438 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2439         hqspi->AbortCpltCallback(hqspi);
2440 #else
2441         HAL_QSPI_AbortCpltCallback(hqspi);
2442 #endif
2443       }
2444     }
2445     else
2446     {
2447       if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2448       {
2449         /* Clear interrupt */
2450         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2451 
2452         /* Enable the QSPI Transfer Complete Interrupt */
2453         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2454 
2455         /* Configure QSPI: CR register with Abort request */
2456         SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2457       }
2458       else
2459       {
2460         /* Change state of QSPI */
2461         hqspi->State = HAL_QSPI_STATE_READY;
2462       }
2463     }
2464   }
2465   return status;
2466 }
2467 
2468 /** @brief Set QSPI timeout.
2469   * @param  hqspi QSPI handle.
2470   * @param  Timeout Timeout for the QSPI memory access.
2471   * @retval None
2472   */
HAL_QSPI_SetTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Timeout)2473 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2474 {
2475   hqspi->Timeout = Timeout;
2476 }
2477 
2478 /** @brief Set QSPI Fifo threshold.
2479   * @param  hqspi QSPI handle.
2480   * @param  Threshold Threshold of the Fifo (value between 1 and 16).
2481   * @retval HAL status
2482   */
HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef * hqspi,uint32_t Threshold)2483 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2484 {
2485   HAL_StatusTypeDef status = HAL_OK;
2486 
2487   /* Process locked */
2488   __HAL_LOCK(hqspi);
2489 
2490   if(hqspi->State == HAL_QSPI_STATE_READY)
2491   {
2492     /* Synchronize init structure with new FIFO threshold value */
2493     hqspi->Init.FifoThreshold = Threshold;
2494 
2495     /* Configure QSPI FIFO Threshold */
2496     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2497                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2498   }
2499   else
2500   {
2501     status = HAL_BUSY;
2502   }
2503 
2504   /* Process unlocked */
2505   __HAL_UNLOCK(hqspi);
2506 
2507   /* Return function status */
2508   return status;
2509 }
2510 
2511 /** @brief Get QSPI Fifo threshold.
2512   * @param  hqspi QSPI handle.
2513   * @retval Fifo threshold (value between 1 and 16)
2514   */
HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef * hqspi)2515 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2516 {
2517   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2518 }
2519 
2520 /** @brief  Set FlashID.
2521   * @param  hqspi QSPI handle.
2522   * @param  FlashID Index of the flash memory to be accessed.
2523   *                   This parameter can be a value of @ref QSPI_Flash_Select.
2524   * @note   The FlashID is ignored when dual flash mode is enabled.
2525   * @retval HAL status
2526   */
HAL_QSPI_SetFlashID(QSPI_HandleTypeDef * hqspi,uint32_t FlashID)2527 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2528 {
2529   HAL_StatusTypeDef status = HAL_OK;
2530 
2531   /* Check the parameter */
2532   assert_param(IS_QSPI_FLASH_ID(FlashID));
2533 
2534   /* Process locked */
2535   __HAL_LOCK(hqspi);
2536 
2537   if(hqspi->State == HAL_QSPI_STATE_READY)
2538   {
2539     /* Synchronize init structure with new FlashID value */
2540     hqspi->Init.FlashID = FlashID;
2541 
2542     /* Configure QSPI FlashID */
2543     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2544   }
2545   else
2546   {
2547     status = HAL_BUSY;
2548   }
2549 
2550   /* Process unlocked */
2551   __HAL_UNLOCK(hqspi);
2552 
2553   /* Return function status */
2554   return status;
2555 }
2556 
2557 /**
2558   * @}
2559   */
2560 
2561 /**
2562   * @}
2563   */
2564 
2565 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2566   * @{
2567   */
2568 
2569 /**
2570   * @brief  DMA QSPI receive process complete callback.
2571   * @param  hdma DMA handle
2572   * @retval None
2573   */
QSPI_DMARxCplt(DMA_HandleTypeDef * hdma)2574 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
2575 {
2576   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2577   hqspi->RxXferCount = 0U;
2578 
2579   /* Enable the QSPI transfer complete Interrupt */
2580   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2581 }
2582 
2583 /**
2584   * @brief  DMA QSPI transmit process complete callback.
2585   * @param  hdma DMA handle
2586   * @retval None
2587   */
QSPI_DMATxCplt(DMA_HandleTypeDef * hdma)2588 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
2589 {
2590   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2591   hqspi->TxXferCount = 0U;
2592 
2593   /* Enable the QSPI transfer complete Interrupt */
2594   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2595 }
2596 
2597 /**
2598   * @brief  DMA QSPI receive process half complete callback.
2599   * @param  hdma DMA handle
2600   * @retval None
2601   */
QSPI_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2602 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2603 {
2604   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2605 
2606 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2607   hqspi->RxHalfCpltCallback(hqspi);
2608 #else
2609   HAL_QSPI_RxHalfCpltCallback(hqspi);
2610 #endif
2611 }
2612 
2613 /**
2614   * @brief  DMA QSPI transmit process half complete callback.
2615   * @param  hdma DMA handle
2616   * @retval None
2617   */
QSPI_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2618 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2619 {
2620   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2621 
2622 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2623   hqspi->TxHalfCpltCallback(hqspi);
2624 #else
2625   HAL_QSPI_TxHalfCpltCallback(hqspi);
2626 #endif
2627 }
2628 
2629 /**
2630   * @brief  DMA QSPI communication error callback.
2631   * @param  hdma DMA handle
2632   * @retval None
2633   */
QSPI_DMAError(DMA_HandleTypeDef * hdma)2634 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
2635 {
2636   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2637 
2638   /* if DMA error is FIFO error ignore it */
2639   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2640   {
2641   hqspi->RxXferCount = 0U;
2642   hqspi->TxXferCount = 0U;
2643   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
2644 
2645   /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2646   CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2647 
2648   /* Abort the QSPI */
2649   (void)HAL_QSPI_Abort_IT(hqspi);
2650 
2651   }
2652 }
2653 
2654 /**
2655   * @brief  DMA QSPI abort complete callback.
2656   * @param  hdma DMA handle
2657   * @retval None
2658   */
QSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)2659 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2660 {
2661   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2662 
2663   hqspi->RxXferCount = 0U;
2664   hqspi->TxXferCount = 0U;
2665 
2666   if(hqspi->State == HAL_QSPI_STATE_ABORT)
2667   {
2668     /* DMA Abort called by QSPI abort */
2669     /* Clear interrupt */
2670     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2671 
2672     /* Enable the QSPI Transfer Complete Interrupt */
2673     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2674 
2675     /* Configure QSPI: CR register with Abort request */
2676     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2677   }
2678   else
2679   {
2680     /* DMA Abort called due to a transfer error interrupt */
2681     /* Change state of QSPI */
2682     hqspi->State = HAL_QSPI_STATE_READY;
2683 
2684     /* Error callback */
2685 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2686     hqspi->ErrorCallback(hqspi);
2687 #else
2688     HAL_QSPI_ErrorCallback(hqspi);
2689 #endif
2690   }
2691 }
2692 
2693 /**
2694   * @brief  Wait for a flag state until timeout.
2695   * @param  hqspi QSPI handle
2696   * @param  Flag Flag checked
2697   * @param  State Value of the flag expected
2698   * @param  Tickstart Tick start value
2699   * @param  Timeout Duration of the timeout
2700   * @retval HAL status
2701   */
QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2702 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2703                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2704 {
2705   /* Wait until flag is in expected state */
2706   while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2707   {
2708     /* Check for the Timeout */
2709     if (Timeout != HAL_MAX_DELAY)
2710     {
2711       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2712       {
2713         hqspi->State     = HAL_QSPI_STATE_ERROR;
2714         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2715 
2716         return HAL_ERROR;
2717       }
2718     }
2719   }
2720   return HAL_OK;
2721 }
2722 
2723 /**
2724   * @brief  Wait for a flag state until timeout using CPU cycle.
2725   * @param  hqspi : QSPI handle
2726   * @param  Flag : Flag checked
2727   * @param  State : Value of the flag expected
2728   * @param  Timeout : Duration of the timeout
2729   * @retval HAL status
2730   */
QSPI_WaitFlagStateUntilTimeout_CPUCycle(QSPI_HandleTypeDef * hqspi,uint32_t Flag,FlagStatus State,uint32_t Timeout)2731 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout_CPUCycle(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout)
2732 {
2733   __IO uint32_t count = Timeout * (SystemCoreClock / 16U / 1000U);
2734    do
2735    {
2736      if (count-- == 0U)
2737      {
2738        hqspi->State     = HAL_QSPI_STATE_ERROR;
2739        hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2740        return HAL_TIMEOUT;
2741      }
2742    }
2743    while ((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State);
2744 
2745    return HAL_OK;
2746 }
2747 
2748 /**
2749   * @brief  Configure the communication registers.
2750   * @param  hqspi QSPI handle
2751   * @param  cmd structure that contains the command configuration information
2752   * @param  FunctionalMode functional mode to configured
2753   *           This parameter can be one of the following values:
2754   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2755   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2756   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2757   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2758   * @retval None
2759   */
QSPI_Config(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t FunctionalMode)2760 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2761 {
2762   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2763 
2764   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2765   {
2766     /* Configure QSPI: DLR register with the number of data to read or write */
2767     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2768   }
2769 
2770   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2771   {
2772     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2773     {
2774       /* Configure QSPI: ABR register with alternate bytes value */
2775       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2776 
2777       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2778       {
2779         /*---- Command with instruction, address and alternate bytes ----*/
2780         /* Configure QSPI: CCR register with all communications parameters */
2781         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2782                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2783                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2784                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2785                                          cmd->Instruction | FunctionalMode));
2786 
2787         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2788         {
2789           /* Configure QSPI: AR register with address value */
2790           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2791         }
2792       }
2793       else
2794       {
2795         /*---- Command with instruction and alternate bytes ----*/
2796         /* Configure QSPI: CCR register with all communications parameters */
2797         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2798                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2799                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2800                                          cmd->AddressMode | cmd->InstructionMode |
2801                                          cmd->Instruction | FunctionalMode));
2802       }
2803     }
2804     else
2805     {
2806       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2807       {
2808         /*---- Command with instruction and address ----*/
2809         /* Configure QSPI: CCR register with all communications parameters */
2810         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2811                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2812                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2813                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2814 
2815         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2816         {
2817           /* Configure QSPI: AR register with address value */
2818           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2819         }
2820       }
2821       else
2822       {
2823         /*---- Command with only instruction ----*/
2824         /* Configure QSPI: CCR register with all communications parameters */
2825         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2826                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2827                                          cmd->AlternateByteMode | cmd->AddressMode |
2828                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2829       }
2830     }
2831   }
2832   else
2833   {
2834     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2835     {
2836       /* Configure QSPI: ABR register with alternate bytes value */
2837       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2838 
2839       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2840       {
2841         /*---- Command with address and alternate bytes ----*/
2842         /* Configure QSPI: CCR register with all communications parameters */
2843         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2844                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2845                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2846                                          cmd->AddressSize | cmd->AddressMode |
2847                                          cmd->InstructionMode | FunctionalMode));
2848 
2849         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2850         {
2851           /* Configure QSPI: AR register with address value */
2852           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2853         }
2854       }
2855       else
2856       {
2857         /*---- Command with only alternate bytes ----*/
2858         /* Configure QSPI: CCR register with all communications parameters */
2859         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2860                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2861                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2862                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2863       }
2864     }
2865     else
2866     {
2867       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2868       {
2869         /*---- Command with only address ----*/
2870         /* Configure QSPI: CCR register with all communications parameters */
2871         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2872                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2873                                          cmd->AlternateByteMode | cmd->AddressSize |
2874                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2875 
2876         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2877         {
2878           /* Configure QSPI: AR register with address value */
2879           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2880         }
2881       }
2882       else
2883       {
2884         /*---- Command with only data phase ----*/
2885         if (cmd->DataMode != QSPI_DATA_NONE)
2886         {
2887           /* Configure QSPI: CCR register with all communications parameters */
2888           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2889                                            cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2890                                            cmd->AlternateByteMode | cmd->AddressMode |
2891                                            cmd->InstructionMode | FunctionalMode));
2892         }
2893       }
2894     }
2895   }
2896 }
2897 
2898 /**
2899   * @}
2900   */
2901 
2902 /**
2903   * @}
2904   */
2905 
2906 #endif /* HAL_QSPI_MODULE_ENABLED */
2907 /**
2908   * @}
2909   */
2910 
2911 /**
2912   * @}
2913   */
2914 
2915 #endif /* defined(QUADSPI) */
2916