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