Updated and Validated
[betaflight.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_qspi.c
blobd95528fe90e37dbeed7db42eb33399c1fcfa828d
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_qspi.c
4 * @author MCD Application Team
5 * @brief QSPI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the QuadSPI interface (QSPI).
8 * + Initialization and de-initialization functions
9 * + Indirect functional mode management
10 * + Memory-mapped functional mode management
11 * + Auto-polling functional mode management
12 * + Interrupts and flags management
13 * + DMA channel configuration for indirect functional mode
14 * + Errors management and abort functionality
17 @verbatim
18 ===============================================================================
19 ##### How to use this driver #####
20 ===============================================================================
21 [..]
22 *** Initialization ***
23 ======================
24 [..]
25 (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
26 (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
27 (++) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
28 (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
29 (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
30 (++) If interrupt mode is used, enable and configure QuadSPI global
31 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
32 (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
33 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
34 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
35 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
36 (#) Configure the flash size, the clock prescaler, the fifo threshold, the
37 clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
39 *** Indirect functional mode ***
40 ================================
41 [..]
42 (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
43 functions :
44 (++) Instruction phase : the mode used and if present the instruction opcode.
45 (++) Address phase : the mode used and if present the size and the address value.
46 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
47 bytes values.
48 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
49 (++) Data phase : the mode used and if present the number of bytes.
50 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
51 if activated.
52 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
53 (#) If no data is required for the command, it is sent directly to the memory :
54 (++) In polling mode, the output of the function is done when the transfer is complete.
55 (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
56 (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
57 HAL_QSPI_Transmit_IT() after the command configuration :
58 (++) In polling mode, the output of the function is done when the transfer is complete.
59 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
60 is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
61 (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
62 HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
63 (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
64 HAL_QSPI_Receive_IT() after the command configuration :
65 (++) In polling mode, the output of the function is done when the transfer is complete.
66 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
67 is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
68 (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
69 HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
71 *** Auto-polling functional mode ***
72 ====================================
73 [..]
74 (#) Configure the command sequence and the auto-polling functional mode using the
75 HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
76 (++) Instruction phase : the mode used and if present the instruction opcode.
77 (++) Address phase : the mode used and if present the size and the address value.
78 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
79 bytes values.
80 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
81 (++) Data phase : the mode used.
82 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
83 if activated.
84 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
85 (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
86 the polling interval and the automatic stop activation.
87 (#) After the configuration :
88 (++) In polling mode, the output of the function is done when the status match is reached. The
89 automatic stop is activated to avoid an infinite loop.
90 (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
92 *** Memory-mapped functional mode ***
93 =====================================
94 [..]
95 (#) Configure the command sequence and the memory-mapped functional mode using the
96 HAL_QSPI_MemoryMapped() functions :
97 (++) Instruction phase : the mode used and if present the instruction opcode.
98 (++) Address phase : the mode used and the size.
99 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
100 bytes values.
101 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
102 (++) Data phase : the mode used.
103 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
104 if activated.
105 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
106 (++) The timeout activation and the timeout period.
107 (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
108 the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
110 *** Errors management and abort functionality ***
111 ==================================================
112 [..]
113 (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
114 (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
115 flushes the fifo :
116 (++) In polling mode, the output of the function is done when the transfer
117 complete bit is set and the busy bit cleared.
118 (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
119 the transfer complete bi is set.
121 *** Control functions ***
122 =========================
123 [..]
124 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
125 (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
126 (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
127 (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
129 *** Callback registration ***
130 =============================================
131 [..]
132 The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
133 allows the user to configure dynamically the driver callbacks.
135 Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,
136 it allows to register following callbacks:
137 (+) ErrorCallback : callback when error occurs.
138 (+) AbortCpltCallback : callback when abort is completed.
139 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
140 (+) CmdCpltCallback : callback when a command without data is completed.
141 (+) RxCpltCallback : callback when a reception transfer is completed.
142 (+) TxCpltCallback : callback when a transmission transfer is completed.
143 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
144 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
145 (+) StatusMatchCallback : callback when a status match occurs.
146 (+) TimeOutCallback : callback when the timeout perioed expires.
147 (+) MspInitCallback : QSPI MspInit.
148 (+) MspDeInitCallback : QSPI MspDeInit.
149 This function takes as parameters the HAL peripheral handle, the Callback ID
150 and a pointer to the user callback function.
152 Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default
153 weak (surcharged) function. It allows to reset following callbacks:
154 (+) ErrorCallback : callback when error occurs.
155 (+) AbortCpltCallback : callback when abort is completed.
156 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
157 (+) CmdCpltCallback : callback when a command without data is completed.
158 (+) RxCpltCallback : callback when a reception transfer is completed.
159 (+) TxCpltCallback : callback when a transmission transfer is completed.
160 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
161 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
162 (+) StatusMatchCallback : callback when a status match occurs.
163 (+) TimeOutCallback : callback when the timeout perioed expires.
164 (+) MspInitCallback : QSPI MspInit.
165 (+) MspDeInitCallback : QSPI MspDeInit.
166 This function) takes as parameters the HAL peripheral handle and the Callback ID.
168 By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
169 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
170 Exception done for MspInit and MspDeInit callbacks that are respectively
171 reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init
172 and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
173 If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit
174 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
176 Callbacks can be registered/unregistered in READY state only.
177 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
178 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
179 during the Init/DeInit.
180 In that case first register the MspInit/MspDeInit user callbacks
181 using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
182 or @ref HAL_QSPI_Init function.
184 When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
185 not defined, the callback registering feature is not available
186 and weak (surcharged) callbacks are used.
188 *** Workarounds linked to Silicon Limitation ***
189 ====================================================
190 [..]
191 (#) Workarounds Implemented inside HAL Driver
192 (++) Extra data written in the FIFO at the end of a read transfer
194 @endverbatim
195 ******************************************************************************
196 * @attention
198 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
199 * All rights reserved.</center></h2>
201 * This software component is licensed by ST under BSD 3-Clause license,
202 * the "License"; You may not use this file except in compliance with the
203 * License. You may obtain a copy of the License at:
204 * opensource.org/licenses/BSD-3-Clause
206 ******************************************************************************
209 /* Includes ------------------------------------------------------------------*/
210 #include "stm32f7xx_hal.h"
212 /** @addtogroup STM32F7xx_HAL_Driver
213 * @{
216 /** @defgroup QSPI QSPI
217 * @brief HAL QSPI module driver
218 * @{
220 #ifdef HAL_QSPI_MODULE_ENABLED
222 /* Private typedef -----------------------------------------------------------*/
223 /* Private define ------------------------------------------------------------*/
224 /** @addtogroup QSPI_Private_Constants
225 * @{
227 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000U) /*!<Indirect write mode*/
228 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
229 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
230 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
232 * @}
235 /* Private macro -------------------------------------------------------------*/
236 /** @addtogroup QSPI_Private_Macros QSPI Private Macros
237 * @{
239 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
240 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
241 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
242 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
244 * @}
247 /* Private variables ---------------------------------------------------------*/
248 /* Private function prototypes -----------------------------------------------*/
249 /** @addtogroup QSPI_Private_Functions QSPI Private Functions
250 * @{
252 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
253 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
254 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
255 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
256 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
257 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
258 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t tickstart, uint32_t Timeout);
259 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
261 * @}
264 /* Exported functions ---------------------------------------------------------*/
266 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
267 * @{
270 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
271 * @brief Initialization and Configuration functions
273 @verbatim
274 ===============================================================================
275 ##### Initialization and Configuration functions #####
276 ===============================================================================
277 [..]
278 This subsection provides a set of functions allowing to :
279 (+) Initialize the QuadSPI.
280 (+) De-initialize the QuadSPI.
282 @endverbatim
283 * @{
287 * @brief Initializes the QSPI mode according to the specified parameters
288 * in the QSPI_InitTypeDef and creates the associated handle.
289 * @param hqspi qspi handle
290 * @retval HAL status
292 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
294 HAL_StatusTypeDef status = HAL_ERROR;
295 uint32_t tickstart = HAL_GetTick();
297 /* Check the QSPI handle allocation */
298 if(hqspi == NULL)
300 return HAL_ERROR;
303 /* Check the parameters */
304 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
305 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
306 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
307 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
308 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
309 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
310 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
311 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
313 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
315 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
318 /* Process locked */
319 __HAL_LOCK(hqspi);
321 if(hqspi->State == HAL_QSPI_STATE_RESET)
323 /* Allocate lock resource and initialize it */
324 hqspi->Lock = HAL_UNLOCKED;
326 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
327 /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
328 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
329 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
330 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
331 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
332 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
333 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
334 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
335 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
336 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
337 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
339 if(hqspi->MspInitCallback == NULL)
341 hqspi->MspInitCallback = HAL_QSPI_MspInit;
344 /* Init the low level hardware */
345 hqspi->MspInitCallback(hqspi);
346 #else
347 /* Init the low level hardware : GPIO, CLOCK */
348 HAL_QSPI_MspInit(hqspi);
349 #endif
351 /* Configure the default timeout for the QSPI memory access */
352 HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
355 /* Configure QSPI FIFO Threshold */
356 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, ((hqspi->Init.FifoThreshold - 1) << 8));
358 /* Wait till BUSY flag reset */
359 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
361 if(status == HAL_OK)
364 /* Configure QSPI Clock Prescaler and Sample Shift */
365 MODIFY_REG(hqspi->Instance->CR,(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM), ((hqspi->Init.ClockPrescaler << 24)| hqspi->Init.SampleShifting | hqspi->Init.FlashID| hqspi->Init.DualFlash ));
367 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
368 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
369 ((hqspi->Init.FlashSize << 16) | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
371 /* Enable the QSPI peripheral */
372 __HAL_QSPI_ENABLE(hqspi);
374 /* Set QSPI error code to none */
375 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
377 /* Initialize the QSPI state */
378 hqspi->State = HAL_QSPI_STATE_READY;
381 /* Release Lock */
382 __HAL_UNLOCK(hqspi);
384 /* Return function status */
385 return status;
389 * @brief DeInitializes the QSPI peripheral
390 * @param hqspi qspi handle
391 * @retval HAL status
393 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
395 /* Check the QSPI handle allocation */
396 if(hqspi == NULL)
398 return HAL_ERROR;
401 /* Process locked */
402 __HAL_LOCK(hqspi);
404 /* Disable the QSPI Peripheral Clock */
405 __HAL_QSPI_DISABLE(hqspi);
407 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
408 if(hqspi->MspDeInitCallback == NULL)
410 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
413 /* DeInit the low level hardware */
414 hqspi->MspDeInitCallback(hqspi);
415 #else
416 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
417 HAL_QSPI_MspDeInit(hqspi);
418 #endif
420 /* Set QSPI error code to none */
421 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
423 /* Initialize the QSPI state */
424 hqspi->State = HAL_QSPI_STATE_RESET;
426 /* Release Lock */
427 __HAL_UNLOCK(hqspi);
429 return HAL_OK;
433 * @brief QSPI MSP Init
434 * @param hqspi QSPI handle
435 * @retval None
437 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
439 /* Prevent unused argument(s) compilation warning */
440 UNUSED(hqspi);
442 /* NOTE : This function should not be modified, when the callback is needed,
443 the HAL_QSPI_MspInit can be implemented in the user file
448 * @brief QSPI MSP DeInit
449 * @param hqspi QSPI handle
450 * @retval None
452 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
454 /* Prevent unused argument(s) compilation warning */
455 UNUSED(hqspi);
457 /* NOTE : This function should not be modified, when the callback is needed,
458 the HAL_QSPI_MspDeInit can be implemented in the user file
463 * @}
466 /** @defgroup QSPI_Exported_Functions_Group2 IO operation functions
467 * @brief QSPI Transmit/Receive functions
469 @verbatim
470 ===============================================================================
471 ##### IO operation functions #####
472 ===============================================================================
473 [..]
474 This subsection provides a set of functions allowing to :
475 (+) Handle the interrupts.
476 (+) Handle the command sequence.
477 (+) Transmit data in blocking, interrupt or DMA mode.
478 (+) Receive data in blocking, interrupt or DMA mode.
479 (+) Manage the auto-polling functional mode.
480 (+) Manage the memory-mapped functional mode.
482 @endverbatim
483 * @{
487 * @brief This function handles QSPI interrupt request.
488 * @param hqspi QSPI handle
489 * @retval None.
491 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
493 __IO uint32_t *data_reg;
494 uint32_t flag = READ_REG(hqspi->Instance->SR);
495 uint32_t itsource = READ_REG(hqspi->Instance->CR);
497 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
498 if(((flag & QSPI_FLAG_FT)!= RESET) && ((itsource & QSPI_IT_FT)!= RESET))
500 data_reg = &hqspi->Instance->DR;
502 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
504 /* Transmission process */
505 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
507 if (hqspi->TxXferCount > 0)
509 /* Fill the FIFO until it is full */
510 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
511 hqspi->TxXferCount--;
513 else
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;
522 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
524 /* Receiving Process */
525 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
527 if (hqspi->RxXferCount > 0)
529 /* Read the FIFO until it is empty */
530 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
531 hqspi->RxXferCount--;
533 else
535 /* All data have been received for the transfer */
536 /* Disable the QSPI FIFO Threshold Interrupt */
537 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
538 break;
543 /* FIFO Threshold callback */
544 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
545 hqspi->FifoThresholdCallback(hqspi);
546 #else
547 HAL_QSPI_FifoThresholdCallback(hqspi);
548 #endif
551 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
552 else if(((flag & QSPI_FLAG_TC)!= RESET) && ((itsource & QSPI_IT_TC)!= RESET))
554 /* Clear interrupt */
555 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
557 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
558 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
560 /* Transfer complete callback */
561 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
563 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
565 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
566 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
568 /* Disable the DMA channel */
569 __HAL_DMA_DISABLE(hqspi->hdma);
572 #if defined(QSPI1_V1_0)
573 /* Clear Busy bit */
574 HAL_QSPI_Abort_IT(hqspi);
575 #endif
577 /* Change state of QSPI */
578 hqspi->State = HAL_QSPI_STATE_READY;
580 /* TX Complete callback */
581 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
582 hqspi->TxCpltCallback(hqspi);
583 #else
584 HAL_QSPI_TxCpltCallback(hqspi);
585 #endif
587 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
589 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
591 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
592 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
594 /* Disable the DMA channel */
595 __HAL_DMA_DISABLE(hqspi->hdma);
597 else
599 data_reg = &hqspi->Instance->DR;
600 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0)
602 if (hqspi->RxXferCount > 0)
604 /* Read the last data received in the FIFO until it is empty */
605 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
606 hqspi->RxXferCount--;
608 else
610 /* All data have been received for the transfer */
611 break;
615 #if defined(QSPI1_V1_0)
616 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
617 HAL_QSPI_Abort_IT(hqspi);
618 #endif /* QSPI_V1_0*/
620 /* Change state of QSPI */
621 hqspi->State = HAL_QSPI_STATE_READY;
623 /* RX Complete callback */
624 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
625 hqspi->RxCpltCallback(hqspi);
626 #else
627 HAL_QSPI_RxCpltCallback(hqspi);
628 #endif
630 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
632 /* Change state of QSPI */
633 hqspi->State = HAL_QSPI_STATE_READY;
635 /* Command Complete callback */
636 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
637 hqspi->CmdCpltCallback(hqspi);
638 #else
639 HAL_QSPI_CmdCpltCallback(hqspi);
640 #endif
642 else if(hqspi->State == HAL_QSPI_STATE_ABORT)
644 /* Change state of QSPI */
645 hqspi->State = HAL_QSPI_STATE_READY;
647 if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
649 /* Abort called by the user */
651 /* Abort Complete callback */
652 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
653 hqspi->AbortCpltCallback(hqspi);
654 #else
655 HAL_QSPI_AbortCpltCallback(hqspi);
656 #endif
658 else
660 /* Abort due to an error (eg : DMA error) */
662 /* Error callback */
663 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
664 hqspi->ErrorCallback(hqspi);
665 #else
666 HAL_QSPI_ErrorCallback(hqspi);
667 #endif
672 /* QSPI Status Match interrupt occurred ------------------------------------*/
673 else if(((flag & QSPI_FLAG_SM)!= RESET) && ((itsource & QSPI_IT_SM)!= RESET))
675 /* Clear interrupt */
676 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
678 /* Check if the automatic poll mode stop is activated */
679 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0)
681 /* Disable the QSPI Transfer Error and Status Match Interrupts */
682 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
684 /* Change state of QSPI */
685 hqspi->State = HAL_QSPI_STATE_READY;
688 /* Status match callback */
689 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
690 hqspi->StatusMatchCallback(hqspi);
691 #else
692 HAL_QSPI_StatusMatchCallback(hqspi);
693 #endif
696 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
697 else if(((flag & QSPI_FLAG_TE)!= RESET) && ((itsource & QSPI_IT_TE)!= RESET))
699 /* Clear interrupt */
700 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
702 /* Disable all the QSPI Interrupts */
703 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
705 /* Set error code */
706 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
708 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
710 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
711 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
713 /* Disable the DMA channel */
714 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
715 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
717 /* Set error code to DMA */
718 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
720 /* Change state of QSPI */
721 hqspi->State = HAL_QSPI_STATE_READY;
723 /* Error callback */
724 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
725 hqspi->ErrorCallback(hqspi);
726 #else
727 HAL_QSPI_ErrorCallback(hqspi);
728 #endif
731 else
733 /* Change state of QSPI */
734 hqspi->State = HAL_QSPI_STATE_READY;
736 /* Error callback */
737 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
738 hqspi->ErrorCallback(hqspi);
739 #else
740 HAL_QSPI_ErrorCallback(hqspi);
741 #endif
745 /* QSPI Timeout interrupt occurred -----------------------------------------*/
746 else if(((flag & QSPI_FLAG_TO)!= RESET) && ((itsource & QSPI_IT_TO)!= RESET))
748 /* Clear interrupt */
749 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
751 /* Time out callback */
752 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
753 hqspi->TimeOutCallback(hqspi);
754 #else
755 HAL_QSPI_TimeOutCallback(hqspi);
756 #endif
761 * @brief Sets the command configuration.
762 * @param hqspi QSPI handle
763 * @param cmd structure that contains the command configuration information
764 * @param Timeout Time out duration
765 * @note This function is used only in Indirect Read or Write Modes
766 * @retval HAL status
768 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
770 HAL_StatusTypeDef status = HAL_ERROR;
771 uint32_t tickstart = HAL_GetTick();
773 /* Check the parameters */
774 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
775 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
777 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
780 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
781 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
783 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
786 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
787 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
789 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
792 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
793 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
795 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
796 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
797 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
799 /* Process locked */
800 __HAL_LOCK(hqspi);
802 if(hqspi->State == HAL_QSPI_STATE_READY)
804 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
806 /* Update QSPI state */
807 hqspi->State = HAL_QSPI_STATE_BUSY;
809 /* Wait till BUSY flag reset */
810 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
812 if (status == HAL_OK)
814 /* Call the configuration function */
815 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
817 if (cmd->DataMode == QSPI_DATA_NONE)
819 /* When there is no data phase, the transfer start as soon as the configuration is done
820 so wait until TC flag is set to go back in idle state */
821 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
823 if (status == HAL_OK)
825 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
827 /* Update QSPI state */
828 hqspi->State = HAL_QSPI_STATE_READY;
832 else
834 /* Update QSPI state */
835 hqspi->State = HAL_QSPI_STATE_READY;
839 else
841 status = HAL_BUSY;
844 /* Process unlocked */
845 __HAL_UNLOCK(hqspi);
847 /* Return function status */
848 return status;
852 * @brief Sets the command configuration in interrupt mode.
853 * @param hqspi QSPI handle
854 * @param cmd structure that contains the command configuration information
855 * @note This function is used only in Indirect Read or Write Modes
856 * @retval HAL status
858 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
860 HAL_StatusTypeDef status = HAL_ERROR;
861 uint32_t tickstart = HAL_GetTick();
863 /* Check the parameters */
864 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
865 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
867 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
870 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
871 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
873 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
876 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
877 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
879 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
882 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
883 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
885 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
886 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
887 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
889 /* Process locked */
890 __HAL_LOCK(hqspi);
892 if(hqspi->State == HAL_QSPI_STATE_READY)
894 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
896 /* Update QSPI state */
897 hqspi->State = HAL_QSPI_STATE_BUSY;
899 /* Wait till BUSY flag reset */
900 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
902 if (status == HAL_OK)
904 if (cmd->DataMode == QSPI_DATA_NONE)
906 /* Clear interrupt */
907 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
910 /* Call the configuration function */
911 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
913 if (cmd->DataMode == QSPI_DATA_NONE)
915 /* When there is no data phase, the transfer start as soon as the configuration is done
916 so activate TC and TE interrupts */
917 /* Process unlocked */
918 __HAL_UNLOCK(hqspi);
920 /* Enable the QSPI Transfer Error Interrupt */
921 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
923 else
925 /* Update QSPI state */
926 hqspi->State = HAL_QSPI_STATE_READY;
928 /* Process unlocked */
929 __HAL_UNLOCK(hqspi);
932 else
934 /* Process unlocked */
935 __HAL_UNLOCK(hqspi);
938 else
940 status = HAL_BUSY;
942 /* Process unlocked */
943 __HAL_UNLOCK(hqspi);
946 /* Return function status */
947 return status;
951 * @brief Transmit an amount of data in blocking mode.
952 * @param hqspi QSPI handle
953 * @param pData pointer to data buffer
954 * @param Timeout Time out duration
955 * @note This function is used only in Indirect Write Mode
956 * @retval HAL status
958 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
960 HAL_StatusTypeDef status = HAL_OK;
961 uint32_t tickstart = HAL_GetTick();
962 __IO uint32_t *data_reg = &hqspi->Instance->DR;
964 /* Process locked */
965 __HAL_LOCK(hqspi);
967 if(hqspi->State == HAL_QSPI_STATE_READY)
969 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
971 if(pData != NULL )
973 /* Update state */
974 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
976 /* Configure counters and size of the handle */
977 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
978 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
979 hqspi->pTxBuffPtr = pData;
981 /* Configure QSPI: CCR register with functional as indirect write */
982 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
984 while(hqspi->TxXferCount > 0)
986 /* Wait until FT flag is set to send data */
987 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
989 if (status != HAL_OK)
991 break;
994 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
995 hqspi->TxXferCount--;
998 if (status == HAL_OK)
1000 /* Wait until TC flag is set to go back in idle state */
1001 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1003 if (status == HAL_OK)
1005 /* Clear Transfer Complete bit */
1006 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1008 #if defined(QSPI1_V1_0)
1009 /* Clear Busy bit */
1010 status = HAL_QSPI_Abort(hqspi);
1011 #endif /* QSPI_V1_0 */
1015 /* Update QSPI state */
1016 hqspi->State = HAL_QSPI_STATE_READY;
1018 else
1020 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1021 status = HAL_ERROR;
1024 else
1026 status = HAL_BUSY;
1029 /* Process unlocked */
1030 __HAL_UNLOCK(hqspi);
1032 return status;
1037 * @brief Receive an amount of data in blocking mode
1038 * @param hqspi QSPI handle
1039 * @param pData pointer to data buffer
1040 * @param Timeout Time out duration
1041 * @note This function is used only in Indirect Read Mode
1042 * @retval HAL status
1044 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1046 HAL_StatusTypeDef status = HAL_OK;
1047 uint32_t tickstart = HAL_GetTick();
1048 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1049 __IO uint32_t *data_reg = &hqspi->Instance->DR;
1051 /* Process locked */
1052 __HAL_LOCK(hqspi);
1054 if(hqspi->State == HAL_QSPI_STATE_READY)
1056 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1057 if(pData != NULL )
1059 /* Update state */
1060 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1062 /* Configure counters and size of the handle */
1063 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
1064 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
1065 hqspi->pRxBuffPtr = pData;
1067 /* Configure QSPI: CCR register with functional as indirect read */
1068 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1070 /* Start the transfer by re-writing the address in AR register */
1071 WRITE_REG(hqspi->Instance->AR, addr_reg);
1073 while(hqspi->RxXferCount > 0)
1075 /* Wait until FT or TC flag is set to read received data */
1076 status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1078 if (status != HAL_OK)
1080 break;
1083 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
1084 hqspi->RxXferCount--;
1087 if (status == HAL_OK)
1089 /* Wait until TC flag is set to go back in idle state */
1090 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1092 if (status == HAL_OK)
1094 /* Clear Transfer Complete bit */
1095 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1097 #if defined(QSPI1_V1_0)
1098 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
1099 status = HAL_QSPI_Abort(hqspi);
1100 #endif /* QSPI_V1_0 */
1104 /* Update QSPI state */
1105 hqspi->State = HAL_QSPI_STATE_READY;
1107 else
1109 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1110 status = HAL_ERROR;
1113 else
1115 status = HAL_BUSY;
1118 /* Process unlocked */
1119 __HAL_UNLOCK(hqspi);
1121 return status;
1125 * @brief Send an amount of data in interrupt mode
1126 * @param hqspi QSPI handle
1127 * @param pData pointer to data buffer
1128 * @note This function is used only in Indirect Write Mode
1129 * @retval HAL status
1131 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1133 HAL_StatusTypeDef status = HAL_OK;
1135 /* Process locked */
1136 __HAL_LOCK(hqspi);
1138 if(hqspi->State == HAL_QSPI_STATE_READY)
1140 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1141 if(pData != NULL )
1143 /* Update state */
1144 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1146 /* Configure counters and size of the handle */
1147 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
1148 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
1149 hqspi->pTxBuffPtr = pData;
1151 /* Configure QSPI: CCR register with functional as indirect write */
1152 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1154 /* Clear interrupt */
1155 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1157 /* Process unlocked */
1158 __HAL_UNLOCK(hqspi);
1160 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1161 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1164 else
1166 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1167 status = HAL_ERROR;
1169 /* Process unlocked */
1170 __HAL_UNLOCK(hqspi);
1173 else
1175 status = HAL_BUSY;
1177 /* Process unlocked */
1178 __HAL_UNLOCK(hqspi);
1181 return status;
1185 * @brief Receive an amount of data in no-blocking mode with Interrupt
1186 * @param hqspi QSPI handle
1187 * @param pData pointer to data buffer
1188 * @note This function is used only in Indirect Read Mode
1189 * @retval HAL status
1191 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1193 HAL_StatusTypeDef status = HAL_OK;
1194 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1196 /* Process locked */
1197 __HAL_LOCK(hqspi);
1199 if(hqspi->State == HAL_QSPI_STATE_READY)
1201 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1203 if(pData != NULL )
1205 /* Update state */
1206 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1208 /* Configure counters and size of the handle */
1209 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
1210 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
1211 hqspi->pRxBuffPtr = pData;
1213 /* Configure QSPI: CCR register with functional as indirect read */
1214 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1216 /* Start the transfer by re-writing the address in AR register */
1217 WRITE_REG(hqspi->Instance->AR, addr_reg);
1219 /* Clear interrupt */
1220 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1222 /* Process unlocked */
1223 __HAL_UNLOCK(hqspi);
1225 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1226 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1228 else
1230 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1231 status = HAL_ERROR;
1233 /* Process unlocked */
1234 __HAL_UNLOCK(hqspi);
1237 else
1239 status = HAL_BUSY;
1241 /* Process unlocked */
1242 __HAL_UNLOCK(hqspi);
1245 return status;
1249 * @brief Sends an amount of data in non blocking mode with DMA.
1250 * @param hqspi QSPI handle
1251 * @param pData pointer to data buffer
1252 * @note This function is used only in Indirect Write Mode
1253 * @note If DMA peripheral access is configured as halfword, the number
1254 * of data and the fifo threshold should be aligned on halfword
1255 * @note If DMA peripheral access is configured as word, the number
1256 * of data and the fifo threshold should be aligned on word
1257 * @retval HAL status
1259 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1261 HAL_StatusTypeDef status = HAL_OK;
1262 uint32_t *tmp;
1263 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1);
1265 /* Process locked */
1266 __HAL_LOCK(hqspi);
1268 if(hqspi->State == HAL_QSPI_STATE_READY)
1270 /* Clear the error code */
1271 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1273 if(pData != NULL )
1275 /* Configure counters of the handle */
1276 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1278 hqspi->TxXferCount = data_size;
1280 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1282 if (((data_size % 2) != 0) || ((hqspi->Init.FifoThreshold % 2) != 0))
1284 /* The number of data or the fifo threshold is not aligned on halfword
1285 => no transfer possible with DMA peripheral access configured as halfword */
1286 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1287 status = HAL_ERROR;
1289 /* Process unlocked */
1290 __HAL_UNLOCK(hqspi);
1292 else
1294 hqspi->TxXferCount = (data_size >> 1);
1297 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1299 if (((data_size % 4) != 0) || ((hqspi->Init.FifoThreshold % 4) != 0))
1301 /* The number of data or the fifo threshold is not aligned on word
1302 => no transfer possible with DMA peripheral access configured as word */
1303 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1304 status = HAL_ERROR;
1306 /* Process unlocked */
1307 __HAL_UNLOCK(hqspi);
1309 else
1311 hqspi->TxXferCount = (data_size >> 2);
1315 if (status == HAL_OK)
1318 /* Update state */
1319 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1321 /* Clear interrupt */
1322 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1324 /* Configure size and pointer of the handle */
1325 hqspi->TxXferSize = hqspi->TxXferCount;
1326 hqspi->pTxBuffPtr = pData;
1328 /* Configure QSPI: CCR register with functional mode as indirect write */
1329 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1331 /* Set the QSPI DMA transfer complete callback */
1332 hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
1334 /* Set the QSPI DMA Half transfer complete callback */
1335 hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
1337 /* Set the DMA error callback */
1338 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1340 /* Clear the DMA abort callback */
1341 hqspi->hdma->XferAbortCallback = NULL;
1343 /* Configure the direction of the DMA */
1344 hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1345 MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1347 /* Enable the QSPI transmit DMA Channel */
1348 tmp = (uint32_t*)&pData;
1349 HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize);
1351 /* Process unlocked */
1352 __HAL_UNLOCK(hqspi);
1354 /* Enable the QSPI transfer error Interrupt */
1355 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1357 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1358 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1361 else
1363 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1365 status = HAL_ERROR;
1367 /* Process unlocked */
1368 __HAL_UNLOCK(hqspi);
1371 else
1373 status = HAL_BUSY;
1375 /* Process unlocked */
1376 __HAL_UNLOCK(hqspi);
1379 return status;
1383 * @brief Receives an amount of data in non blocking mode with DMA.
1384 * @param hqspi QSPI handle
1385 * @param pData pointer to data buffer.
1386 * @note This function is used only in Indirect Read Mode
1387 * @note If DMA peripheral access is configured as halfword, the number
1388 * of data and the fifo threshold should be aligned on halfword
1389 * @note If DMA peripheral access is configured as word, the number
1390 * of data and the fifo threshold should be aligned on word
1391 * @retval HAL status
1393 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1395 HAL_StatusTypeDef status = HAL_OK;
1396 uint32_t *tmp;
1397 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1398 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1);
1400 /* Process locked */
1401 __HAL_LOCK(hqspi);
1403 if(hqspi->State == HAL_QSPI_STATE_READY)
1405 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1407 if(pData != NULL )
1409 /* Configure counters of the handle */
1410 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1412 hqspi->RxXferCount = data_size;
1414 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1416 if (((data_size % 2) != 0) || ((hqspi->Init.FifoThreshold % 2) != 0))
1418 /* The number of data or the fifo threshold is not aligned on halfword
1419 => no transfer possible with DMA peripheral access configured as halfword */
1420 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1421 status = HAL_ERROR;
1423 /* Process unlocked */
1424 __HAL_UNLOCK(hqspi);
1426 else
1428 hqspi->RxXferCount = (data_size >> 1);
1431 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1433 if (((data_size % 4) != 0) || ((hqspi->Init.FifoThreshold % 4) != 0))
1435 /* The number of data or the fifo threshold is not aligned on word
1436 => no transfer possible with DMA peripheral access configured as word */
1437 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1438 status = HAL_ERROR;
1440 /* Process unlocked */
1441 __HAL_UNLOCK(hqspi);
1443 else
1445 hqspi->RxXferCount = (data_size >> 2);
1449 if (status == HAL_OK)
1452 /* Update state */
1453 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1455 /* Clear interrupt */
1456 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1458 /* Configure size and pointer of the handle */
1459 hqspi->RxXferSize = hqspi->RxXferCount;
1460 hqspi->pRxBuffPtr = pData;
1462 /* Set the QSPI DMA transfer complete callback */
1463 hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
1465 /* Set the QSPI DMA Half transfer complete callback */
1466 hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
1468 /* Set the DMA error callback */
1469 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1471 /* Clear the DMA abort callback */
1472 hqspi->hdma->XferAbortCallback = NULL;
1474 /* Configure the direction of the DMA */
1475 hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1476 MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1478 /* Enable the DMA Channel */
1479 tmp = (uint32_t*)&pData;
1480 HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
1482 /* Configure QSPI: CCR register with functional as indirect read */
1483 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1485 /* Start the transfer by re-writing the address in AR register */
1486 WRITE_REG(hqspi->Instance->AR, addr_reg);
1488 /* Process unlocked */
1489 __HAL_UNLOCK(hqspi);
1491 /* Enable the QSPI transfer error Interrupt */
1492 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1494 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1495 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1498 else
1500 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1501 status = HAL_ERROR;
1503 /* Process unlocked */
1504 __HAL_UNLOCK(hqspi);
1507 else
1509 status = HAL_BUSY;
1511 /* Process unlocked */
1512 __HAL_UNLOCK(hqspi);
1515 return status;
1519 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1520 * @param hqspi QSPI handle
1521 * @param cmd structure that contains the command configuration information.
1522 * @param cfg structure that contains the polling configuration information.
1523 * @param Timeout Time out duration
1524 * @note This function is used only in Automatic Polling Mode
1525 * @retval HAL status
1527 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1529 HAL_StatusTypeDef status = HAL_ERROR;
1530 uint32_t tickstart = HAL_GetTick();
1532 /* Check the parameters */
1533 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1534 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1536 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1539 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1540 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1542 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1545 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1546 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1548 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1551 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1552 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1554 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1555 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1556 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1558 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1559 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1560 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1562 /* Process locked */
1563 __HAL_LOCK(hqspi);
1565 if(hqspi->State == HAL_QSPI_STATE_READY)
1568 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1570 /* Update state */
1571 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1573 /* Wait till BUSY flag reset */
1574 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1576 if (status == HAL_OK)
1578 /* Configure QSPI: PSMAR register with the status match value */
1579 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1581 /* Configure QSPI: PSMKR register with the status mask value */
1582 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1584 /* Configure QSPI: PIR register with the interval value */
1585 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1587 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1588 (otherwise there will be an infinite loop in blocking mode) */
1589 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1590 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1592 /* Call the configuration function */
1593 cmd->NbData = cfg->StatusBytesSize;
1594 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1596 /* Wait until SM flag is set to go back in idle state */
1597 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1599 if (status == HAL_OK)
1601 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1603 /* Update state */
1604 hqspi->State = HAL_QSPI_STATE_READY;
1608 else
1610 status = HAL_BUSY;
1612 /* Process unlocked */
1613 __HAL_UNLOCK(hqspi);
1615 /* Return function status */
1616 return status;
1620 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1621 * @param hqspi QSPI handle
1622 * @param cmd structure that contains the command configuration information.
1623 * @param cfg structure that contains the polling configuration information.
1624 * @note This function is used only in Automatic Polling Mode
1625 * @retval HAL status
1627 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1629 HAL_StatusTypeDef status = HAL_ERROR;
1630 uint32_t tickstart = HAL_GetTick();
1632 /* Check the parameters */
1633 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1634 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1636 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1639 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1640 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1642 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1645 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1646 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1648 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1651 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1652 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1654 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1655 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1656 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1658 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1659 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1660 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1661 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1663 /* Process locked */
1664 __HAL_LOCK(hqspi);
1666 if(hqspi->State == HAL_QSPI_STATE_READY)
1668 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1670 /* Update state */
1671 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1673 /* Wait till BUSY flag reset */
1674 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1676 if (status == HAL_OK)
1678 /* Configure QSPI: PSMAR register with the status match value */
1679 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1681 /* Configure QSPI: PSMKR register with the status mask value */
1682 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1684 /* Configure QSPI: PIR register with the interval value */
1685 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1687 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1688 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1689 (cfg->MatchMode | cfg->AutomaticStop));
1691 /* Clear interrupt */
1692 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1694 /* Call the configuration function */
1695 cmd->NbData = cfg->StatusBytesSize;
1696 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1698 /* Process unlocked */
1699 __HAL_UNLOCK(hqspi);
1701 /* Enable the QSPI Transfer Error and status match Interrupt */
1702 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1705 else
1707 /* Process unlocked */
1708 __HAL_UNLOCK(hqspi);
1711 else
1713 status = HAL_BUSY;
1715 /* Process unlocked */
1716 __HAL_UNLOCK(hqspi);
1719 /* Return function status */
1720 return status;
1724 * @brief Configure the Memory Mapped mode.
1725 * @param hqspi QSPI handle
1726 * @param cmd structure that contains the command configuration information.
1727 * @param cfg structure that contains the memory mapped configuration information.
1728 * @note This function is used only in Memory mapped Mode
1729 * @retval HAL status
1731 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1733 HAL_StatusTypeDef status = HAL_ERROR;
1734 uint32_t tickstart = HAL_GetTick();
1736 /* Check the parameters */
1737 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1738 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1740 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1743 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1744 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1746 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1749 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1750 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1752 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1755 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1756 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1758 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1759 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1760 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1762 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1764 /* Process locked */
1765 __HAL_LOCK(hqspi);
1767 if(hqspi->State == HAL_QSPI_STATE_READY)
1769 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1771 /* Update state */
1772 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1774 /* Wait till BUSY flag reset */
1775 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1777 if (status == HAL_OK)
1779 /* Configure QSPI: CR register with timeout counter enable */
1780 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1782 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1784 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1786 /* Configure QSPI: LPTR register with the low-power timeout value */
1787 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1789 /* Clear interrupt */
1790 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1792 /* Enable the QSPI TimeOut Interrupt */
1793 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1796 /* Call the configuration function */
1797 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1800 else
1802 status = HAL_BUSY;
1805 /* Process unlocked */
1806 __HAL_UNLOCK(hqspi);
1808 /* Return function status */
1809 return status;
1813 * @brief Transfer Error callbacks
1814 * @param hqspi QSPI handle
1815 * @retval None
1817 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1819 /* Prevent unused argument(s) compilation warning */
1820 UNUSED(hqspi);
1822 /* NOTE : This function Should not be modified, when the callback is needed,
1823 the HAL_QSPI_ErrorCallback could be implemented in the user file
1828 * @brief Abort completed callback.
1829 * @param hqspi QSPI handle
1830 * @retval None
1832 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1834 /* Prevent unused argument(s) compilation warning */
1835 UNUSED(hqspi);
1837 /* NOTE: This function should not be modified, when the callback is needed,
1838 the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1843 * @brief Command completed callback.
1844 * @param hqspi QSPI handle
1845 * @retval None
1847 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1849 /* Prevent unused argument(s) compilation warning */
1850 UNUSED(hqspi);
1852 /* NOTE: This function Should not be modified, when the callback is needed,
1853 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1858 * @brief Rx Transfer completed callbacks.
1859 * @param hqspi QSPI handle
1860 * @retval None
1862 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1864 /* Prevent unused argument(s) compilation warning */
1865 UNUSED(hqspi);
1867 /* NOTE: This function Should not be modified, when the callback is needed,
1868 the HAL_QSPI_RxCpltCallback could be implemented in the user file
1873 * @brief Tx Transfer completed callbacks.
1874 * @param hqspi QSPI handle
1875 * @retval None
1877 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1879 /* Prevent unused argument(s) compilation warning */
1880 UNUSED(hqspi);
1882 /* NOTE: This function Should not be modified, when the callback is needed,
1883 the HAL_QSPI_TxCpltCallback could be implemented in the user file
1888 * @brief Rx Half Transfer completed callbacks.
1889 * @param hqspi QSPI handle
1890 * @retval None
1892 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1894 /* Prevent unused argument(s) compilation warning */
1895 UNUSED(hqspi);
1897 /* NOTE: This function Should not be modified, when the callback is needed,
1898 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
1903 * @brief Tx Half Transfer completed callbacks.
1904 * @param hqspi QSPI handle
1905 * @retval None
1907 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1909 /* Prevent unused argument(s) compilation warning */
1910 UNUSED(hqspi);
1912 /* NOTE: This function Should not be modified, when the callback is needed,
1913 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
1918 * @brief FIFO Threshold callbacks
1919 * @param hqspi QSPI handle
1920 * @retval None
1922 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1924 /* Prevent unused argument(s) compilation warning */
1925 UNUSED(hqspi);
1927 /* NOTE : This function Should not be modified, when the callback is needed,
1928 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1933 * @brief Status Match callbacks
1934 * @param hqspi QSPI handle
1935 * @retval None
1937 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1939 /* Prevent unused argument(s) compilation warning */
1940 UNUSED(hqspi);
1942 /* NOTE : This function Should not be modified, when the callback is needed,
1943 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1948 * @brief Timeout callbacks
1949 * @param hqspi QSPI handle
1950 * @retval None
1952 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1954 /* Prevent unused argument(s) compilation warning */
1955 UNUSED(hqspi);
1957 /* NOTE : This function Should not be modified, when the callback is needed,
1958 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1961 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
1963 * @brief Register a User QSPI Callback
1964 * To be used instead of the weak (surcharged) predefined callback
1965 * @param hqspi : QSPI handle
1966 * @param CallbackId : ID of the callback to be registered
1967 * This parameter can be one of the following values:
1968 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
1969 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
1970 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
1971 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
1972 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
1973 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
1974 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
1975 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
1976 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
1977 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
1978 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
1979 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
1980 * @param pCallback : pointer to the Callback function
1981 * @retval status
1983 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
1985 HAL_StatusTypeDef status = HAL_OK;
1987 if(pCallback == NULL)
1989 /* Update the error code */
1990 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1991 return HAL_ERROR;
1994 /* Process locked */
1995 __HAL_LOCK(hqspi);
1997 if(hqspi->State == HAL_QSPI_STATE_READY)
1999 switch (CallbackId)
2001 case HAL_QSPI_ERROR_CB_ID :
2002 hqspi->ErrorCallback = pCallback;
2003 break;
2004 case HAL_QSPI_ABORT_CB_ID :
2005 hqspi->AbortCpltCallback = pCallback;
2006 break;
2007 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2008 hqspi->FifoThresholdCallback = pCallback;
2009 break;
2010 case HAL_QSPI_CMD_CPLT_CB_ID :
2011 hqspi->CmdCpltCallback = pCallback;
2012 break;
2013 case HAL_QSPI_RX_CPLT_CB_ID :
2014 hqspi->RxCpltCallback = pCallback;
2015 break;
2016 case HAL_QSPI_TX_CPLT_CB_ID :
2017 hqspi->TxCpltCallback = pCallback;
2018 break;
2019 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2020 hqspi->RxHalfCpltCallback = pCallback;
2021 break;
2022 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2023 hqspi->TxHalfCpltCallback = pCallback;
2024 break;
2025 case HAL_QSPI_STATUS_MATCH_CB_ID :
2026 hqspi->StatusMatchCallback = pCallback;
2027 break;
2028 case HAL_QSPI_TIMEOUT_CB_ID :
2029 hqspi->TimeOutCallback = pCallback;
2030 break;
2031 case HAL_QSPI_MSP_INIT_CB_ID :
2032 hqspi->MspInitCallback = pCallback;
2033 break;
2034 case HAL_QSPI_MSP_DEINIT_CB_ID :
2035 hqspi->MspDeInitCallback = pCallback;
2036 break;
2037 default :
2038 /* Update the error code */
2039 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2040 /* update return status */
2041 status = HAL_ERROR;
2042 break;
2045 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2047 switch (CallbackId)
2049 case HAL_QSPI_MSP_INIT_CB_ID :
2050 hqspi->MspInitCallback = pCallback;
2051 break;
2052 case HAL_QSPI_MSP_DEINIT_CB_ID :
2053 hqspi->MspDeInitCallback = pCallback;
2054 break;
2055 default :
2056 /* Update the error code */
2057 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2058 /* update return status */
2059 status = HAL_ERROR;
2060 break;
2063 else
2065 /* Update the error code */
2066 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2067 /* update return status */
2068 status = HAL_ERROR;
2071 /* Release Lock */
2072 __HAL_UNLOCK(hqspi);
2073 return status;
2077 * @brief Unregister a User QSPI Callback
2078 * QSPI Callback is redirected to the weak (surcharged) predefined callback
2079 * @param hqspi : QSPI handle
2080 * @param CallbackId : ID of the callback to be unregistered
2081 * This parameter can be one of the following values:
2082 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
2083 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
2084 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2085 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
2086 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
2087 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
2088 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
2089 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
2090 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
2091 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
2092 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
2093 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
2094 * @retval status
2096 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2098 HAL_StatusTypeDef status = HAL_OK;
2100 /* Process locked */
2101 __HAL_LOCK(hqspi);
2103 if(hqspi->State == HAL_QSPI_STATE_READY)
2105 switch (CallbackId)
2107 case HAL_QSPI_ERROR_CB_ID :
2108 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2109 break;
2110 case HAL_QSPI_ABORT_CB_ID :
2111 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2112 break;
2113 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2114 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2115 break;
2116 case HAL_QSPI_CMD_CPLT_CB_ID :
2117 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2118 break;
2119 case HAL_QSPI_RX_CPLT_CB_ID :
2120 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2121 break;
2122 case HAL_QSPI_TX_CPLT_CB_ID :
2123 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2124 break;
2125 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2126 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
2127 break;
2128 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2129 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
2130 break;
2131 case HAL_QSPI_STATUS_MATCH_CB_ID :
2132 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2133 break;
2134 case HAL_QSPI_TIMEOUT_CB_ID :
2135 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2136 break;
2137 case HAL_QSPI_MSP_INIT_CB_ID :
2138 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2139 break;
2140 case HAL_QSPI_MSP_DEINIT_CB_ID :
2141 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2142 break;
2143 default :
2144 /* Update the error code */
2145 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2146 /* update return status */
2147 status = HAL_ERROR;
2148 break;
2151 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2153 switch (CallbackId)
2155 case HAL_QSPI_MSP_INIT_CB_ID :
2156 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2157 break;
2158 case HAL_QSPI_MSP_DEINIT_CB_ID :
2159 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2160 break;
2161 default :
2162 /* Update the error code */
2163 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2164 /* update return status */
2165 status = HAL_ERROR;
2166 break;
2169 else
2171 /* Update the error code */
2172 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2173 /* update return status */
2174 status = HAL_ERROR;
2177 /* Release Lock */
2178 __HAL_UNLOCK(hqspi);
2179 return status;
2181 #endif
2184 * @}
2187 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2188 * @brief QSPI control and State functions
2190 @verbatim
2191 ===============================================================================
2192 ##### Peripheral Control and State functions #####
2193 ===============================================================================
2194 [..]
2195 This subsection provides a set of functions allowing to :
2196 (+) Check in run-time the state of the driver.
2197 (+) Check the error code set during last operation.
2198 (+) Abort any operation.
2199 .....
2200 @endverbatim
2201 * @{
2205 * @brief Return the QSPI handle state.
2206 * @param hqspi QSPI handle
2207 * @retval HAL state
2209 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2211 /* Return QSPI handle state */
2212 return hqspi->State;
2216 * @brief Return the QSPI error code
2217 * @param hqspi QSPI handle
2218 * @retval QSPI Error Code
2220 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2222 return hqspi->ErrorCode;
2226 * @brief Abort the current transmission
2227 * @param hqspi QSPI handle
2228 * @retval HAL status
2230 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2232 HAL_StatusTypeDef status = HAL_OK;
2233 uint32_t tickstart = HAL_GetTick();
2235 /* Check if the state is in one of the busy states */
2236 if ((hqspi->State & 0x2) != 0)
2238 /* Process unlocked */
2239 __HAL_UNLOCK(hqspi);
2241 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
2243 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2244 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2246 /* Abort DMA channel */
2247 status = HAL_DMA_Abort(hqspi->hdma);
2248 if(status != HAL_OK)
2250 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2254 /* Configure QSPI: CR register with Abort request */
2255 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2257 /* Wait until TC flag is set to go back in idle state */
2258 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2260 if(status == HAL_OK)
2262 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2264 /* Wait until BUSY flag is reset */
2265 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2268 if (status == HAL_OK)
2270 /* Update state */
2271 hqspi->State = HAL_QSPI_STATE_READY;
2275 return status;
2279 * @brief Abort the current transmission (non-blocking function)
2280 * @param hqspi QSPI handle
2281 * @retval HAL status
2283 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2285 HAL_StatusTypeDef status = HAL_OK;
2287 /* Check if the state is in one of the busy states */
2288 if ((hqspi->State & 0x2) != 0)
2290 /* Process unlocked */
2291 __HAL_UNLOCK(hqspi);
2293 /* Update QSPI state */
2294 hqspi->State = HAL_QSPI_STATE_ABORT;
2296 /* Disable all interrupts */
2297 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2299 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
2301 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2302 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2304 /* Abort DMA channel */
2305 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
2306 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
2308 /* Change state of QSPI */
2309 hqspi->State = HAL_QSPI_STATE_READY;
2311 /* Abort Complete callback */
2312 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2313 hqspi->AbortCpltCallback(hqspi);
2314 #else
2315 HAL_QSPI_AbortCpltCallback(hqspi);
2316 #endif
2319 else
2321 /* Clear interrupt */
2322 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2324 /* Enable the QSPI Transfer Complete Interrupt */
2325 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2327 /* Configure QSPI: CR register with Abort request */
2328 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2332 return status;
2335 /** @brief Set QSPI timeout
2336 * @param hqspi QSPI handle.
2337 * @param Timeout Timeout for the QSPI memory access.
2338 * @retval None
2340 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2342 hqspi->Timeout = Timeout;
2345 /** @brief Set QSPI Fifo threshold.
2346 * @param hqspi QSPI handle.
2347 * @param Threshold Threshold of the Fifo (value between 1 and 16).
2348 * @retval HAL status
2350 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2352 HAL_StatusTypeDef status = HAL_OK;
2354 /* Process locked */
2355 __HAL_LOCK(hqspi);
2357 if(hqspi->State == HAL_QSPI_STATE_READY)
2359 /* Synchronize init structure with new FIFO threshold value */
2360 hqspi->Init.FifoThreshold = Threshold;
2362 /* Configure QSPI FIFO Threshold */
2363 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2364 ((hqspi->Init.FifoThreshold - 1) << QUADSPI_CR_FTHRES_Pos));
2366 else
2368 status = HAL_BUSY;
2371 /* Process unlocked */
2372 __HAL_UNLOCK(hqspi);
2374 /* Return function status */
2375 return status;
2378 /** @brief Get QSPI Fifo threshold.
2379 * @param hqspi QSPI handle.
2380 * @retval Fifo threshold (value between 1 and 16)
2382 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2384 return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1);
2388 * @}
2391 /* Private functions ---------------------------------------------------------*/
2394 * @brief DMA QSPI receive process complete callback.
2395 * @param hdma DMA handle
2396 * @retval None
2398 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
2400 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2401 hqspi->RxXferCount = 0;
2403 /* Enable the QSPI transfer complete Interrupt */
2404 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2408 * @brief DMA QSPI transmit process complete callback.
2409 * @param hdma DMA handle
2410 * @retval None
2412 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
2414 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2415 hqspi->TxXferCount = 0;
2417 /* Enable the QSPI transfer complete Interrupt */
2418 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2422 * @brief DMA QSPI receive process half complete callback
2423 * @param hdma DMA handle
2424 * @retval None
2426 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2428 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
2430 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2431 hqspi->RxHalfCpltCallback(hqspi);
2432 #else
2433 HAL_QSPI_RxHalfCpltCallback(hqspi);
2434 #endif
2438 * @brief DMA QSPI transmit process half complete callback
2439 * @param hdma DMA handle
2440 * @retval None
2442 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2444 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
2446 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2447 hqspi->TxHalfCpltCallback(hqspi);
2448 #else
2449 HAL_QSPI_TxHalfCpltCallback(hqspi);
2450 #endif
2454 * @brief DMA QSPI communication error callback.
2455 * @param hdma DMA handle
2456 * @retval None
2458 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
2460 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2462 /* if DMA error is FIFO error ignore it */
2463 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2465 hqspi->RxXferCount = 0;
2466 hqspi->TxXferCount = 0;
2467 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2469 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2470 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2472 /* Abort the QSPI */
2473 HAL_QSPI_Abort_IT(hqspi);
2478 * @brief DMA QSPI abort complete callback.
2479 * @param hdma DMA handle
2480 * @retval None
2482 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2484 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2486 hqspi->RxXferCount = 0;
2487 hqspi->TxXferCount = 0;
2489 if(hqspi->State == HAL_QSPI_STATE_ABORT)
2491 /* DMA Abort called by QSPI abort */
2492 /* Clear interrupt */
2493 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2495 /* Enable the QSPI Transfer Complete Interrupt */
2496 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2498 /* Configure QSPI: CR register with Abort request */
2499 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2501 else
2503 /* DMA Abort called due to a transfer error interrupt */
2504 /* Change state of QSPI */
2505 hqspi->State = HAL_QSPI_STATE_READY;
2507 /* Error callback */
2508 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2509 hqspi->ErrorCallback(hqspi);
2510 #else
2511 HAL_QSPI_ErrorCallback(hqspi);
2512 #endif
2517 * @brief Wait for a flag state until timeout.
2518 * @param hqspi QSPI handle
2519 * @param Flag Flag checked
2520 * @param State Value of the flag expected
2521 * @param tickstart Start tick value
2522 * @param Timeout Duration of the time out
2523 * @retval HAL status
2525 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2526 FlagStatus State, uint32_t tickstart, uint32_t Timeout)
2528 /* Wait until flag is in expected state */
2529 while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2531 /* Check for the Timeout */
2532 if (Timeout != HAL_MAX_DELAY)
2534 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
2536 hqspi->State = HAL_QSPI_STATE_ERROR;
2537 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2539 return HAL_ERROR;
2543 return HAL_OK;
2547 * @brief Configure the communication registers.
2548 * @param hqspi QSPI handle
2549 * @param cmd structure that contains the command configuration information
2550 * @param FunctionalMode functional mode to configured
2551 * This parameter can be one of the following values:
2552 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2553 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2554 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2555 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2556 * @retval None
2558 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2560 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2562 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2564 /* Configure QSPI: DLR register with the number of data to read or write */
2565 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1));
2568 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2570 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2572 /* Configure QSPI: ABR register with alternate bytes value */
2573 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2575 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2577 /*---- Command with instruction, address and alternate bytes ----*/
2578 /* Configure QSPI: CCR register with all communications parameters */
2579 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2580 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
2581 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2582 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2584 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2586 /* Configure QSPI: AR register with address value */
2587 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2590 else
2592 /*---- Command with instruction and alternate bytes ----*/
2593 /* Configure QSPI: CCR register with all communications parameters */
2594 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2595 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
2596 cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
2597 cmd->Instruction | FunctionalMode));
2600 else
2602 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2604 /*---- Command with instruction and address ----*/
2605 /* Configure QSPI: CCR register with all communications parameters */
2606 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2607 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
2608 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2609 cmd->Instruction | FunctionalMode));
2611 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2613 /* Configure QSPI: AR register with address value */
2614 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2617 else
2619 /*---- Command with only instruction ----*/
2620 /* Configure QSPI: CCR register with all communications parameters */
2621 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2622 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
2623 cmd->AddressMode | cmd->InstructionMode | cmd->Instruction |
2624 FunctionalMode));
2628 else
2630 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2632 /* Configure QSPI: ABR register with alternate bytes value */
2633 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2635 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2637 /*---- Command with address and alternate bytes ----*/
2638 /* Configure QSPI: CCR register with all communications parameters */
2639 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2640 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
2641 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2642 cmd->InstructionMode | FunctionalMode));
2644 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2646 /* Configure QSPI: AR register with address value */
2647 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2650 else
2652 /*---- Command with only alternate bytes ----*/
2653 /* Configure QSPI: CCR register with all communications parameters */
2654 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2655 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
2656 cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
2657 FunctionalMode));
2660 else
2662 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2664 /*---- Command with only address ----*/
2665 /* Configure QSPI: CCR register with all communications parameters */
2666 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2667 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
2668 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2669 FunctionalMode));
2671 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2673 /* Configure QSPI: AR register with address value */
2674 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2677 else
2679 /*---- Command with only data phase ----*/
2680 if (cmd->DataMode != QSPI_DATA_NONE)
2682 /* Configure QSPI: CCR register with all communications parameters */
2683 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2684 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
2685 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2692 * @}
2695 #endif /* HAL_QSPI_MODULE_ENABLED */
2697 * @}
2701 * @}
2704 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/