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