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