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