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