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