1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_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) 2017 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 "stm32f7xx_hal.h"
212 
213 #if defined(QUADSPI)
214 
215 /** @addtogroup STM32F7xx_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 #if  defined(QSPI1_V1_0)
576       /* Clear Busy bit */
577       HAL_QSPI_Abort_IT(hqspi);
578 #endif
579 
580       /* Change state of QSPI */
581       hqspi->State = HAL_QSPI_STATE_READY;
582 
583       /* TX Complete callback */
584 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
585       hqspi->TxCpltCallback(hqspi);
586 #else
587       HAL_QSPI_TxCpltCallback(hqspi);
588 #endif
589     }
590     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
591     {
592       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
593       {
594         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
595         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
596 
597         /* Disable the DMA channel */
598         __HAL_DMA_DISABLE(hqspi->hdma);
599       }
600       else
601       {
602         data_reg = &hqspi->Instance->DR;
603         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
604         {
605           if (hqspi->RxXferCount > 0U)
606           {
607             /* Read the last data received in the FIFO until it is empty */
608             *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
609             hqspi->pRxBuffPtr++;
610             hqspi->RxXferCount--;
611           }
612           else
613           {
614             /* All data have been received for the transfer */
615             break;
616           }
617         }
618       }
619 
620 #if  defined(QSPI1_V1_0)
621       /* Workaround - Extra data written in the FIFO at the end of a read transfer */
622       HAL_QSPI_Abort_IT(hqspi);
623 #endif
624 
625       /* Change state of QSPI */
626       hqspi->State = HAL_QSPI_STATE_READY;
627 
628       /* RX Complete callback */
629 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
630       hqspi->RxCpltCallback(hqspi);
631 #else
632       HAL_QSPI_RxCpltCallback(hqspi);
633 #endif
634     }
635     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
636     {
637       /* Change state of QSPI */
638       hqspi->State = HAL_QSPI_STATE_READY;
639 
640       /* Command Complete callback */
641 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
642       hqspi->CmdCpltCallback(hqspi);
643 #else
644       HAL_QSPI_CmdCpltCallback(hqspi);
645 #endif
646     }
647     else if(hqspi->State == HAL_QSPI_STATE_ABORT)
648     {
649       /* Reset functional mode configuration to indirect write mode by default */
650       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
651 
652       /* Change state of QSPI */
653       hqspi->State = HAL_QSPI_STATE_READY;
654 
655       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
656       {
657         /* Abort called by the user */
658 
659         /* Abort Complete callback */
660 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
661         hqspi->AbortCpltCallback(hqspi);
662 #else
663         HAL_QSPI_AbortCpltCallback(hqspi);
664 #endif
665       }
666       else
667       {
668         /* Abort due to an error (eg :  DMA error) */
669 
670         /* Error callback */
671 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
672         hqspi->ErrorCallback(hqspi);
673 #else
674         HAL_QSPI_ErrorCallback(hqspi);
675 #endif
676       }
677     }
678     else
679     {
680      /* Nothing to do */
681     }
682   }
683 
684   /* QSPI Status Match interrupt occurred ------------------------------------*/
685   else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
686   {
687     /* Clear interrupt */
688     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
689 
690     /* Check if the automatic poll mode stop is activated */
691     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
692     {
693       /* Disable the QSPI Transfer Error and Status Match Interrupts */
694       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
695 
696       /* Change state of QSPI */
697       hqspi->State = HAL_QSPI_STATE_READY;
698     }
699 
700     /* Status match callback */
701 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
702     hqspi->StatusMatchCallback(hqspi);
703 #else
704     HAL_QSPI_StatusMatchCallback(hqspi);
705 #endif
706   }
707 
708   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
709   else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
710   {
711     /* Clear interrupt */
712     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
713 
714     /* Disable all the QSPI Interrupts */
715     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
716 
717     /* Set error code */
718     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
719 
720     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
721     {
722       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
723       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
724 
725       /* Disable the DMA channel */
726       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
727       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
728       {
729         /* Set error code to DMA */
730         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
731 
732         /* Change state of QSPI */
733         hqspi->State = HAL_QSPI_STATE_READY;
734 
735         /* Error callback */
736 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
737         hqspi->ErrorCallback(hqspi);
738 #else
739         HAL_QSPI_ErrorCallback(hqspi);
740 #endif
741       }
742     }
743     else
744     {
745       /* Change state of QSPI */
746       hqspi->State = HAL_QSPI_STATE_READY;
747 
748       /* Error callback */
749 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
750       hqspi->ErrorCallback(hqspi);
751 #else
752       HAL_QSPI_ErrorCallback(hqspi);
753 #endif
754     }
755   }
756 
757   /* QSPI Timeout interrupt occurred -----------------------------------------*/
758   else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
759   {
760     /* Clear interrupt */
761     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
762 
763     /* Timeout callback */
764 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
765     hqspi->TimeOutCallback(hqspi);
766 #else
767     HAL_QSPI_TimeOutCallback(hqspi);
768 #endif
769   }
770 
771    else
772   {
773    /* Nothing to do */
774   }
775 }
776 
777 /**
778   * @brief Set the command configuration.
779   * @param hqspi QSPI handle
780   * @param cmd : structure that contains the command configuration information
781   * @param Timeout Timeout duration
782   * @note   This function is used only in Indirect Read or Write Modes
783   * @retval HAL status
784   */
HAL_QSPI_Command(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t Timeout)785 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
786 {
787   HAL_StatusTypeDef status;
788   uint32_t tickstart = HAL_GetTick();
789 
790   /* Check the parameters */
791   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
792   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
793   {
794     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
795   }
796 
797   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
798   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
799   {
800     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
801   }
802 
803   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
804   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
805   {
806     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
807   }
808 
809   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
810   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
811 
812   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
813   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
814   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
815 
816   /* Process locked */
817   __HAL_LOCK(hqspi);
818 
819   if(hqspi->State == HAL_QSPI_STATE_READY)
820   {
821     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
822 
823     /* Update QSPI state */
824     hqspi->State = HAL_QSPI_STATE_BUSY;
825 
826     /* Wait till BUSY flag reset */
827     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
828 
829     if (status == HAL_OK)
830     {
831       /* Call the configuration function */
832       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
833 
834       if (cmd->DataMode == QSPI_DATA_NONE)
835       {
836         /* When there is no data phase, the transfer start as soon as the configuration is done
837         so wait until TC flag is set to go back in idle state */
838         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
839 
840         if (status == HAL_OK)
841         {
842           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
843 
844           /* Update QSPI state */
845           hqspi->State = HAL_QSPI_STATE_READY;
846         }
847       }
848       else
849       {
850         /* Update QSPI state */
851         hqspi->State = HAL_QSPI_STATE_READY;
852       }
853     }
854   }
855   else
856   {
857     status = HAL_BUSY;
858   }
859 
860   /* Process unlocked */
861   __HAL_UNLOCK(hqspi);
862 
863   /* Return function status */
864   return status;
865 }
866 
867 /**
868   * @brief Set the command configuration in interrupt mode.
869   * @param hqspi QSPI handle
870   * @param cmd structure that contains the command configuration information
871   * @note   This function is used only in Indirect Read or Write Modes
872   * @retval HAL status
873   */
HAL_QSPI_Command_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd)874 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
875 {
876   HAL_StatusTypeDef status;
877 
878   /* Check the parameters */
879   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
880   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
881   {
882     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
883   }
884 
885   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
886   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
887   {
888     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
889   }
890 
891   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
892   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
893   {
894     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
895   }
896 
897   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
898   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
899 
900   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
901   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
902   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
903 
904   /* Process locked */
905   __HAL_LOCK(hqspi);
906 
907   if(hqspi->State == HAL_QSPI_STATE_READY)
908   {
909     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
910 
911     /* Update QSPI state */
912     hqspi->State = HAL_QSPI_STATE_BUSY;
913 
914     /* Wait till BUSY flag reset */
915     status = QSPI_WaitFlagStateUntilTimeout_CPUCycle(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
916 
917     if (status == HAL_OK)
918     {
919       if (cmd->DataMode == QSPI_DATA_NONE)
920       {
921         /* Clear interrupt */
922         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
923       }
924 
925       /* Call the configuration function */
926       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
927 
928       if (cmd->DataMode == QSPI_DATA_NONE)
929       {
930         /* When there is no data phase, the transfer start as soon as the configuration is done
931         so activate TC and TE interrupts */
932         /* Process unlocked */
933         __HAL_UNLOCK(hqspi);
934 
935         /* Enable the QSPI Transfer Error Interrupt */
936         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
937       }
938       else
939       {
940         /* Update QSPI state */
941         hqspi->State = HAL_QSPI_STATE_READY;
942 
943         /* Process unlocked */
944         __HAL_UNLOCK(hqspi);
945       }
946     }
947     else
948     {
949       /* Process unlocked */
950       __HAL_UNLOCK(hqspi);
951     }
952   }
953   else
954   {
955     status = HAL_BUSY;
956 
957     /* Process unlocked */
958     __HAL_UNLOCK(hqspi);
959   }
960 
961   /* Return function status */
962   return status;
963 }
964 
965 /**
966   * @brief Transmit an amount of data in blocking mode.
967   * @param hqspi QSPI handle
968   * @param pData pointer to data buffer
969   * @param Timeout Timeout duration
970   * @note   This function is used only in Indirect Write Mode
971   * @retval HAL status
972   */
HAL_QSPI_Transmit(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)973 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
974 {
975   HAL_StatusTypeDef status = HAL_OK;
976   uint32_t tickstart = HAL_GetTick();
977   __IO uint32_t *data_reg = &hqspi->Instance->DR;
978 
979   /* Process locked */
980   __HAL_LOCK(hqspi);
981 
982   if(hqspi->State == HAL_QSPI_STATE_READY)
983   {
984     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
985 
986     if(pData != NULL )
987     {
988       /* Update state */
989       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
990 
991       /* Configure counters and size of the handle */
992       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
993       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
994       hqspi->pTxBuffPtr = pData;
995 
996       /* Configure QSPI: CCR register with functional as indirect write */
997       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
998 
999       while(hqspi->TxXferCount > 0U)
1000       {
1001         /* Wait until FT flag is set to send data */
1002         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
1003 
1004         if (status != HAL_OK)
1005         {
1006           break;
1007         }
1008 
1009         *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
1010         hqspi->pTxBuffPtr++;
1011         hqspi->TxXferCount--;
1012       }
1013 
1014       if (status == HAL_OK)
1015       {
1016         /* Wait until TC flag is set to go back in idle state */
1017         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1018 
1019         if (status == HAL_OK)
1020         {
1021           /* Clear Transfer Complete bit */
1022           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1023 
1024 #if  defined(QSPI1_V1_0)
1025           /* Clear Busy bit */
1026           status = HAL_QSPI_Abort(hqspi);
1027 #endif
1028         }
1029       }
1030 
1031       /* Update QSPI state */
1032       hqspi->State = HAL_QSPI_STATE_READY;
1033     }
1034     else
1035     {
1036       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1037       status = HAL_ERROR;
1038     }
1039   }
1040   else
1041   {
1042     status = HAL_BUSY;
1043   }
1044 
1045   /* Process unlocked */
1046   __HAL_UNLOCK(hqspi);
1047 
1048   return status;
1049 }
1050 
1051 
1052 /**
1053   * @brief Receive an amount of data in blocking mode.
1054   * @param hqspi QSPI handle
1055   * @param pData pointer to data buffer
1056   * @param Timeout Timeout duration
1057   * @note   This function is used only in Indirect Read Mode
1058   * @retval HAL status
1059   */
HAL_QSPI_Receive(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)1060 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1061 {
1062   HAL_StatusTypeDef status = HAL_OK;
1063   uint32_t tickstart = HAL_GetTick();
1064   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1065   __IO uint32_t *data_reg = &hqspi->Instance->DR;
1066 
1067   /* Process locked */
1068   __HAL_LOCK(hqspi);
1069 
1070   if(hqspi->State == HAL_QSPI_STATE_READY)
1071   {
1072     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1073 
1074     if(pData != NULL )
1075     {
1076       /* Update state */
1077       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1078 
1079       /* Configure counters and size of the handle */
1080       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1081       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1082       hqspi->pRxBuffPtr = pData;
1083 
1084       /* Configure QSPI: CCR register with functional as indirect read */
1085       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1086 
1087       /* Start the transfer by re-writing the address in AR register */
1088       WRITE_REG(hqspi->Instance->AR, addr_reg);
1089 
1090       while(hqspi->RxXferCount > 0U)
1091       {
1092         /* Wait until FT or TC flag is set to read received data */
1093         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1094 
1095         if  (status != HAL_OK)
1096         {
1097           break;
1098         }
1099 
1100         *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
1101         hqspi->pRxBuffPtr++;
1102         hqspi->RxXferCount--;
1103       }
1104 
1105       if (status == HAL_OK)
1106       {
1107         /* Wait until TC flag is set to go back in idle state */
1108         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1109 
1110         if  (status == HAL_OK)
1111         {
1112           /* Clear Transfer Complete bit */
1113           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1114 
1115 #if  defined(QSPI1_V1_0)
1116           /* Workaround - Extra data written in the FIFO at the end of a read transfer */
1117           status = HAL_QSPI_Abort(hqspi);
1118 #endif
1119         }
1120       }
1121 
1122       /* Update QSPI state */
1123       hqspi->State = HAL_QSPI_STATE_READY;
1124     }
1125     else
1126     {
1127       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1128       status = HAL_ERROR;
1129     }
1130   }
1131   else
1132   {
1133     status = HAL_BUSY;
1134   }
1135 
1136   /* Process unlocked */
1137   __HAL_UNLOCK(hqspi);
1138 
1139   return status;
1140 }
1141 
1142 /**
1143   * @brief  Send an amount of data in non-blocking mode with interrupt.
1144   * @param  hqspi QSPI handle
1145   * @param  pData pointer to data buffer
1146   * @note   This function is used only in Indirect Write Mode
1147   * @retval HAL status
1148   */
HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1149 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1150 {
1151   HAL_StatusTypeDef status = HAL_OK;
1152 
1153   /* Process locked */
1154   __HAL_LOCK(hqspi);
1155 
1156   if(hqspi->State == HAL_QSPI_STATE_READY)
1157   {
1158     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1159 
1160     if(pData != NULL )
1161     {
1162       /* Update state */
1163       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1164 
1165       /* Configure counters and size of the handle */
1166       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1167       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1168       hqspi->pTxBuffPtr = pData;
1169 
1170       /* Clear interrupt */
1171       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1172 
1173       /* Configure QSPI: CCR register with functional as indirect write */
1174       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1175 
1176       /* Process unlocked */
1177       __HAL_UNLOCK(hqspi);
1178 
1179       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1180       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1181     }
1182     else
1183     {
1184       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1185       status = HAL_ERROR;
1186 
1187       /* Process unlocked */
1188       __HAL_UNLOCK(hqspi);
1189     }
1190   }
1191   else
1192   {
1193     status = HAL_BUSY;
1194 
1195     /* Process unlocked */
1196     __HAL_UNLOCK(hqspi);
1197   }
1198 
1199   return status;
1200 }
1201 
1202 /**
1203   * @brief  Receive an amount of data in non-blocking mode with interrupt.
1204   * @param  hqspi QSPI handle
1205   * @param  pData pointer to data buffer
1206   * @note   This function is used only in Indirect Read Mode
1207   * @retval HAL status
1208   */
HAL_QSPI_Receive_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1209 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1210 {
1211   HAL_StatusTypeDef status = HAL_OK;
1212   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1213 
1214   /* Process locked */
1215   __HAL_LOCK(hqspi);
1216 
1217   if(hqspi->State == HAL_QSPI_STATE_READY)
1218   {
1219     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1220 
1221     if(pData != NULL )
1222     {
1223       /* Update state */
1224       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1225 
1226       /* Configure counters and size of the handle */
1227       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1228       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1229       hqspi->pRxBuffPtr = pData;
1230 
1231       /* Clear interrupt */
1232       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1233 
1234       /* Configure QSPI: CCR register with functional as indirect read */
1235       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1236 
1237       /* Start the transfer by re-writing the address in AR register */
1238       WRITE_REG(hqspi->Instance->AR, addr_reg);
1239 
1240       /* Process unlocked */
1241       __HAL_UNLOCK(hqspi);
1242 
1243       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1244       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1245     }
1246     else
1247     {
1248       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1249       status = HAL_ERROR;
1250 
1251       /* Process unlocked */
1252       __HAL_UNLOCK(hqspi);
1253     }
1254   }
1255   else
1256   {
1257     status = HAL_BUSY;
1258 
1259     /* Process unlocked */
1260     __HAL_UNLOCK(hqspi);
1261   }
1262 
1263   return status;
1264 }
1265 
1266 /**
1267   * @brief  Send an amount of data in non-blocking mode with DMA.
1268   * @param  hqspi QSPI handle
1269   * @param  pData pointer to data buffer
1270   * @note   This function is used only in Indirect Write Mode
1271   * @note   If DMA peripheral access is configured as halfword, the number
1272   *         of data and the fifo threshold should be aligned on halfword
1273   * @note   If DMA peripheral access is configured as word, the number
1274   *         of data and the fifo threshold should be aligned on word
1275   * @retval HAL status
1276   */
HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1277 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1278 {
1279   HAL_StatusTypeDef status = HAL_OK;
1280   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1281 
1282   /* Process locked */
1283   __HAL_LOCK(hqspi);
1284 
1285   if(hqspi->State == HAL_QSPI_STATE_READY)
1286   {
1287     /* Clear the error code */
1288     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1289 
1290     if(pData != NULL )
1291     {
1292       /* Configure counters of the handle */
1293       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1294       {
1295         hqspi->TxXferCount = data_size;
1296       }
1297       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1298       {
1299         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1300         {
1301           /* The number of data or the fifo threshold is not aligned on halfword
1302           => no transfer possible with DMA peripheral access configured as halfword */
1303           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1304           status = HAL_ERROR;
1305 
1306           /* Process unlocked */
1307           __HAL_UNLOCK(hqspi);
1308         }
1309         else
1310         {
1311           hqspi->TxXferCount = (data_size >> 1U);
1312         }
1313       }
1314       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1315       {
1316         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1317         {
1318           /* The number of data or the fifo threshold is not aligned on word
1319           => no transfer possible with DMA peripheral access configured as word */
1320           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1321           status = HAL_ERROR;
1322 
1323           /* Process unlocked */
1324           __HAL_UNLOCK(hqspi);
1325         }
1326         else
1327         {
1328           hqspi->TxXferCount = (data_size >> 2U);
1329         }
1330       }
1331       else
1332       {
1333         /* Nothing to do */
1334       }
1335 
1336       if (status == HAL_OK)
1337       {
1338         /* Update state */
1339         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1340 
1341         /* Clear interrupt */
1342         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1343 
1344         /* Configure size and pointer of the handle */
1345         hqspi->TxXferSize = hqspi->TxXferCount;
1346         hqspi->pTxBuffPtr = pData;
1347 
1348         /* Configure QSPI: CCR register with functional mode as indirect write */
1349         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1350 
1351         /* Set the QSPI DMA transfer complete callback */
1352         hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
1353 
1354         /* Set the QSPI DMA Half transfer complete callback */
1355         hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
1356 
1357         /* Set the DMA error callback */
1358         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1359 
1360         /* Clear the DMA abort callback */
1361         hqspi->hdma->XferAbortCallback = NULL;
1362 
1363         /* Configure the direction of the DMA */
1364         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1365         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1366 
1367         /* Enable the QSPI transmit DMA Channel */
1368         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
1369         {
1370           /* Process unlocked */
1371           __HAL_UNLOCK(hqspi);
1372 
1373           /* Enable the QSPI transfer error Interrupt */
1374           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1375 
1376           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1377           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1378         }
1379         else
1380         {
1381           status = HAL_ERROR;
1382           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1383           hqspi->State = HAL_QSPI_STATE_READY;
1384 
1385           /* Process unlocked */
1386           __HAL_UNLOCK(hqspi);
1387         }
1388      }
1389     }
1390     else
1391     {
1392       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1393       status = HAL_ERROR;
1394 
1395       /* Process unlocked */
1396       __HAL_UNLOCK(hqspi);
1397     }
1398   }
1399   else
1400   {
1401     status = HAL_BUSY;
1402 
1403     /* Process unlocked */
1404     __HAL_UNLOCK(hqspi);
1405   }
1406 
1407   return status;
1408 }
1409 
1410 /**
1411   * @brief  Receive an amount of data in non-blocking mode with DMA.
1412   * @param  hqspi QSPI handle
1413   * @param  pData pointer to data buffer.
1414   * @note   This function is used only in Indirect Read Mode
1415   * @note   If DMA peripheral access is configured as halfword, the number
1416   *         of data and the fifo threshold should be aligned on halfword
1417   * @note   If DMA peripheral access is configured as word, the number
1418   *         of data and the fifo threshold should be aligned on word
1419   * @retval HAL status
1420   */
HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1421 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1422 {
1423   HAL_StatusTypeDef status = HAL_OK;
1424   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1425   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1426 
1427   /* Process locked */
1428   __HAL_LOCK(hqspi);
1429 
1430   if(hqspi->State == HAL_QSPI_STATE_READY)
1431   {
1432     /* Clear the error code */
1433     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1434 
1435     if(pData != NULL )
1436     {
1437       /* Configure counters of the handle */
1438       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1439       {
1440         hqspi->RxXferCount = data_size;
1441       }
1442       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1443       {
1444         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1445         {
1446           /* The number of data or the fifo threshold is not aligned on halfword
1447              => no transfer possible with DMA peripheral access configured as halfword */
1448           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1449           status = HAL_ERROR;
1450 
1451           /* Process unlocked */
1452           __HAL_UNLOCK(hqspi);
1453         }
1454         else
1455         {
1456           hqspi->RxXferCount = (data_size >> 1U);
1457         }
1458       }
1459       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1460       {
1461         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1462         {
1463           /* The number of data or the fifo threshold is not aligned on word
1464              => no transfer possible with DMA peripheral access configured as word */
1465           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1466           status = HAL_ERROR;
1467 
1468           /* Process unlocked */
1469           __HAL_UNLOCK(hqspi);
1470         }
1471         else
1472         {
1473           hqspi->RxXferCount = (data_size >> 2U);
1474         }
1475       }
1476       else
1477       {
1478         /* Nothing to do */
1479       }
1480 
1481       if (status == HAL_OK)
1482       {
1483         /* Update state */
1484         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1485 
1486         /* Clear interrupt */
1487         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1488 
1489         /* Configure size and pointer of the handle */
1490         hqspi->RxXferSize = hqspi->RxXferCount;
1491         hqspi->pRxBuffPtr = pData;
1492 
1493         /* Set the QSPI DMA transfer complete callback */
1494         hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
1495 
1496         /* Set the QSPI DMA Half transfer complete callback */
1497         hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
1498 
1499         /* Set the DMA error callback */
1500         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1501 
1502         /* Clear the DMA abort callback */
1503         hqspi->hdma->XferAbortCallback = NULL;
1504 
1505         /* Configure the direction of the DMA */
1506         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1507         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1508 
1509         /* Enable the DMA Channel */
1510         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
1511         {
1512           /* Configure QSPI: CCR register with functional as indirect read */
1513           MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1514 
1515           /* Start the transfer by re-writing the address in AR register */
1516           WRITE_REG(hqspi->Instance->AR, addr_reg);
1517 
1518           /* Process unlocked */
1519           __HAL_UNLOCK(hqspi);
1520 
1521           /* Enable the QSPI transfer error Interrupt */
1522           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1523 
1524           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1525           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1526         }
1527         else
1528         {
1529           status = HAL_ERROR;
1530           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1531           hqspi->State = HAL_QSPI_STATE_READY;
1532 
1533           /* Process unlocked */
1534           __HAL_UNLOCK(hqspi);
1535         }
1536       }
1537     }
1538     else
1539     {
1540       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1541       status = HAL_ERROR;
1542 
1543       /* Process unlocked */
1544       __HAL_UNLOCK(hqspi);
1545     }
1546   }
1547   else
1548   {
1549     status = HAL_BUSY;
1550 
1551     /* Process unlocked */
1552     __HAL_UNLOCK(hqspi);
1553   }
1554 
1555   return status;
1556 }
1557 
1558 /**
1559   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode.
1560   * @param  hqspi QSPI handle
1561   * @param  cmd structure that contains the command configuration information.
1562   * @param  cfg structure that contains the polling configuration information.
1563   * @param  Timeout Timeout duration
1564   * @note   This function is used only in Automatic Polling Mode
1565   * @retval HAL status
1566   */
HAL_QSPI_AutoPolling(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg,uint32_t Timeout)1567 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1568 {
1569   HAL_StatusTypeDef status;
1570   uint32_t tickstart = HAL_GetTick();
1571 
1572   /* Check the parameters */
1573   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1574   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1575   {
1576     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1577   }
1578 
1579   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1580   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1581   {
1582     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1583   }
1584 
1585   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1586   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1587   {
1588     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1589   }
1590 
1591   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1592   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1593 
1594   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1595   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1596   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1597 
1598   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1599   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1600   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1601 
1602   /* Process locked */
1603   __HAL_LOCK(hqspi);
1604 
1605   if(hqspi->State == HAL_QSPI_STATE_READY)
1606   {
1607     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1608 
1609     /* Update state */
1610     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1611 
1612     /* Wait till BUSY flag reset */
1613     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1614 
1615     if (status == HAL_OK)
1616     {
1617       /* Configure QSPI: PSMAR register with the status match value */
1618       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1619 
1620       /* Configure QSPI: PSMKR register with the status mask value */
1621       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1622 
1623       /* Configure QSPI: PIR register with the interval value */
1624       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1625 
1626       /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1627       (otherwise there will be an infinite loop in blocking mode) */
1628       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1629                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1630 
1631       /* Call the configuration function */
1632       cmd->NbData = cfg->StatusBytesSize;
1633       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1634 
1635       /* Wait until SM flag is set to go back in idle state */
1636       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1637 
1638       if (status == HAL_OK)
1639       {
1640         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1641 
1642         /* Update state */
1643         hqspi->State = HAL_QSPI_STATE_READY;
1644       }
1645     }
1646   }
1647   else
1648   {
1649     status = HAL_BUSY;
1650   }
1651 
1652   /* Process unlocked */
1653   __HAL_UNLOCK(hqspi);
1654 
1655   /* Return function status */
1656   return status;
1657 }
1658 
1659 /**
1660   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode.
1661   * @param  hqspi QSPI handle
1662   * @param  cmd structure that contains the command configuration information.
1663   * @param  cfg structure that contains the polling configuration information.
1664   * @note   This function is used only in Automatic Polling Mode
1665   * @retval HAL status
1666   */
HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg)1667 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1668 {
1669   HAL_StatusTypeDef status;
1670 
1671   /* Check the parameters */
1672   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1673   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1674   {
1675     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1676   }
1677 
1678   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1679   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1680   {
1681     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1682   }
1683 
1684   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1685   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1686   {
1687     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1688   }
1689 
1690   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1691   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1692 
1693   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1694   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1695   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1696 
1697   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1698   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1699   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1700   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1701 
1702   /* Process locked */
1703   __HAL_LOCK(hqspi);
1704 
1705   if(hqspi->State == HAL_QSPI_STATE_READY)
1706   {
1707     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1708 
1709     /* Update state */
1710     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1711 
1712     /* Wait till BUSY flag reset */
1713     status = QSPI_WaitFlagStateUntilTimeout_CPUCycle(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
1714 
1715     if (status == HAL_OK)
1716     {
1717       /* Configure QSPI: PSMAR register with the status match value */
1718       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1719 
1720       /* Configure QSPI: PSMKR register with the status mask value */
1721       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1722 
1723       /* Configure QSPI: PIR register with the interval value */
1724       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1725 
1726       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1727       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1728                (cfg->MatchMode | cfg->AutomaticStop));
1729 
1730       /* Clear interrupt */
1731       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1732 
1733       /* Call the configuration function */
1734       cmd->NbData = cfg->StatusBytesSize;
1735       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1736 
1737       /* Process unlocked */
1738       __HAL_UNLOCK(hqspi);
1739 
1740       /* Enable the QSPI Transfer Error and status match Interrupt */
1741       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1742 
1743     }
1744     else
1745     {
1746       /* Process unlocked */
1747       __HAL_UNLOCK(hqspi);
1748     }
1749   }
1750   else
1751   {
1752     status = HAL_BUSY;
1753 
1754     /* Process unlocked */
1755     __HAL_UNLOCK(hqspi);
1756   }
1757 
1758   /* Return function status */
1759   return status;
1760 }
1761 
1762 /**
1763   * @brief  Configure the Memory Mapped mode.
1764   * @param  hqspi QSPI handle
1765   * @param  cmd structure that contains the command configuration information.
1766   * @param  cfg structure that contains the memory mapped configuration information.
1767   * @note   This function is used only in Memory mapped Mode
1768   * @retval HAL status
1769   */
HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_MemoryMappedTypeDef * cfg)1770 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1771 {
1772   HAL_StatusTypeDef status;
1773   uint32_t tickstart = HAL_GetTick();
1774 
1775   /* Check the parameters */
1776   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1777   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1778   {
1779   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1780   }
1781 
1782   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1783   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1784   {
1785     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1786   }
1787 
1788   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1789   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1790   {
1791     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1792   }
1793 
1794   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1795   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1796 
1797   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1798   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1799   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1800 
1801   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1802 
1803   /* Process locked */
1804   __HAL_LOCK(hqspi);
1805 
1806   if(hqspi->State == HAL_QSPI_STATE_READY)
1807   {
1808     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1809 
1810     /* Update state */
1811     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1812 
1813     /* Wait till BUSY flag reset */
1814     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1815 
1816     if (status == HAL_OK)
1817     {
1818       /* Configure QSPI: CR register with timeout counter enable */
1819     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1820 
1821     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1822       {
1823         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1824 
1825         /* Configure QSPI: LPTR register with the low-power timeout value */
1826         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1827 
1828         /* Clear interrupt */
1829         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1830 
1831         /* Enable the QSPI TimeOut Interrupt */
1832         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1833       }
1834 
1835       /* Call the configuration function */
1836       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1837     }
1838   }
1839   else
1840   {
1841     status = HAL_BUSY;
1842   }
1843 
1844   /* Process unlocked */
1845   __HAL_UNLOCK(hqspi);
1846 
1847   /* Return function status */
1848   return status;
1849 }
1850 
1851 /**
1852   * @brief  Transfer Error callback.
1853   * @param  hqspi QSPI handle
1854   * @retval None
1855   */
HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef * hqspi)1856 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1857 {
1858   /* Prevent unused argument(s) compilation warning */
1859   UNUSED(hqspi);
1860 
1861   /* NOTE : This function should not be modified, when the callback is needed,
1862             the HAL_QSPI_ErrorCallback could be implemented in the user file
1863    */
1864 }
1865 
1866 /**
1867   * @brief  Abort completed callback.
1868   * @param  hqspi QSPI handle
1869   * @retval None
1870   */
HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef * hqspi)1871 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1872 {
1873   /* Prevent unused argument(s) compilation warning */
1874   UNUSED(hqspi);
1875 
1876   /* NOTE: This function should not be modified, when the callback is needed,
1877            the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1878    */
1879 }
1880 
1881 /**
1882   * @brief  Command completed callback.
1883   * @param  hqspi QSPI handle
1884   * @retval None
1885   */
HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef * hqspi)1886 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1887 {
1888   /* Prevent unused argument(s) compilation warning */
1889   UNUSED(hqspi);
1890 
1891   /* NOTE: This function should not be modified, when the callback is needed,
1892            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1893    */
1894 }
1895 
1896 /**
1897   * @brief  Rx Transfer completed callback.
1898   * @param  hqspi QSPI handle
1899   * @retval None
1900   */
HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef * hqspi)1901 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1902 {
1903   /* Prevent unused argument(s) compilation warning */
1904   UNUSED(hqspi);
1905 
1906   /* NOTE: This function should not be modified, when the callback is needed,
1907            the HAL_QSPI_RxCpltCallback could be implemented in the user file
1908    */
1909 }
1910 
1911 /**
1912   * @brief  Tx Transfer completed callback.
1913   * @param  hqspi QSPI handle
1914   * @retval None
1915   */
HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef * hqspi)1916 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1917 {
1918   /* Prevent unused argument(s) compilation warning */
1919   UNUSED(hqspi);
1920 
1921   /* NOTE: This function should not be modified, when the callback is needed,
1922            the HAL_QSPI_TxCpltCallback could be implemented in the user file
1923    */
1924 }
1925 
1926 /**
1927   * @brief  Rx Half Transfer completed callback.
1928   * @param  hqspi QSPI handle
1929   * @retval None
1930   */
HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)1931 __weak void HAL_QSPI_RxHalfCpltCallback(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_RxHalfCpltCallback could be implemented in the user file
1938    */
1939 }
1940 
1941 /**
1942   * @brief  Tx Half Transfer completed callback.
1943   * @param  hqspi QSPI handle
1944   * @retval None
1945   */
HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)1946 __weak void HAL_QSPI_TxHalfCpltCallback(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_TxHalfCpltCallback could be implemented in the user file
1953    */
1954 }
1955 
1956 /**
1957   * @brief  FIFO Threshold callback.
1958   * @param  hqspi QSPI handle
1959   * @retval None
1960   */
HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef * hqspi)1961 __weak void HAL_QSPI_FifoThresholdCallback(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_FIFOThresholdCallback could be implemented in the user file
1968    */
1969 }
1970 
1971 /**
1972   * @brief  Status Match callback.
1973   * @param  hqspi QSPI handle
1974   * @retval None
1975   */
HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef * hqspi)1976 __weak void HAL_QSPI_StatusMatchCallback(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_StatusMatchCallback could be implemented in the user file
1983    */
1984 }
1985 
1986 /**
1987   * @brief  Timeout callback.
1988   * @param  hqspi QSPI handle
1989   * @retval None
1990   */
HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef * hqspi)1991 __weak void HAL_QSPI_TimeOutCallback(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_TimeOutCallback could be implemented in the user file
1998    */
1999 }
2000 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2001 /**
2002   * @brief  Register a User QSPI Callback
2003   *         To be used instead of the weak (surcharged) predefined callback
2004   * @param hqspi QSPI handle
2005   * @param CallbackId ID of the callback to be registered
2006   *        This parameter can be one of the following values:
2007   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
2008   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
2009   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2010   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
2011   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
2012   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
2013   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
2014   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
2015   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
2016   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
2017   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
2018   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
2019   * @param pCallback pointer to the Callback function
2020   * @retval status
2021   */
HAL_QSPI_RegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId,pQSPI_CallbackTypeDef pCallback)2022 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
2023 {
2024   HAL_StatusTypeDef status = HAL_OK;
2025 
2026   if(pCallback == NULL)
2027   {
2028     /* Update the error code */
2029     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2030     return HAL_ERROR;
2031   }
2032 
2033   /* Process locked */
2034   __HAL_LOCK(hqspi);
2035 
2036   if(hqspi->State == HAL_QSPI_STATE_READY)
2037   {
2038     switch (CallbackId)
2039     {
2040     case  HAL_QSPI_ERROR_CB_ID :
2041       hqspi->ErrorCallback = pCallback;
2042       break;
2043     case HAL_QSPI_ABORT_CB_ID :
2044       hqspi->AbortCpltCallback = pCallback;
2045       break;
2046     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2047       hqspi->FifoThresholdCallback = pCallback;
2048       break;
2049     case HAL_QSPI_CMD_CPLT_CB_ID :
2050       hqspi->CmdCpltCallback = pCallback;
2051       break;
2052     case HAL_QSPI_RX_CPLT_CB_ID :
2053       hqspi->RxCpltCallback = pCallback;
2054       break;
2055     case HAL_QSPI_TX_CPLT_CB_ID :
2056       hqspi->TxCpltCallback = pCallback;
2057       break;
2058     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2059       hqspi->RxHalfCpltCallback = pCallback;
2060       break;
2061     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2062       hqspi->TxHalfCpltCallback = pCallback;
2063       break;
2064     case HAL_QSPI_STATUS_MATCH_CB_ID :
2065       hqspi->StatusMatchCallback = pCallback;
2066       break;
2067     case HAL_QSPI_TIMEOUT_CB_ID :
2068       hqspi->TimeOutCallback = pCallback;
2069       break;
2070     case HAL_QSPI_MSP_INIT_CB_ID :
2071       hqspi->MspInitCallback = pCallback;
2072       break;
2073     case HAL_QSPI_MSP_DEINIT_CB_ID :
2074       hqspi->MspDeInitCallback = pCallback;
2075       break;
2076     default :
2077       /* Update the error code */
2078       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2079       /* update return status */
2080       status =  HAL_ERROR;
2081       break;
2082     }
2083   }
2084   else if (hqspi->State == HAL_QSPI_STATE_RESET)
2085   {
2086     switch (CallbackId)
2087     {
2088     case HAL_QSPI_MSP_INIT_CB_ID :
2089       hqspi->MspInitCallback = pCallback;
2090       break;
2091     case HAL_QSPI_MSP_DEINIT_CB_ID :
2092       hqspi->MspDeInitCallback = pCallback;
2093       break;
2094     default :
2095       /* Update the error code */
2096       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2097       /* update return status */
2098       status =  HAL_ERROR;
2099       break;
2100     }
2101   }
2102   else
2103   {
2104     /* Update the error code */
2105     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2106     /* update return status */
2107     status =  HAL_ERROR;
2108   }
2109 
2110   /* Release Lock */
2111   __HAL_UNLOCK(hqspi);
2112   return status;
2113 }
2114 
2115 /**
2116   * @brief  Unregister a User QSPI Callback
2117   *         QSPI Callback is redirected to the weak (surcharged) predefined callback
2118   * @param hqspi QSPI handle
2119   * @param CallbackId ID of the callback to be unregistered
2120   *        This parameter can be one of the following values:
2121   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID
2122   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID
2123   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2124   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID
2125   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID
2126   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID
2127   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID
2128   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID
2129   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID
2130   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID
2131   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID
2132   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID
2133   * @retval status
2134   */
HAL_QSPI_UnRegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId)2135 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2136 {
2137   HAL_StatusTypeDef status = HAL_OK;
2138 
2139   /* Process locked */
2140   __HAL_LOCK(hqspi);
2141 
2142   if(hqspi->State == HAL_QSPI_STATE_READY)
2143   {
2144     switch (CallbackId)
2145     {
2146     case  HAL_QSPI_ERROR_CB_ID :
2147       hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2148       break;
2149     case HAL_QSPI_ABORT_CB_ID :
2150       hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2151       break;
2152     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2153       hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2154       break;
2155     case HAL_QSPI_CMD_CPLT_CB_ID :
2156       hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2157       break;
2158     case HAL_QSPI_RX_CPLT_CB_ID :
2159       hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2160       break;
2161     case HAL_QSPI_TX_CPLT_CB_ID :
2162       hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2163       break;
2164     case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2165       hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
2166       break;
2167     case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2168       hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
2169       break;
2170     case HAL_QSPI_STATUS_MATCH_CB_ID :
2171       hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2172       break;
2173     case HAL_QSPI_TIMEOUT_CB_ID :
2174       hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2175       break;
2176     case HAL_QSPI_MSP_INIT_CB_ID :
2177       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2178       break;
2179     case HAL_QSPI_MSP_DEINIT_CB_ID :
2180       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2181       break;
2182     default :
2183       /* Update the error code */
2184       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2185       /* update return status */
2186       status =  HAL_ERROR;
2187       break;
2188     }
2189   }
2190   else if (hqspi->State == HAL_QSPI_STATE_RESET)
2191   {
2192     switch (CallbackId)
2193     {
2194     case HAL_QSPI_MSP_INIT_CB_ID :
2195       hqspi->MspInitCallback = HAL_QSPI_MspInit;
2196       break;
2197     case HAL_QSPI_MSP_DEINIT_CB_ID :
2198       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2199       break;
2200     default :
2201       /* Update the error code */
2202       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2203       /* update return status */
2204       status =  HAL_ERROR;
2205       break;
2206     }
2207   }
2208   else
2209   {
2210     /* Update the error code */
2211     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2212     /* update return status */
2213     status =  HAL_ERROR;
2214   }
2215 
2216   /* Release Lock */
2217   __HAL_UNLOCK(hqspi);
2218   return status;
2219 }
2220 #endif
2221 
2222 /**
2223   * @}
2224   */
2225 
2226 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2227   *  @brief   QSPI control and State functions
2228   *
2229 @verbatim
2230  ===============================================================================
2231                   ##### Peripheral Control and State functions #####
2232  ===============================================================================
2233     [..]
2234     This subsection provides a set of functions allowing to :
2235       (+) Check in run-time the state of the driver.
2236       (+) Check the error code set during last operation.
2237       (+) Abort any operation.
2238 
2239 
2240 @endverbatim
2241   * @{
2242   */
2243 
2244 /**
2245   * @brief  Return the QSPI handle state.
2246   * @param  hqspi QSPI handle
2247   * @retval HAL state
2248   */
HAL_QSPI_GetState(QSPI_HandleTypeDef * hqspi)2249 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2250 {
2251   /* Return QSPI handle state */
2252   return hqspi->State;
2253 }
2254 
2255 /**
2256 * @brief  Return the QSPI error code.
2257 * @param  hqspi QSPI handle
2258 * @retval QSPI Error Code
2259 */
HAL_QSPI_GetError(QSPI_HandleTypeDef * hqspi)2260 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2261 {
2262   return hqspi->ErrorCode;
2263 }
2264 
2265 /**
2266 * @brief  Abort the current transmission.
2267 * @param  hqspi QSPI handle
2268 * @retval HAL status
2269 */
HAL_QSPI_Abort(QSPI_HandleTypeDef * hqspi)2270 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2271 {
2272   HAL_StatusTypeDef status = HAL_OK;
2273   uint32_t tickstart = HAL_GetTick();
2274 
2275   /* Check if the state is in one of the busy states */
2276   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2277   {
2278     /* Process unlocked */
2279     __HAL_UNLOCK(hqspi);
2280 
2281     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2282     {
2283       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2284       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2285 
2286       /* Abort DMA channel */
2287       status = HAL_DMA_Abort(hqspi->hdma);
2288       if(status != HAL_OK)
2289       {
2290         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2291       }
2292     }
2293 
2294     if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2295     {
2296       /* Configure QSPI: CR register with Abort request */
2297       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2298 
2299       /* Wait until TC flag is set to go back in idle state */
2300       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2301 
2302       if (status == HAL_OK)
2303       {
2304         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2305 
2306         /* Wait until BUSY flag is reset */
2307         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2308       }
2309 
2310       if (status == HAL_OK)
2311       {
2312         /* Reset functional mode configuration to indirect write mode by default */
2313         CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2314 
2315         /* Update state */
2316         hqspi->State = HAL_QSPI_STATE_READY;
2317       }
2318     }
2319     else
2320     {
2321       /* Update state */
2322       hqspi->State = HAL_QSPI_STATE_READY;
2323     }
2324   }
2325 
2326   return status;
2327 }
2328 
2329 /**
2330 * @brief  Abort the current transmission (non-blocking function)
2331 * @param  hqspi QSPI handle
2332 * @retval HAL status
2333 */
HAL_QSPI_Abort_IT(QSPI_HandleTypeDef * hqspi)2334 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2335 {
2336   HAL_StatusTypeDef status = HAL_OK;
2337 
2338   /* Check if the state is in one of the busy states */
2339   if (((uint32_t)hqspi->State & 0x2U) != 0U)
2340   {
2341     /* Process unlocked */
2342     __HAL_UNLOCK(hqspi);
2343 
2344     /* Update QSPI state */
2345     hqspi->State = HAL_QSPI_STATE_ABORT;
2346 
2347     /* Disable all interrupts */
2348     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2349 
2350     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2351     {
2352       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2353       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2354 
2355       /* Abort DMA channel */
2356       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
2357       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
2358       {
2359         /* Change state of QSPI */
2360         hqspi->State = HAL_QSPI_STATE_READY;
2361 
2362         /* Abort Complete callback */
2363 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2364         hqspi->AbortCpltCallback(hqspi);
2365 #else
2366         HAL_QSPI_AbortCpltCallback(hqspi);
2367 #endif
2368       }
2369     }
2370     else
2371     {
2372       if (__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY) != RESET)
2373       {
2374         /* Clear interrupt */
2375         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2376 
2377         /* Enable the QSPI Transfer Complete Interrupt */
2378         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2379 
2380         /* Configure QSPI: CR register with Abort request */
2381         SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2382       }
2383       else
2384       {
2385         /* Change state of QSPI */
2386         hqspi->State = HAL_QSPI_STATE_READY;
2387       }
2388     }
2389   }
2390   return status;
2391 }
2392 
2393 /** @brief Set QSPI timeout.
2394   * @param  hqspi QSPI handle.
2395   * @param  Timeout Timeout for the QSPI memory access.
2396   * @retval None
2397   */
HAL_QSPI_SetTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Timeout)2398 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2399 {
2400   hqspi->Timeout = Timeout;
2401 }
2402 
2403 /** @brief Set QSPI Fifo threshold.
2404   * @param  hqspi QSPI handle.
2405   * @param  Threshold Threshold of the Fifo (value between 1 and 16).
2406   * @retval HAL status
2407   */
HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef * hqspi,uint32_t Threshold)2408 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2409 {
2410   HAL_StatusTypeDef status = HAL_OK;
2411 
2412   /* Process locked */
2413   __HAL_LOCK(hqspi);
2414 
2415   if(hqspi->State == HAL_QSPI_STATE_READY)
2416   {
2417     /* Synchronize init structure with new FIFO threshold value */
2418     hqspi->Init.FifoThreshold = Threshold;
2419 
2420     /* Configure QSPI FIFO Threshold */
2421     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2422                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2423   }
2424   else
2425   {
2426     status = HAL_BUSY;
2427   }
2428 
2429   /* Process unlocked */
2430   __HAL_UNLOCK(hqspi);
2431 
2432   /* Return function status */
2433   return status;
2434 }
2435 
2436 /** @brief Get QSPI Fifo threshold.
2437   * @param  hqspi QSPI handle.
2438   * @retval Fifo threshold (value between 1 and 16)
2439   */
HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef * hqspi)2440 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2441 {
2442   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2443 }
2444 
2445 /** @brief  Set FlashID.
2446   * @param  hqspi QSPI handle.
2447   * @param  FlashID Index of the flash memory to be accessed.
2448   *                   This parameter can be a value of @ref QSPI_Flash_Select.
2449   * @note   The FlashID is ignored when dual flash mode is enabled.
2450   * @retval HAL status
2451   */
HAL_QSPI_SetFlashID(QSPI_HandleTypeDef * hqspi,uint32_t FlashID)2452 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2453 {
2454   HAL_StatusTypeDef status = HAL_OK;
2455 
2456   /* Check the parameter */
2457   assert_param(IS_QSPI_FLASH_ID(FlashID));
2458 
2459   /* Process locked */
2460   __HAL_LOCK(hqspi);
2461 
2462   if(hqspi->State == HAL_QSPI_STATE_READY)
2463   {
2464     /* Synchronize init structure with new FlashID value */
2465     hqspi->Init.FlashID = FlashID;
2466 
2467     /* Configure QSPI FlashID */
2468     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2469   }
2470   else
2471   {
2472     status = HAL_BUSY;
2473   }
2474 
2475   /* Process unlocked */
2476   __HAL_UNLOCK(hqspi);
2477 
2478   /* Return function status */
2479   return status;
2480 }
2481 
2482 /**
2483   * @}
2484   */
2485 
2486 /**
2487   * @}
2488   */
2489 
2490 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2491   * @{
2492   */
2493 
2494 /**
2495   * @brief  DMA QSPI receive process complete callback.
2496   * @param  hdma DMA handle
2497   * @retval None
2498   */
QSPI_DMARxCplt(DMA_HandleTypeDef * hdma)2499 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
2500 {
2501   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2502   hqspi->RxXferCount = 0U;
2503 
2504   /* Enable the QSPI transfer complete Interrupt */
2505   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2506 }
2507 
2508 /**
2509   * @brief  DMA QSPI transmit process complete callback.
2510   * @param  hdma DMA handle
2511   * @retval None
2512   */
QSPI_DMATxCplt(DMA_HandleTypeDef * hdma)2513 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
2514 {
2515   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2516   hqspi->TxXferCount = 0U;
2517 
2518   /* Enable the QSPI transfer complete Interrupt */
2519   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2520 }
2521 
2522 /**
2523   * @brief  DMA QSPI receive process half complete callback.
2524   * @param  hdma DMA handle
2525   * @retval None
2526   */
QSPI_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2527 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2528 {
2529   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2530 
2531 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2532   hqspi->RxHalfCpltCallback(hqspi);
2533 #else
2534   HAL_QSPI_RxHalfCpltCallback(hqspi);
2535 #endif
2536 }
2537 
2538 /**
2539   * @brief  DMA QSPI transmit process half complete callback.
2540   * @param  hdma DMA handle
2541   * @retval None
2542   */
QSPI_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2543 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2544 {
2545   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2546 
2547 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2548   hqspi->TxHalfCpltCallback(hqspi);
2549 #else
2550   HAL_QSPI_TxHalfCpltCallback(hqspi);
2551 #endif
2552 }
2553 
2554 /**
2555   * @brief  DMA QSPI communication error callback.
2556   * @param  hdma DMA handle
2557   * @retval None
2558   */
QSPI_DMAError(DMA_HandleTypeDef * hdma)2559 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
2560 {
2561   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2562 
2563   /* if DMA error is FIFO error ignore it */
2564   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2565   {
2566   hqspi->RxXferCount = 0U;
2567   hqspi->TxXferCount = 0U;
2568   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
2569 
2570   /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2571   CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2572 
2573   /* Abort the QSPI */
2574   (void)HAL_QSPI_Abort_IT(hqspi);
2575 
2576   }
2577 }
2578 
2579 /**
2580   * @brief  DMA QSPI abort complete callback.
2581   * @param  hdma DMA handle
2582   * @retval None
2583   */
QSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)2584 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2585 {
2586   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2587 
2588   hqspi->RxXferCount = 0U;
2589   hqspi->TxXferCount = 0U;
2590 
2591   if(hqspi->State == HAL_QSPI_STATE_ABORT)
2592   {
2593     /* DMA Abort called by QSPI abort */
2594     /* Clear interrupt */
2595     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2596 
2597     /* Enable the QSPI Transfer Complete Interrupt */
2598     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2599 
2600     /* Configure QSPI: CR register with Abort request */
2601     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2602   }
2603   else
2604   {
2605     /* DMA Abort called due to a transfer error interrupt */
2606     /* Change state of QSPI */
2607     hqspi->State = HAL_QSPI_STATE_READY;
2608 
2609     /* Error callback */
2610 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2611     hqspi->ErrorCallback(hqspi);
2612 #else
2613     HAL_QSPI_ErrorCallback(hqspi);
2614 #endif
2615   }
2616 }
2617 
2618 /**
2619   * @brief  Wait for a flag state until timeout.
2620   * @param  hqspi QSPI handle
2621   * @param  Flag Flag checked
2622   * @param  State Value of the flag expected
2623   * @param  Tickstart Tick start value
2624   * @param  Timeout Duration of the timeout
2625   * @retval HAL status
2626   */
QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2627 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2628                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2629 {
2630   /* Wait until flag is in expected state */
2631   while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2632   {
2633     /* Check for the Timeout */
2634     if (Timeout != HAL_MAX_DELAY)
2635     {
2636       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2637       {
2638         hqspi->State     = HAL_QSPI_STATE_ERROR;
2639         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2640 
2641         return HAL_ERROR;
2642       }
2643     }
2644   }
2645   return HAL_OK;
2646 }
2647 
2648 /**
2649   * @brief  Wait for a flag state until timeout using CPU cycle.
2650   * @param  hqspi : QSPI handle
2651   * @param  Flag : Flag checked
2652   * @param  State : Value of the flag expected
2653   * @param  Timeout : Duration of the timeout
2654   * @retval HAL status
2655   */
QSPI_WaitFlagStateUntilTimeout_CPUCycle(QSPI_HandleTypeDef * hqspi,uint32_t Flag,FlagStatus State,uint32_t Timeout)2656 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout_CPUCycle(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout)
2657 {
2658   __IO uint32_t count = Timeout * (SystemCoreClock / 16U / 1000U);
2659    do
2660    {
2661      if (count-- == 0U)
2662      {
2663        hqspi->State     = HAL_QSPI_STATE_ERROR;
2664        hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2665        return HAL_TIMEOUT;
2666      }
2667    }
2668    while ((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State);
2669 
2670    return HAL_OK;
2671 }
2672 
2673 /**
2674   * @brief  Configure the communication registers.
2675   * @param  hqspi QSPI handle
2676   * @param  cmd structure that contains the command configuration information
2677   * @param  FunctionalMode functional mode to configured
2678   *           This parameter can be one of the following values:
2679   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2680   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2681   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2682   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2683   * @retval None
2684   */
QSPI_Config(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t FunctionalMode)2685 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2686 {
2687   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2688 
2689   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2690   {
2691     /* Configure QSPI: DLR register with the number of data to read or write */
2692     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2693   }
2694 
2695   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2696   {
2697     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2698     {
2699       /* Configure QSPI: ABR register with alternate bytes value */
2700       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2701 
2702       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2703       {
2704         /*---- Command with instruction, address and alternate bytes ----*/
2705         /* Configure QSPI: CCR register with all communications parameters */
2706         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2707                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2708                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2709                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2710                                          cmd->Instruction | FunctionalMode));
2711 
2712         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2713         {
2714           /* Configure QSPI: AR register with address value */
2715           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2716         }
2717       }
2718       else
2719       {
2720         /*---- Command with instruction and alternate bytes ----*/
2721         /* Configure QSPI: CCR register with all communications parameters */
2722         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2723                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2724                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2725                                          cmd->AddressMode | cmd->InstructionMode |
2726                                          cmd->Instruction | FunctionalMode));
2727       }
2728     }
2729     else
2730     {
2731       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2732       {
2733         /*---- Command with instruction and address ----*/
2734         /* Configure QSPI: CCR register with all communications parameters */
2735         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2736                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2737                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2738                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2739 
2740         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2741         {
2742           /* Configure QSPI: AR register with address value */
2743           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2744         }
2745       }
2746       else
2747       {
2748         /*---- Command with only instruction ----*/
2749         /* Configure QSPI: CCR register with all communications parameters */
2750         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2751                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2752                                          cmd->AlternateByteMode | cmd->AddressMode |
2753                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2754       }
2755     }
2756   }
2757   else
2758   {
2759     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2760     {
2761       /* Configure QSPI: ABR register with alternate bytes value */
2762       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2763 
2764       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2765       {
2766         /*---- Command with address and alternate bytes ----*/
2767         /* Configure QSPI: CCR register with all communications parameters */
2768         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2769                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2770                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2771                                          cmd->AddressSize | cmd->AddressMode |
2772                                          cmd->InstructionMode | FunctionalMode));
2773 
2774         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2775         {
2776           /* Configure QSPI: AR register with address value */
2777           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2778         }
2779       }
2780       else
2781       {
2782         /*---- Command with only alternate bytes ----*/
2783         /* Configure QSPI: CCR register with all communications parameters */
2784         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2785                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2786                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |
2787                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2788       }
2789     }
2790     else
2791     {
2792       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2793       {
2794         /*---- Command with only address ----*/
2795         /* Configure QSPI: CCR register with all communications parameters */
2796         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2797                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2798                                          cmd->AlternateByteMode | cmd->AddressSize |
2799                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2800 
2801         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2802         {
2803           /* Configure QSPI: AR register with address value */
2804           WRITE_REG(hqspi->Instance->AR, cmd->Address);
2805         }
2806       }
2807       else
2808       {
2809         /*---- Command with only data phase ----*/
2810         if (cmd->DataMode != QSPI_DATA_NONE)
2811         {
2812           /* Configure QSPI: CCR register with all communications parameters */
2813           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2814                                            cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2815                                            cmd->AlternateByteMode | cmd->AddressMode |
2816                                            cmd->InstructionMode | FunctionalMode));
2817         }
2818       }
2819     }
2820   }
2821 }
2822 
2823 /**
2824   * @}
2825   */
2826 
2827 /**
2828   * @}
2829   */
2830 
2831 #endif /* HAL_QSPI_MODULE_ENABLED */
2832 /**
2833   * @}
2834   */
2835 
2836 /**
2837   * @}
2838   */
2839 
2840 #endif /* defined(QUADSPI) */
2841