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