Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_qspi.c
blob0587b0b57c4d1ddb03ae8bacdce11bf9e3283882
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_qspi.c
4 * @author MCD Application Team
5 * @brief QSPI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the QuadSPI interface (QSPI).
8 * + Initialization and de-initialization functions
9 * + Indirect functional mode management
10 * + Memory-mapped functional mode management
11 * + Auto-polling functional mode management
12 * + Interrupts and flags management
13 * + MDMA channel configuration for indirect functional mode
14 * + Errors management and abort functionality
17 @verbatim
18 ===============================================================================
19 ##### How to use this driver #####
20 ===============================================================================
21 [..]
22 *** Initialization ***
23 ======================
24 [..]
25 (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
26 (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
27 (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
28 (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
29 (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
30 (++) If interrupt mode is used, enable and configure QuadSPI global
31 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
32 (++) If DMA mode is used, enable the clocks for the QuadSPI MDMA
33 with __HAL_RCC_MDMA_CLK_ENABLE(), configure MDMA with HAL_MDMA_Init(),
34 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
35 MDMA 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_TxCpltCallback() will be called when the transfer is complete.
62 (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
63 HAL_QSPI_Receive_IT() after the command configuration :
64 (++) In polling mode, the output of the function is done when the transfer is complete.
65 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
66 is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
67 (++) In DMA mode,HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
69 *** Auto-polling functional mode ***
70 ====================================
71 [..]
72 (#) Configure the command sequence and the auto-polling functional mode using the
73 HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
74 (++) Instruction phase : the mode used and if present the instruction opcode.
75 (++) Address phase : the mode used and if present the size and the address value.
76 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
77 bytes values.
78 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
79 (++) Data phase : the mode used.
80 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
81 if activated.
82 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
83 (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
84 the polling interval and the automatic stop activation.
85 (#) After the configuration :
86 (++) In polling mode, the output of the function is done when the status match is reached. The
87 automatic stop is activated to avoid an infinite loop.
88 (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
90 *** MDMA functional mode ***
91 ====================================
92 [..]
93 (#) Configure the SourceInc and DestinationInc of MDMA paramters in the HAL_QSPI_MspInit() function :
94 (++) MDMA settings for write operation :
95 (+) The DestinationInc should be MDMA_DEST_INC_DISABLE
96 (+) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
97 (+) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
98 aligned with @ref MDMA_Source_increment_mode .
99 (+) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
100 (++) MDMA settings for read operation :
101 (+) The SourceInc should be MDMA_SRC_INC_DISABLE
102 (+) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode (Except the MDMA_DEST_INC_DOUBLEWORD).
103 (+) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
104 (+) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
105 aligned with @ref MDMA_Destination_increment_mode.
106 (++)The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Quadspi.
107 (#)In case of wrong MDMA setting
108 (++) For write operation :
109 (+) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled by the HAL_QSPI_Transmit_DMA().
110 (++) For read operation :
111 (+) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled by the HAL_QSPI_Receive_DMA().
113 *** Memory-mapped functional mode ***
114 =====================================
115 [..]
116 (#) Configure the command sequence and the memory-mapped functional mode using the
117 HAL_QSPI_MemoryMapped() functions :
118 (++) Instruction phase : the mode used and if present the instruction opcode.
119 (++) Address phase : the mode used and the size.
120 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
121 bytes values.
122 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
123 (++) Data phase : the mode used.
124 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
125 if activated.
126 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
127 (++) The timeout activation and the timeout period.
128 (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
129 the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
131 *** Errors management and abort functionality ***
132 =================================================
133 [..]
134 (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
135 (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
136 flushes the fifo :
137 (++) In polling mode, the output of the function is done when the transfer
138 complete bit is set and the busy bit cleared.
139 (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
140 the transfer complete bit is set.
142 *** Control functions ***
143 =========================
144 [..]
145 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
146 (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
147 (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
148 (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
149 (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
151 *** Callback registration ***
152 =============================================
153 [..]
154 The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
155 allows the user to configure dynamically the driver callbacks.
157 Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,
158 it allows to register following callbacks:
159 (+) ErrorCallback : callback when error occurs.
160 (+) AbortCpltCallback : callback when abort is completed.
161 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
162 (+) CmdCpltCallback : callback when a command without data is completed.
163 (+) RxCpltCallback : callback when a reception transfer is completed.
164 (+) TxCpltCallback : callback when a transmission transfer is completed.
165 (+) StatusMatchCallback : callback when a status match occurs.
166 (+) TimeOutCallback : callback when the timeout perioed expires.
167 (+) MspInitCallback : QSPI MspInit.
168 (+) MspDeInitCallback : QSPI MspDeInit.
169 This function takes as parameters the HAL peripheral handle, the Callback ID
170 and a pointer to the user callback function.
172 Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default
173 weak (surcharged) function. It allows to reset following callbacks:
174 (+) ErrorCallback : callback when error occurs.
175 (+) AbortCpltCallback : callback when abort is completed.
176 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
177 (+) CmdCpltCallback : callback when a command without data is completed.
178 (+) RxCpltCallback : callback when a reception transfer is completed.
179 (+) TxCpltCallback : callback when a transmission transfer is completed.
180 (+) StatusMatchCallback : callback when a status match occurs.
181 (+) TimeOutCallback : callback when the timeout perioed expires.
182 (+) MspInitCallback : QSPI MspInit.
183 (+) MspDeInitCallback : QSPI MspDeInit.
184 This function) takes as parameters the HAL peripheral handle and the Callback ID.
186 By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
187 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
188 Exception done for MspInit and MspDeInit callbacks that are respectively
189 reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init
190 and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
191 If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit
192 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
194 Callbacks can be registered/unregistered in READY state only.
195 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
196 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
197 during the Init/DeInit.
198 In that case first register the MspInit/MspDeInit user callbacks
199 using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
200 or @ref HAL_QSPI_Init function.
202 When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
203 not defined, the callback registering feature is not available
204 and weak (surcharged) callbacks are used.
206 *** Workarounds linked to Silicon Limitation ***
207 ====================================================
208 [..]
209 (#) Workarounds Implemented inside HAL Driver
210 (++) Extra data written in the FIFO at the end of a read transfer
212 @endverbatim
213 ******************************************************************************
214 * @attention
216 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
217 * All rights reserved.</center></h2>
219 * This software component is licensed by ST under BSD 3-Clause license,
220 * the "License"; You may not use this file except in compliance with the
221 * License. You may obtain a copy of the License at:
222 * opensource.org/licenses/BSD-3-Clause
224 ******************************************************************************
227 /* Includes ------------------------------------------------------------------*/
228 #include "stm32h7xx_hal.h"
230 #if defined(QUADSPI)
232 /** @addtogroup STM32H7xx_HAL_Driver
233 * @{
236 /** @defgroup QSPI QSPI
237 * @brief QSPI HAL module driver
238 * @{
240 #ifdef HAL_QSPI_MODULE_ENABLED
242 /* Private typedef -----------------------------------------------------------*/
244 /* Private define ------------------------------------------------------------*/
245 /** @defgroup QSPI_Private_Constants QSPI Private Constants
246 * @{
248 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
249 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
250 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
251 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
253 * @}
256 /* Private macro -------------------------------------------------------------*/
257 /** @defgroup QSPI_Private_Macros QSPI Private Macros
258 * @{
260 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
261 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
262 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
263 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
265 * @}
268 /* Private variables ---------------------------------------------------------*/
270 /* Private function prototypes -----------------------------------------------*/
271 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma);
272 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma);
273 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma);
274 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma);
275 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
276 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
278 /* Exported functions --------------------------------------------------------*/
280 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
281 * @{
284 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
285 * @brief Initialization and Configuration functions
287 @verbatim
288 ===============================================================================
289 ##### Initialization and Configuration functions #####
290 ===============================================================================
291 [..]
292 This subsection provides a set of functions allowing to :
293 (+) Initialize the QuadSPI.
294 (+) De-initialize the QuadSPI.
296 @endverbatim
297 * @{
301 * @brief Initialize the QSPI mode according to the specified parameters
302 * in the QSPI_InitTypeDef and initialize the associated handle.
303 * @param hqspi : QSPI handle
304 * @retval HAL status
306 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
308 HAL_StatusTypeDef status;
309 uint32_t tickstart = HAL_GetTick();
311 /* Check the QSPI handle allocation */
312 if(hqspi == NULL)
314 return HAL_ERROR;
317 /* Check the parameters */
318 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
319 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
320 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
321 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
322 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
323 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
324 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
325 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
327 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
329 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
332 if(hqspi->State == HAL_QSPI_STATE_RESET)
335 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
336 /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
337 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
338 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
339 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
340 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
341 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
342 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
343 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
344 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
346 if(hqspi->MspInitCallback == NULL)
348 hqspi->MspInitCallback = HAL_QSPI_MspInit;
351 /* Init the low level hardware */
352 hqspi->MspInitCallback(hqspi);
353 #else
354 /* Init the low level hardware : GPIO, CLOCK */
355 HAL_QSPI_MspInit(hqspi);
356 #endif
358 /* Configure the default timeout for the QSPI memory access */
359 HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
362 /* Configure QSPI FIFO Threshold */
363 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
364 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
366 /* Wait till BUSY flag reset */
367 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
369 if(status == HAL_OK)
371 /* Configure QSPI Clock Prescaler and Sample Shift */
372 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
373 ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
374 hqspi->Init.SampleShifting | hqspi->Init.FlashID | hqspi->Init.DualFlash));
376 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
377 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
378 ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
379 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
381 /* Enable the QSPI peripheral */
382 __HAL_QSPI_ENABLE(hqspi);
384 /* Set QSPI error code to none */
385 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
387 /* Initialize the QSPI state */
388 hqspi->State = HAL_QSPI_STATE_READY;
391 /* Return function status */
392 return status;
396 * @brief De-Initialize the QSPI peripheral.
397 * @param hqspi : QSPI handle
398 * @retval HAL status
400 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
402 /* Check the QSPI handle allocation */
403 if(hqspi == NULL)
405 return HAL_ERROR;
408 /* Disable the QSPI Peripheral Clock */
409 __HAL_QSPI_DISABLE(hqspi);
411 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
412 if(hqspi->MspDeInitCallback == NULL)
414 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
417 /* DeInit the low level hardware */
418 hqspi->MspDeInitCallback(hqspi);
419 #else
420 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
421 HAL_QSPI_MspDeInit(hqspi);
422 #endif
424 /* Set QSPI error code to none */
425 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
427 /* Initialize the QSPI state */
428 hqspi->State = HAL_QSPI_STATE_RESET;
430 return HAL_OK;
434 * @brief Initialize the QSPI MSP.
435 * @param hqspi : QSPI handle
436 * @retval None
438 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
440 /* Prevent unused argument(s) compilation warning */
441 UNUSED(hqspi);
443 /* NOTE : This function should not be modified, when the callback is needed,
444 the HAL_QSPI_MspInit can be implemented in the user file
449 * @brief DeInitialize the QSPI MSP.
450 * @param hqspi : QSPI handle
451 * @retval None
453 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
455 /* Prevent unused argument(s) compilation warning */
456 UNUSED(hqspi);
458 /* NOTE : This function should not be modified, when the callback is needed,
459 the HAL_QSPI_MspDeInit can be implemented in the user file
464 * @}
467 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
468 * @brief QSPI Transmit/Receive functions
470 @verbatim
471 ===============================================================================
472 ##### IO operation functions #####
473 ===============================================================================
474 [..]
475 This subsection provides a set of functions allowing to :
476 (+) Handle the interrupts.
477 (+) Handle the command sequence.
478 (+) Transmit data in blocking, interrupt or DMA mode.
479 (+) Receive data in blocking, interrupt or DMA mode.
480 (+) Manage the auto-polling functional mode.
481 (+) Manage the memory-mapped functional mode.
483 @endverbatim
484 * @{
488 * @brief Handle QSPI interrupt request.
489 * @param hqspi : QSPI handle
490 * @retval None
492 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
494 __IO uint32_t *data_reg;
495 uint32_t flag = READ_REG(hqspi->Instance->SR);
496 uint32_t itsource = READ_REG(hqspi->Instance->CR);
498 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
499 if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
501 data_reg = &hqspi->Instance->DR;
503 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
505 /* Transmission process */
506 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
508 if (hqspi->TxXferCount > 0U)
510 /* Fill the FIFO until the threshold is reached */
511 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
512 hqspi->pTxBuffPtr++;
513 hqspi->TxXferCount--;
515 else
517 /* No more data available for the transfer */
518 /* Disable the QSPI FIFO Threshold Interrupt */
519 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
520 break;
524 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
526 /* Receiving Process */
527 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
529 if (hqspi->RxXferCount > 0U)
531 /* Read the FIFO until the threshold is reached */
532 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
533 hqspi->pRxBuffPtr++;
534 hqspi->RxXferCount--;
536 else
538 /* All data have been received for the transfer */
539 /* Disable the QSPI FIFO Threshold Interrupt */
540 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
541 break;
545 else
547 /* Nothing to do */
550 /* FIFO Threshold callback */
551 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
552 hqspi->FifoThresholdCallback(hqspi);
553 #else
554 HAL_QSPI_FifoThresholdCallback(hqspi);
555 #endif
558 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
559 else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
561 /* Clear interrupt */
562 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
564 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
565 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
567 /* Transfer complete callback */
568 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
570 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
572 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
573 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
575 /* Disable the MDMA channel */
576 __HAL_MDMA_DISABLE(hqspi->hmdma);
580 /* Change state of QSPI */
581 hqspi->State = HAL_QSPI_STATE_READY;
583 /* TX Complete callback */
584 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
585 hqspi->TxCpltCallback(hqspi);
586 #else
587 HAL_QSPI_TxCpltCallback(hqspi);
588 #endif
590 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
592 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
594 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
595 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
597 /* Disable the MDMA channel */
598 __HAL_MDMA_DISABLE(hqspi->hmdma);
600 else
602 data_reg = &hqspi->Instance->DR;
603 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
605 if (hqspi->RxXferCount > 0U)
607 /* Read the last data received in the FIFO until it is empty */
608 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
609 hqspi->pRxBuffPtr++;
610 hqspi->RxXferCount--;
612 else
614 /* All data have been received for the transfer */
615 break;
621 /* Change state of QSPI */
622 hqspi->State = HAL_QSPI_STATE_READY;
624 /* RX Complete callback */
625 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
626 hqspi->RxCpltCallback(hqspi);
627 #else
628 HAL_QSPI_RxCpltCallback(hqspi);
629 #endif
631 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
633 /* Change state of QSPI */
634 hqspi->State = HAL_QSPI_STATE_READY;
636 /* Command Complete callback */
637 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
638 hqspi->CmdCpltCallback(hqspi);
639 #else
640 HAL_QSPI_CmdCpltCallback(hqspi);
641 #endif
643 else if(hqspi->State == HAL_QSPI_STATE_ABORT)
645 /* Reset functional mode configuration to indirect write mode by default */
646 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
648 /* Change state of QSPI */
649 hqspi->State = HAL_QSPI_STATE_READY;
651 if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
653 /* Abort called by the user */
655 /* Abort Complete callback */
656 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
657 hqspi->AbortCpltCallback(hqspi);
658 #else
659 HAL_QSPI_AbortCpltCallback(hqspi);
660 #endif
662 else
664 /* Abort due to an error (eg : MDMA error) */
666 /* Error callback */
667 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
668 hqspi->ErrorCallback(hqspi);
669 #else
670 HAL_QSPI_ErrorCallback(hqspi);
671 #endif
674 else
676 /* Nothing to do */
680 /* QSPI Status Match interrupt occurred ------------------------------------*/
681 else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
683 /* Clear interrupt */
684 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
686 /* Check if the automatic poll mode stop is activated */
687 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
689 /* Disable the QSPI Transfer Error and Status Match Interrupts */
690 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
692 /* Change state of QSPI */
693 hqspi->State = HAL_QSPI_STATE_READY;
696 /* Status match callback */
697 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
698 hqspi->StatusMatchCallback(hqspi);
699 #else
700 HAL_QSPI_StatusMatchCallback(hqspi);
701 #endif
704 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
705 else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
707 /* Clear interrupt */
708 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
710 /* Disable all the QSPI Interrupts */
711 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
713 /* Set error code */
714 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
716 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
718 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
719 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
721 /* Disable the MDMA channel */
722 hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
723 if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
725 /* Set error code to DMA */
726 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
728 /* Change state of QSPI */
729 hqspi->State = HAL_QSPI_STATE_READY;
731 /* Error callback */
732 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
733 hqspi->ErrorCallback(hqspi);
734 #else
735 HAL_QSPI_ErrorCallback(hqspi);
736 #endif
739 else
741 /* Change state of QSPI */
742 hqspi->State = HAL_QSPI_STATE_READY;
744 /* Error callback */
745 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
746 hqspi->ErrorCallback(hqspi);
747 #else
748 HAL_QSPI_ErrorCallback(hqspi);
749 #endif
753 /* QSPI Timeout interrupt occurred -----------------------------------------*/
754 else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
756 /* Clear interrupt */
757 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
759 /* Timeout callback */
760 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
761 hqspi->TimeOutCallback(hqspi);
762 #else
763 HAL_QSPI_TimeOutCallback(hqspi);
764 #endif
767 else
769 /* Nothing to do */
774 * @brief Set the command configuration.
775 * @param hqspi : QSPI handle
776 * @param cmd : structure that contains the command configuration information
777 * @param Timeout : Timeout duration
778 * @note This function is used only in Indirect Read or Write Modes
779 * @retval HAL status
781 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
783 HAL_StatusTypeDef status;
784 uint32_t tickstart = HAL_GetTick();
786 /* Check the parameters */
787 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
788 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
790 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
793 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
794 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
796 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
799 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
800 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
802 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
805 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
806 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
808 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
809 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
810 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
812 /* Process locked */
813 __HAL_LOCK(hqspi);
815 if(hqspi->State == HAL_QSPI_STATE_READY)
817 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
819 /* Update QSPI state */
820 hqspi->State = HAL_QSPI_STATE_BUSY;
822 /* Wait till BUSY flag reset */
823 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
825 if (status == HAL_OK)
827 /* Call the configuration function */
828 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
830 if (cmd->DataMode == QSPI_DATA_NONE)
832 /* When there is no data phase, the transfer start as soon as the configuration is done
833 so wait until TC flag is set to go back in idle state */
834 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
836 if (status == HAL_OK)
838 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
840 /* Update QSPI state */
841 hqspi->State = HAL_QSPI_STATE_READY;
844 else
846 /* Update QSPI state */
847 hqspi->State = HAL_QSPI_STATE_READY;
851 else
853 status = HAL_BUSY;
856 /* Process unlocked */
857 __HAL_UNLOCK(hqspi);
859 /* Return function status */
860 return status;
864 * @brief Set the command configuration in interrupt mode.
865 * @param hqspi : QSPI handle
866 * @param cmd : structure that contains the command configuration information
867 * @note This function is used only in Indirect Read or Write Modes
868 * @retval HAL status
870 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
872 HAL_StatusTypeDef status;
873 uint32_t tickstart = HAL_GetTick();
875 /* Check the parameters */
876 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
877 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
879 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
882 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
883 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
885 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
888 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
889 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
891 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
894 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
895 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
897 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
898 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
899 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
901 /* Process locked */
902 __HAL_LOCK(hqspi);
904 if(hqspi->State == HAL_QSPI_STATE_READY)
906 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
908 /* Update QSPI state */
909 hqspi->State = HAL_QSPI_STATE_BUSY;
911 /* Wait till BUSY flag reset */
912 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
914 if (status == HAL_OK)
916 if (cmd->DataMode == QSPI_DATA_NONE)
918 /* Clear interrupt */
919 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
922 /* Call the configuration function */
923 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
925 if (cmd->DataMode == QSPI_DATA_NONE)
927 /* When there is no data phase, the transfer start as soon as the configuration is done
928 so activate TC and TE interrupts */
929 /* Process unlocked */
930 __HAL_UNLOCK(hqspi);
932 /* Enable the QSPI Transfer Error Interrupt */
933 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
935 else
937 /* Update QSPI state */
938 hqspi->State = HAL_QSPI_STATE_READY;
940 /* Process unlocked */
941 __HAL_UNLOCK(hqspi);
944 else
946 /* Process unlocked */
947 __HAL_UNLOCK(hqspi);
950 else
952 status = HAL_BUSY;
954 /* Process unlocked */
955 __HAL_UNLOCK(hqspi);
958 /* Return function status */
959 return status;
963 * @brief Transmit an amount of data in blocking mode.
964 * @param hqspi : QSPI handle
965 * @param pData : pointer to data buffer
966 * @param Timeout : Timeout duration
967 * @note This function is used only in Indirect Write Mode
969 * @retval HAL status
971 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
973 HAL_StatusTypeDef status = HAL_OK;
974 uint32_t tickstart = HAL_GetTick();
975 __IO uint32_t *data_reg = &hqspi->Instance->DR;
977 /* Process locked */
978 __HAL_LOCK(hqspi);
980 if(hqspi->State == HAL_QSPI_STATE_READY)
982 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
984 if(pData != NULL )
986 /* Update state */
987 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
989 /* Configure counters and size of the handle */
990 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
991 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
992 hqspi->pTxBuffPtr = pData;
994 /* Configure QSPI: CCR register with functional as indirect write */
995 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
997 while(hqspi->TxXferCount > 0U)
999 /* Wait until FT flag is set to send data */
1000 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
1002 if (status != HAL_OK)
1004 break;
1007 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
1008 hqspi->pTxBuffPtr++;
1009 hqspi->TxXferCount--;
1012 if (status == HAL_OK)
1014 /* Wait until TC flag is set to go back in idle state */
1015 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1017 if (status == HAL_OK)
1019 /* Clear Transfer Complete bit */
1020 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1025 /* Update QSPI state */
1026 hqspi->State = HAL_QSPI_STATE_READY;
1028 else
1030 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1031 status = HAL_ERROR;
1034 else
1036 status = HAL_BUSY;
1039 /* Process unlocked */
1040 __HAL_UNLOCK(hqspi);
1042 return status;
1047 * @brief Receive an amount of data in blocking mode.
1048 * @param hqspi : QSPI handle
1049 * @param pData : pointer to data buffer
1050 * @param Timeout : Timeout duration
1051 * @note This function is used only in Indirect Read Mode
1052 * @retval HAL status
1054 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1056 HAL_StatusTypeDef status = HAL_OK;
1057 uint32_t tickstart = HAL_GetTick();
1058 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1059 __IO uint32_t *data_reg = &hqspi->Instance->DR;
1061 /* Process locked */
1062 __HAL_LOCK(hqspi);
1064 if(hqspi->State == HAL_QSPI_STATE_READY)
1066 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1068 if(pData != NULL )
1070 /* Update state */
1071 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1073 /* Configure counters and size of the handle */
1074 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1075 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1076 hqspi->pRxBuffPtr = pData;
1078 /* Configure QSPI: CCR register with functional as indirect read */
1079 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1081 /* Start the transfer by re-writing the address in AR register */
1082 WRITE_REG(hqspi->Instance->AR, addr_reg);
1084 while(hqspi->RxXferCount > 0U)
1086 /* Wait until FT or TC flag is set to read received data */
1087 status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1089 if (status != HAL_OK)
1091 break;
1094 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
1095 hqspi->pRxBuffPtr++;
1096 hqspi->RxXferCount--;
1099 if (status == HAL_OK)
1101 /* Wait until TC flag is set to go back in idle state */
1102 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1104 if (status == HAL_OK)
1106 /* Clear Transfer Complete bit */
1107 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1112 /* Update QSPI state */
1113 hqspi->State = HAL_QSPI_STATE_READY;
1115 else
1117 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1118 status = HAL_ERROR;
1121 else
1123 status = HAL_BUSY;
1126 /* Process unlocked */
1127 __HAL_UNLOCK(hqspi);
1129 return status;
1133 * @brief Send an amount of data in non-blocking mode with interrupt.
1134 * @param hqspi : QSPI handle
1135 * @param pData : pointer to data buffer
1136 * @note This function is used only in Indirect Write Mode
1137 * @retval HAL status
1139 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1141 HAL_StatusTypeDef status = HAL_OK;
1143 /* Process locked */
1144 __HAL_LOCK(hqspi);
1146 if(hqspi->State == HAL_QSPI_STATE_READY)
1148 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1150 if(pData != NULL )
1152 /* Update state */
1153 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1155 /* Configure counters and size of the handle */
1156 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1157 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1158 hqspi->pTxBuffPtr = pData;
1160 /* Clear interrupt */
1161 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1163 /* Configure QSPI: CCR register with functional as indirect write */
1164 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1166 /* Process unlocked */
1167 __HAL_UNLOCK(hqspi);
1169 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1170 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1172 else
1174 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1175 status = HAL_ERROR;
1177 /* Process unlocked */
1178 __HAL_UNLOCK(hqspi);
1181 else
1183 status = HAL_BUSY;
1185 /* Process unlocked */
1186 __HAL_UNLOCK(hqspi);
1189 return status;
1193 * @brief Receive an amount of data in non-blocking mode with interrupt.
1194 * @param hqspi : QSPI handle
1195 * @param pData : pointer to data buffer
1196 * @note This function is used only in Indirect Read Mode
1197 * @retval HAL status
1199 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1201 HAL_StatusTypeDef status = HAL_OK;
1202 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1204 /* Process locked */
1205 __HAL_LOCK(hqspi);
1207 if(hqspi->State == HAL_QSPI_STATE_READY)
1209 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1211 if(pData != NULL )
1213 /* Update state */
1214 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1216 /* Configure counters and size of the handle */
1217 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1218 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1219 hqspi->pRxBuffPtr = pData;
1221 /* Clear interrupt */
1222 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1224 /* Configure QSPI: CCR register with functional as indirect read */
1225 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1227 /* Start the transfer by re-writing the address in AR register */
1228 WRITE_REG(hqspi->Instance->AR, addr_reg);
1230 /* Process unlocked */
1231 __HAL_UNLOCK(hqspi);
1233 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1234 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1236 else
1238 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1239 status = HAL_ERROR;
1241 /* Process unlocked */
1242 __HAL_UNLOCK(hqspi);
1245 else
1247 status = HAL_BUSY;
1249 /* Process unlocked */
1250 __HAL_UNLOCK(hqspi);
1253 return status;
1257 * @brief Send an amount of data in non-blocking mode with DMA.
1258 * @param hqspi : QSPI handle
1259 * @param pData : pointer to data buffer
1260 * @note This function is used only in Indirect Write Mode
1261 * @retval HAL status
1263 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1265 HAL_StatusTypeDef status = HAL_OK;
1266 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1268 /* Process locked */
1269 __HAL_LOCK(hqspi);
1271 if(hqspi->State == HAL_QSPI_STATE_READY)
1273 /* Clear the error code */
1274 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1276 if(pData != NULL )
1278 /* Configure counters of the handle */
1279 hqspi->TxXferCount = data_size;
1281 /* Update state */
1282 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1284 /* Clear interrupt */
1285 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1287 /* Configure size and pointer of the handle */
1288 hqspi->TxXferSize = hqspi->TxXferCount;
1289 hqspi->pTxBuffPtr = pData;
1291 /* Configure QSPI: CCR register with functional mode as indirect write */
1292 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1294 /* Set the QSPI MDMA transfer complete callback */
1295 hqspi->hmdma->XferCpltCallback = QSPI_DMATxCplt;
1297 /* Set the MDMA error callback */
1298 hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1300 /* Clear the MDMA abort callback */
1301 hqspi->hmdma->XferAbortCallback = NULL;
1303 /* In Transmit mode , the MDMA destination is the QSPI DR register : Force the MDMA Destination Increment to disable */
1304 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE);
1306 /* Update MDMA configuration with the correct SourceInc field for Write operation */
1307 if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
1309 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE);
1311 else if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
1313 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD);
1315 else if (hqspi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
1317 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD);
1319 else
1321 /* in case of incorrect source data size */
1322 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1323 status = HAL_ERROR;
1326 /* Enable the QSPI transmit MDMA */
1327 if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize, 1) == HAL_OK)
1329 /* Process unlocked */
1330 __HAL_UNLOCK(hqspi);
1332 /* Enable the QSPI transfer error Interrupt */
1333 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1335 /* Enable the MDMA transfer by setting the DMAEN bit in the QSPI CR register */
1336 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1338 else
1340 status = HAL_ERROR;
1341 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1342 hqspi->State = HAL_QSPI_STATE_READY;
1344 /* Process unlocked */
1345 __HAL_UNLOCK(hqspi);
1348 else
1350 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1351 status = HAL_ERROR;
1353 /* Process unlocked */
1354 __HAL_UNLOCK(hqspi);
1357 else
1359 status = HAL_BUSY;
1361 /* Process unlocked */
1362 __HAL_UNLOCK(hqspi);
1365 return status;
1369 * @brief Receive an amount of data in non-blocking mode with DMA.
1370 * @param hqspi : QSPI handle
1371 * @param pData : pointer to data buffer.
1372 * @note This function is used only in Indirect Read Mode
1373 * @retval HAL status
1375 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1377 HAL_StatusTypeDef status = HAL_OK;
1378 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1379 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1381 /* Process locked */
1382 __HAL_LOCK(hqspi);
1384 if(hqspi->State == HAL_QSPI_STATE_READY)
1386 /* Clear the error code */
1387 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1389 if(pData != NULL )
1391 /* Configure counters of the handle */
1392 hqspi->RxXferCount = data_size;
1393 /* Update state */
1394 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1396 /* Clear interrupt */
1397 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1399 /* Configure size and pointer of the handle */
1400 hqspi->RxXferSize = hqspi->RxXferCount;
1401 hqspi->pRxBuffPtr = pData;
1403 /* Set the QSPI MDMA transfer complete callback */
1404 hqspi->hmdma->XferCpltCallback = QSPI_DMARxCplt;
1406 /* Set the MDMA error callback */
1407 hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1409 /* Clear the MDMA abort callback */
1410 hqspi->hmdma->XferAbortCallback = NULL;
1412 /* In Receive mode , the MDMA source is the QSPI DR register : Force the MDMA Source Increment to disable */
1413 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE);
1415 /* Update MDMA configuration with the correct DestinationInc field for read operation */
1416 if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
1418 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE);
1420 else if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
1422 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD);
1424 else if (hqspi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
1426 MODIFY_REG(hqspi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD);
1428 else
1430 /* in case of incorrect destination data size */
1431 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1432 status = HAL_ERROR;
1434 /* Configure QSPI: CCR register with functional as indirect read */
1435 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1437 /* Start the transfer by re-writing the address in AR register */
1438 WRITE_REG(hqspi->Instance->AR, addr_reg);
1440 /* Enable the MDMA */
1441 if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize, 1) == HAL_OK)
1443 /* Process unlocked */
1444 __HAL_UNLOCK(hqspi);
1446 /* Enable the QSPI transfer error Interrupt */
1447 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1449 /* Enable the MDMA transfer by setting the DMAEN bit in the QSPI CR register */
1450 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1452 else
1454 status = HAL_ERROR;
1455 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1456 hqspi->State = HAL_QSPI_STATE_READY;
1458 /* Process unlocked */
1459 __HAL_UNLOCK(hqspi);
1462 else
1464 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1465 status = HAL_ERROR;
1467 /* Process unlocked */
1468 __HAL_UNLOCK(hqspi);
1471 else
1473 status = HAL_BUSY;
1475 /* Process unlocked */
1476 __HAL_UNLOCK(hqspi);
1479 return status;
1483 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1484 * @param hqspi : QSPI handle
1485 * @param cmd : structure that contains the command configuration information.
1486 * @param cfg : structure that contains the polling configuration information.
1487 * @param Timeout : Timeout duration
1488 * @note This function is used only in Automatic Polling Mode
1489 * @retval HAL status
1491 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1493 HAL_StatusTypeDef status;
1494 uint32_t tickstart = HAL_GetTick();
1496 /* Check the parameters */
1497 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1498 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1500 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1503 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1504 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1506 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1509 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1510 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1512 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1515 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1516 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1518 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1519 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1520 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1522 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1523 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1524 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1526 /* Process locked */
1527 __HAL_LOCK(hqspi);
1529 if(hqspi->State == HAL_QSPI_STATE_READY)
1531 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1533 /* Update state */
1534 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1536 /* Wait till BUSY flag reset */
1537 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1539 if (status == HAL_OK)
1541 /* Configure QSPI: PSMAR register with the status match value */
1542 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1544 /* Configure QSPI: PSMKR register with the status mask value */
1545 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1547 /* Configure QSPI: PIR register with the interval value */
1548 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1550 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1551 (otherwise there will be an infinite loop in blocking mode) */
1552 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1553 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1555 /* Call the configuration function */
1556 cmd->NbData = cfg->StatusBytesSize;
1557 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1559 /* Wait until SM flag is set to go back in idle state */
1560 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1562 if (status == HAL_OK)
1564 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1566 /* Update state */
1567 hqspi->State = HAL_QSPI_STATE_READY;
1571 else
1573 status = HAL_BUSY;
1576 /* Process unlocked */
1577 __HAL_UNLOCK(hqspi);
1579 /* Return function status */
1580 return status;
1584 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1585 * @param hqspi : QSPI handle
1586 * @param cmd : structure that contains the command configuration information.
1587 * @param cfg : structure that contains the polling configuration information.
1588 * @note This function is used only in Automatic Polling Mode
1589 * @retval HAL status
1591 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1593 HAL_StatusTypeDef status;
1594 uint32_t tickstart = HAL_GetTick();
1596 /* Check the parameters */
1597 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1598 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1600 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1603 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1604 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1606 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1609 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1610 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1612 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1615 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1616 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1618 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1619 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1620 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1622 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1623 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1624 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1625 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1627 /* Process locked */
1628 __HAL_LOCK(hqspi);
1630 if(hqspi->State == HAL_QSPI_STATE_READY)
1632 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1634 /* Update state */
1635 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1637 /* Wait till BUSY flag reset */
1638 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1640 if (status == HAL_OK)
1642 /* Configure QSPI: PSMAR register with the status match value */
1643 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1645 /* Configure QSPI: PSMKR register with the status mask value */
1646 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1648 /* Configure QSPI: PIR register with the interval value */
1649 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1651 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1652 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1653 (cfg->MatchMode | cfg->AutomaticStop));
1655 /* Clear interrupt */
1656 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1658 /* Call the configuration function */
1659 cmd->NbData = cfg->StatusBytesSize;
1660 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1662 /* Process unlocked */
1663 __HAL_UNLOCK(hqspi);
1665 /* Enable the QSPI Transfer Error and status match Interrupt */
1666 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1669 else
1671 /* Process unlocked */
1672 __HAL_UNLOCK(hqspi);
1675 else
1677 status = HAL_BUSY;
1679 /* Process unlocked */
1680 __HAL_UNLOCK(hqspi);
1683 /* Return function status */
1684 return status;
1688 * @brief Configure the Memory Mapped mode.
1689 * @param hqspi : QSPI handle
1690 * @param cmd : structure that contains the command configuration information.
1691 * @param cfg : structure that contains the memory mapped configuration information.
1692 * @note This function is used only in Memory mapped Mode
1693 * @retval HAL status
1695 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1697 HAL_StatusTypeDef status;
1698 uint32_t tickstart = HAL_GetTick();
1700 /* Check the parameters */
1701 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1702 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1704 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1707 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1708 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1710 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1713 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1714 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1716 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1719 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1720 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1722 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1723 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1724 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1726 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1728 /* Process locked */
1729 __HAL_LOCK(hqspi);
1731 if(hqspi->State == HAL_QSPI_STATE_READY)
1733 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1735 /* Update state */
1736 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1738 /* Wait till BUSY flag reset */
1739 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1741 if (status == HAL_OK)
1743 /* Configure QSPI: CR register with timeout counter enable */
1744 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1746 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1748 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1750 /* Configure QSPI: LPTR register with the low-power timeout value */
1751 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1753 /* Clear interrupt */
1754 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1756 /* Enable the QSPI TimeOut Interrupt */
1757 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1760 /* Call the configuration function */
1761 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1764 else
1766 status = HAL_BUSY;
1769 /* Process unlocked */
1770 __HAL_UNLOCK(hqspi);
1772 /* Return function status */
1773 return status;
1777 * @brief Transfer Error callback.
1778 * @param hqspi : QSPI handle
1779 * @retval None
1781 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1783 /* Prevent unused argument(s) compilation warning */
1784 UNUSED(hqspi);
1786 /* NOTE : This function should not be modified, when the callback is needed,
1787 the HAL_QSPI_ErrorCallback could be implemented in the user file
1792 * @brief Abort completed callback.
1793 * @param hqspi : QSPI handle
1794 * @retval None
1796 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1798 /* Prevent unused argument(s) compilation warning */
1799 UNUSED(hqspi);
1801 /* NOTE: This function should not be modified, when the callback is needed,
1802 the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1807 * @brief Command completed callback.
1808 * @param hqspi : QSPI handle
1809 * @retval None
1811 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1813 /* Prevent unused argument(s) compilation warning */
1814 UNUSED(hqspi);
1816 /* NOTE: This function should not be modified, when the callback is needed,
1817 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1822 * @brief Rx Transfer completed callback.
1823 * @param hqspi : QSPI handle
1824 * @retval None
1826 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1828 /* Prevent unused argument(s) compilation warning */
1829 UNUSED(hqspi);
1831 /* NOTE: This function should not be modified, when the callback is needed,
1832 the HAL_QSPI_RxCpltCallback could be implemented in the user file
1837 * @brief Tx Transfer completed callback.
1838 * @param hqspi : QSPI handle
1839 * @retval None
1841 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1843 /* Prevent unused argument(s) compilation warning */
1844 UNUSED(hqspi);
1846 /* NOTE: This function should not be modified, when the callback is needed,
1847 the HAL_QSPI_TxCpltCallback could be implemented in the user file
1853 * @brief FIFO Threshold callback.
1854 * @param hqspi : QSPI handle
1855 * @retval None
1857 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1859 /* Prevent unused argument(s) compilation warning */
1860 UNUSED(hqspi);
1862 /* NOTE : This function should not be modified, when the callback is needed,
1863 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1868 * @brief Status Match callback.
1869 * @param hqspi : QSPI handle
1870 * @retval None
1872 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1874 /* Prevent unused argument(s) compilation warning */
1875 UNUSED(hqspi);
1877 /* NOTE : This function should not be modified, when the callback is needed,
1878 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1883 * @brief Timeout callback.
1884 * @param hqspi : QSPI handle
1885 * @retval None
1887 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1889 /* Prevent unused argument(s) compilation warning */
1890 UNUSED(hqspi);
1892 /* NOTE : This function should not be modified, when the callback is needed,
1893 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1896 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
1898 * @brief Register a User QSPI Callback
1899 * To be used instead of the weak (surcharged) predefined callback
1900 * @param hqspi : QSPI handle
1901 * @param CallbackId : ID of the callback to be registered
1902 * This parameter can be one of the following values:
1903 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
1904 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
1905 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
1906 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
1907 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
1908 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
1909 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
1910 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
1911 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
1912 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
1913 * @param pCallback : pointer to the Callback function
1914 * @retval status
1916 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
1918 HAL_StatusTypeDef status = HAL_OK;
1920 if(pCallback == NULL)
1922 /* Update the error code */
1923 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1924 return HAL_ERROR;
1927 /* Process locked */
1928 __HAL_LOCK(hqspi);
1930 if(hqspi->State == HAL_QSPI_STATE_READY)
1932 switch (CallbackId)
1934 case HAL_QSPI_ERROR_CB_ID :
1935 hqspi->ErrorCallback = pCallback;
1936 break;
1937 case HAL_QSPI_ABORT_CB_ID :
1938 hqspi->AbortCpltCallback = pCallback;
1939 break;
1940 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
1941 hqspi->FifoThresholdCallback = pCallback;
1942 break;
1943 case HAL_QSPI_CMD_CPLT_CB_ID :
1944 hqspi->CmdCpltCallback = pCallback;
1945 break;
1946 case HAL_QSPI_RX_CPLT_CB_ID :
1947 hqspi->RxCpltCallback = pCallback;
1948 break;
1949 case HAL_QSPI_TX_CPLT_CB_ID :
1950 hqspi->TxCpltCallback = pCallback;
1951 break;
1952 case HAL_QSPI_STATUS_MATCH_CB_ID :
1953 hqspi->StatusMatchCallback = pCallback;
1954 break;
1955 case HAL_QSPI_TIMEOUT_CB_ID :
1956 hqspi->TimeOutCallback = pCallback;
1957 break;
1958 case HAL_QSPI_MSP_INIT_CB_ID :
1959 hqspi->MspInitCallback = pCallback;
1960 break;
1961 case HAL_QSPI_MSP_DEINIT_CB_ID :
1962 hqspi->MspDeInitCallback = pCallback;
1963 break;
1964 default :
1965 /* Update the error code */
1966 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1967 /* update return status */
1968 status = HAL_ERROR;
1969 break;
1972 else if (hqspi->State == HAL_QSPI_STATE_RESET)
1974 switch (CallbackId)
1976 case HAL_QSPI_MSP_INIT_CB_ID :
1977 hqspi->MspInitCallback = pCallback;
1978 break;
1979 case HAL_QSPI_MSP_DEINIT_CB_ID :
1980 hqspi->MspDeInitCallback = pCallback;
1981 break;
1982 default :
1983 /* Update the error code */
1984 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1985 /* update return status */
1986 status = HAL_ERROR;
1987 break;
1990 else
1992 /* Update the error code */
1993 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1994 /* update return status */
1995 status = HAL_ERROR;
1998 /* Release Lock */
1999 __HAL_UNLOCK(hqspi);
2000 return status;
2004 * @brief Unregister a User QSPI Callback
2005 * QSPI Callback is redirected to the weak (surcharged) predefined callback
2006 * @param hqspi : QSPI handle
2007 * @param CallbackId : ID of the callback to be unregistered
2008 * This parameter can be one of the following values:
2009 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
2010 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
2011 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2012 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
2013 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
2014 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
2015 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
2016 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
2017 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
2018 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
2019 * @retval status
2021 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2023 HAL_StatusTypeDef status = HAL_OK;
2025 /* Process locked */
2026 __HAL_LOCK(hqspi);
2028 if(hqspi->State == HAL_QSPI_STATE_READY)
2030 switch (CallbackId)
2032 case HAL_QSPI_ERROR_CB_ID :
2033 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2034 break;
2035 case HAL_QSPI_ABORT_CB_ID :
2036 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2037 break;
2038 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2039 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2040 break;
2041 case HAL_QSPI_CMD_CPLT_CB_ID :
2042 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2043 break;
2044 case HAL_QSPI_RX_CPLT_CB_ID :
2045 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2046 break;
2047 case HAL_QSPI_TX_CPLT_CB_ID :
2048 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2049 break;
2050 case HAL_QSPI_STATUS_MATCH_CB_ID :
2051 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2052 break;
2053 case HAL_QSPI_TIMEOUT_CB_ID :
2054 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2055 break;
2056 case HAL_QSPI_MSP_INIT_CB_ID :
2057 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2058 break;
2059 case HAL_QSPI_MSP_DEINIT_CB_ID :
2060 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2061 break;
2062 default :
2063 /* Update the error code */
2064 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2065 /* update return status */
2066 status = HAL_ERROR;
2067 break;
2070 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2072 switch (CallbackId)
2074 case HAL_QSPI_MSP_INIT_CB_ID :
2075 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2076 break;
2077 case HAL_QSPI_MSP_DEINIT_CB_ID :
2078 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2079 break;
2080 default :
2081 /* Update the error code */
2082 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2083 /* update return status */
2084 status = HAL_ERROR;
2085 break;
2088 else
2090 /* Update the error code */
2091 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2092 /* update return status */
2093 status = HAL_ERROR;
2096 /* Release Lock */
2097 __HAL_UNLOCK(hqspi);
2098 return status;
2100 #endif
2103 * @}
2106 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2107 * @brief QSPI control and State functions
2109 @verbatim
2110 ===============================================================================
2111 ##### Peripheral Control and State functions #####
2112 ===============================================================================
2113 [..]
2114 This subsection provides a set of functions allowing to :
2115 (+) Check in run-time the state of the driver.
2116 (+) Check the error code set during last operation.
2117 (+) Abort any operation.
2120 @endverbatim
2121 * @{
2125 * @brief Return the QSPI handle state.
2126 * @param hqspi : QSPI handle
2127 * @retval HAL state
2129 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2131 /* Return QSPI handle state */
2132 return hqspi->State;
2136 * @brief Return the QSPI error code.
2137 * @param hqspi : QSPI handle
2138 * @retval QSPI Error Code
2140 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2142 return hqspi->ErrorCode;
2146 * @brief Abort the current transmission.
2147 * @param hqspi : QSPI handle
2148 * @retval HAL status
2150 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2152 HAL_StatusTypeDef status = HAL_OK;
2153 uint32_t tickstart = HAL_GetTick();
2155 /* Check if the state is in one of the busy states */
2156 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2158 /* Process unlocked */
2159 __HAL_UNLOCK(hqspi);
2161 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2163 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2164 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2166 /* Abort MDMA */
2167 status = HAL_MDMA_Abort(hqspi->hmdma);
2168 if(status != HAL_OK)
2170 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2174 /* Configure QSPI: CR register with Abort request */
2175 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2177 /* Wait until TC flag is set to go back in idle state */
2178 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2180 if (status == HAL_OK)
2182 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2184 /* Wait until BUSY flag is reset */
2185 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2188 if (status == HAL_OK)
2190 /* Reset functional mode configuration to indirect write mode by default */
2191 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2193 /* Update state */
2194 hqspi->State = HAL_QSPI_STATE_READY;
2198 return status;
2202 * @brief Abort the current transmission (non-blocking function)
2203 * @param hqspi : QSPI handle
2204 * @retval HAL status
2206 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2208 HAL_StatusTypeDef status = HAL_OK;
2210 /* Check if the state is in one of the busy states */
2211 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2213 /* Process unlocked */
2214 __HAL_UNLOCK(hqspi);
2216 /* Update QSPI state */
2217 hqspi->State = HAL_QSPI_STATE_ABORT;
2219 /* Disable all interrupts */
2220 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2222 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2224 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2225 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2227 /* Abort MDMA channel */
2228 hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
2229 if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
2231 /* Change state of QSPI */
2232 hqspi->State = HAL_QSPI_STATE_READY;
2234 /* Abort Complete callback */
2235 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2236 hqspi->AbortCpltCallback(hqspi);
2237 #else
2238 HAL_QSPI_AbortCpltCallback(hqspi);
2239 #endif
2242 else
2244 /* Clear interrupt */
2245 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2247 /* Enable the QSPI Transfer Complete Interrupt */
2248 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2250 /* Configure QSPI: CR register with Abort request */
2251 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2254 return status;
2257 /** @brief Set QSPI timeout.
2258 * @param hqspi : QSPI handle.
2259 * @param Timeout : Timeout for the QSPI memory access.
2260 * @retval None
2262 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2264 hqspi->Timeout = Timeout;
2267 /** @brief Set QSPI Fifo threshold.
2268 * @param hqspi : QSPI handle.
2269 * @param Threshold : Threshold of the Fifo (value between 1 and 16).
2270 * @retval HAL status
2272 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2274 HAL_StatusTypeDef status = HAL_OK;
2276 /* Process locked */
2277 __HAL_LOCK(hqspi);
2279 if(hqspi->State == HAL_QSPI_STATE_READY)
2281 /* Synchronize init structure with new FIFO threshold value */
2282 hqspi->Init.FifoThreshold = Threshold;
2284 /* Configure QSPI FIFO Threshold */
2285 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2286 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2288 else
2290 status = HAL_BUSY;
2293 /* Process unlocked */
2294 __HAL_UNLOCK(hqspi);
2296 /* Return function status */
2297 return status;
2300 /** @brief Get QSPI Fifo threshold.
2301 * @param hqspi : QSPI handle.
2302 * @retval Fifo threshold (value between 1 and 16)
2304 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2306 return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2309 /** @brief Set FlashID.
2310 * @param hqspi : QSPI handle.
2311 * @param FlashID : Index of the flash memory to be accessed.
2312 * This parameter can be a value of @ref QSPI_Flash_Select.
2313 * @note The FlashID is ignored when dual flash mode is enabled.
2314 * @retval HAL status
2316 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2318 HAL_StatusTypeDef status = HAL_OK;
2320 /* Check the parameter */
2321 assert_param(IS_QSPI_FLASH_ID(FlashID));
2323 /* Process locked */
2324 __HAL_LOCK(hqspi);
2326 if(hqspi->State == HAL_QSPI_STATE_READY)
2328 /* Synchronize init structure with new FlashID value */
2329 hqspi->Init.FlashID = FlashID;
2331 /* Configure QSPI FlashID */
2332 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2334 else
2336 status = HAL_BUSY;
2339 /* Process unlocked */
2340 __HAL_UNLOCK(hqspi);
2342 /* Return function status */
2343 return status;
2347 * @}
2351 * @}
2354 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2355 * @{
2359 * @brief DMA QSPI receive process complete callback.
2360 * @param hmdma : MDMA handle
2361 * @retval None
2363 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma)
2365 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2366 hqspi->RxXferCount = 0U;
2368 /* Enable the QSPI transfer complete Interrupt */
2369 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2373 * @brief DMA QSPI transmit process complete callback.
2374 * @param hmdma : MDMA handle
2375 * @retval None
2377 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma)
2379 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2380 hqspi->TxXferCount = 0U;
2382 /* Enable the QSPI transfer complete Interrupt */
2383 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2387 * @brief DMA QSPI communication error callback.
2388 * @param hmdma : MDMA handle
2389 * @retval None
2391 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2393 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2395 hqspi->RxXferCount = 0U;
2396 hqspi->TxXferCount = 0U;
2397 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2399 /* Disable the MDMA transfer by clearing the DMAEN bit in the QSPI CR register */
2400 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2402 /* Abort the QSPI */
2403 (void)HAL_QSPI_Abort_IT(hqspi);
2408 * @brief MDMA QSPI abort complete callback.
2409 * @param hmdma : MDMA handle
2410 * @retval None
2412 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2414 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2416 hqspi->RxXferCount = 0U;
2417 hqspi->TxXferCount = 0U;
2419 if(hqspi->State == HAL_QSPI_STATE_ABORT)
2421 /* MDMA Abort called by QSPI abort */
2422 /* Clear interrupt */
2423 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2425 /* Enable the QSPI Transfer Complete Interrupt */
2426 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2428 /* Configure QSPI: CR register with Abort request */
2429 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2431 else
2433 /* MDMA Abort called due to a transfer error interrupt */
2434 /* Change state of QSPI */
2435 hqspi->State = HAL_QSPI_STATE_READY;
2437 /* Error callback */
2438 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2439 hqspi->ErrorCallback(hqspi);
2440 #else
2441 HAL_QSPI_ErrorCallback(hqspi);
2442 #endif
2447 * @brief Wait for a flag state until timeout.
2448 * @param hqspi : QSPI handle
2449 * @param Flag : Flag checked
2450 * @param State : Value of the flag expected
2451 * @param Tickstart : Tick start value
2452 * @param Timeout : Duration of the timeout
2453 * @retval HAL status
2455 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2456 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2458 /* Wait until flag is in expected state */
2459 while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2461 /* Check for the Timeout */
2462 if (Timeout != HAL_MAX_DELAY)
2464 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2466 hqspi->State = HAL_QSPI_STATE_ERROR;
2467 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2469 return HAL_ERROR;
2473 return HAL_OK;
2477 * @brief Configure the communication registers.
2478 * @param hqspi : QSPI handle
2479 * @param cmd : structure that contains the command configuration information
2480 * @param FunctionalMode : functional mode to configured
2481 * This parameter can be one of the following values:
2482 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2483 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2484 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2485 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2486 * @retval None
2488 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2490 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2492 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2494 /* Configure QSPI: DLR register with the number of data to read or write */
2495 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2498 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2500 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2502 /* Configure QSPI: ABR register with alternate bytes value */
2503 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2505 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2507 /*---- Command with instruction, address and alternate bytes ----*/
2508 /* Configure QSPI: CCR register with all communications parameters */
2509 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2510 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2511 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2512 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2513 cmd->Instruction | FunctionalMode));
2515 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2517 /* Configure QSPI: AR register with address value */
2518 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2521 else
2523 /*---- Command with instruction and alternate bytes ----*/
2524 /* Configure QSPI: CCR register with all communications parameters */
2525 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2526 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2527 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2528 cmd->AddressMode | cmd->InstructionMode |
2529 cmd->Instruction | FunctionalMode));
2532 else
2534 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2536 /*---- Command with instruction and address ----*/
2537 /* Configure QSPI: CCR register with all communications parameters */
2538 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2539 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2540 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2541 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2543 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2545 /* Configure QSPI: AR register with address value */
2546 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2549 else
2551 /*---- Command with only instruction ----*/
2552 /* Configure QSPI: CCR register with all communications parameters */
2553 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2554 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2555 cmd->AlternateByteMode | cmd->AddressMode |
2556 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2560 else
2562 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2564 /* Configure QSPI: ABR register with alternate bytes value */
2565 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2567 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2569 /*---- Command with address and alternate bytes ----*/
2570 /* Configure QSPI: CCR register with all communications parameters */
2571 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2572 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2573 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2574 cmd->AddressSize | cmd->AddressMode |
2575 cmd->InstructionMode | FunctionalMode));
2577 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2579 /* Configure QSPI: AR register with address value */
2580 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2583 else
2585 /*---- Command with only alternate bytes ----*/
2586 /* Configure QSPI: CCR register with all communications parameters */
2587 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2588 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2589 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2590 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2593 else
2595 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2597 /*---- Command with only address ----*/
2598 /* Configure QSPI: CCR register with all communications parameters */
2599 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2600 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2601 cmd->AlternateByteMode | cmd->AddressSize |
2602 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2604 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2606 /* Configure QSPI: AR register with address value */
2607 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2610 else
2612 /*---- Command with only data phase ----*/
2613 if (cmd->DataMode != QSPI_DATA_NONE)
2615 /* Configure QSPI: CCR register with all communications parameters */
2616 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2617 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2618 cmd->AlternateByteMode | cmd->AddressMode |
2619 cmd->InstructionMode | FunctionalMode));
2627 * @}
2631 * @}
2634 #endif /* HAL_QSPI_MODULE_ENABLED */
2636 * @}
2640 * @}
2643 #endif /* defined(QUADSPI) */
2645 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/