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