Moved IO_GPIOPortIdx to platform (#14127)
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_hal_qspi.c
blobe3b705f8e336e89bf5227f039778d1e2338b5f24
1 /**
2 ******************************************************************************
3 * @file stm32g4xx_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 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 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 bit 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
128 (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
130 *** Callback registration ***
131 =============================================
132 [..]
133 The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
134 allows the user to configure dynamically the driver callbacks.
136 Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,
137 it allows to register following callbacks:
138 (+) ErrorCallback : callback when error occurs.
139 (+) AbortCpltCallback : callback when abort is completed.
140 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
141 (+) CmdCpltCallback : callback when a command without data is completed.
142 (+) RxCpltCallback : callback when a reception transfer is completed.
143 (+) TxCpltCallback : callback when a transmission transfer is completed.
144 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
145 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
146 (+) StatusMatchCallback : callback when a status match occurs.
147 (+) TimeOutCallback : callback when the timeout perioed expires.
148 (+) MspInitCallback : QSPI MspInit.
149 (+) MspDeInitCallback : QSPI MspDeInit.
150 This function takes as parameters the HAL peripheral handle, the Callback ID
151 and a pointer to the user callback function.
153 Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default
154 weak (surcharged) function. It allows to reset following callbacks:
155 (+) ErrorCallback : callback when error occurs.
156 (+) AbortCpltCallback : callback when abort is completed.
157 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
158 (+) CmdCpltCallback : callback when a command without data is completed.
159 (+) RxCpltCallback : callback when a reception transfer is completed.
160 (+) TxCpltCallback : callback when a transmission transfer is completed.
161 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
162 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
163 (+) StatusMatchCallback : callback when a status match occurs.
164 (+) TimeOutCallback : callback when the timeout perioed expires.
165 (+) MspInitCallback : QSPI MspInit.
166 (+) MspDeInitCallback : QSPI MspDeInit.
167 This function) takes as parameters the HAL peripheral handle and the Callback ID.
169 By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
170 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
171 Exception done for MspInit and MspDeInit callbacks that are respectively
172 reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init
173 and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
174 If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit
175 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
177 Callbacks can be registered/unregistered in READY state only.
178 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
179 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
180 during the Init/DeInit.
181 In that case first register the MspInit/MspDeInit user callbacks
182 using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
183 or @ref HAL_QSPI_Init function.
185 When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
186 not defined, the callback registering feature is not available
187 and weak (surcharged) callbacks are used.
189 *** Workarounds linked to Silicon Limitation ***
190 ====================================================
191 [..]
192 (#) Workarounds Implemented inside HAL Driver
193 (++) Extra data written in the FIFO at the end of a read transfer
195 @endverbatim
196 ******************************************************************************
197 * @attention
199 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
200 * All rights reserved.</center></h2>
202 * This software component is licensed by ST under BSD 3-Clause license,
203 * the "License"; You may not use this file except in compliance with the
204 * License. You may obtain a copy of the License at:
205 * opensource.org/licenses/BSD-3-Clause
207 ******************************************************************************
210 /* Includes ------------------------------------------------------------------*/
211 #include "stm32g4xx_hal.h"
213 #if defined(QUADSPI)
215 /** @addtogroup STM32G4xx_HAL_Driver
216 * @{
219 /** @defgroup QSPI QSPI
220 * @brief QSPI HAL module driver
221 * @{
223 #ifdef HAL_QSPI_MODULE_ENABLED
225 /* Private typedef -----------------------------------------------------------*/
227 /* Private define ------------------------------------------------------------*/
228 /** @defgroup QSPI_Private_Constants QSPI Private Constants
229 * @{
231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
232 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
233 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
234 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
236 * @}
239 /* Private macro -------------------------------------------------------------*/
240 /** @defgroup QSPI_Private_Macros QSPI Private Macros
241 * @{
243 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
244 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
245 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
246 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
248 * @}
251 /* Private variables ---------------------------------------------------------*/
253 /* Private function prototypes -----------------------------------------------*/
254 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
255 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
256 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
257 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
258 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
259 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
260 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
261 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
263 /* Exported functions --------------------------------------------------------*/
265 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
266 * @{
269 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
270 * @brief Initialization and Configuration functions
272 @verbatim
273 ===============================================================================
274 ##### Initialization and Configuration functions #####
275 ===============================================================================
276 [..]
277 This subsection provides a set of functions allowing to :
278 (+) Initialize the QuadSPI.
279 (+) De-initialize the QuadSPI.
281 @endverbatim
282 * @{
286 * @brief Initialize the QSPI mode according to the specified parameters
287 * in the QSPI_InitTypeDef and initialize the associated handle.
288 * @param hqspi : QSPI handle
289 * @retval HAL status
291 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
293 HAL_StatusTypeDef status;
294 uint32_t tickstart = HAL_GetTick();
296 /* Check the QSPI handle allocation */
297 if(hqspi == NULL)
299 return HAL_ERROR;
302 /* Check the parameters */
303 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
304 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
305 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
306 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
307 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
308 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
309 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
310 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
312 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
314 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
317 /* Process locked */
318 __HAL_LOCK(hqspi);
320 if(hqspi->State == HAL_QSPI_STATE_RESET)
322 /* Allocate lock resource and initialize it */
323 hqspi->Lock = HAL_UNLOCKED;
325 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
326 /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
327 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
328 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
329 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
330 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
331 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
332 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
333 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
334 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
335 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
336 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
338 if(hqspi->MspInitCallback == NULL)
340 hqspi->MspInitCallback = HAL_QSPI_MspInit;
343 /* Init the low level hardware */
344 hqspi->MspInitCallback(hqspi);
345 #else
346 /* Init the low level hardware : GPIO, CLOCK */
347 HAL_QSPI_MspInit(hqspi);
348 #endif
350 /* Configure the default timeout for the QSPI memory access */
351 HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
354 /* Configure QSPI FIFO Threshold */
355 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
356 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
358 /* Wait till BUSY flag reset */
359 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
361 if(status == HAL_OK)
363 /* Configure QSPI Clock Prescaler and Sample Shift */
364 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
365 ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
366 hqspi->Init.SampleShifting | hqspi->Init.FlashID | hqspi->Init.DualFlash));
368 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
369 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
370 ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
371 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
373 /* Enable the QSPI peripheral */
374 __HAL_QSPI_ENABLE(hqspi);
376 /* Set QSPI error code to none */
377 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
379 /* Initialize the QSPI state */
380 hqspi->State = HAL_QSPI_STATE_READY;
383 /* Release Lock */
384 __HAL_UNLOCK(hqspi);
386 /* Return function status */
387 return status;
391 * @brief De-Initialize the QSPI peripheral.
392 * @param hqspi : QSPI handle
393 * @retval HAL status
395 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
397 /* Check the QSPI handle allocation */
398 if(hqspi == NULL)
400 return HAL_ERROR;
403 /* Process locked */
404 __HAL_LOCK(hqspi);
406 /* Disable the QSPI Peripheral Clock */
407 __HAL_QSPI_DISABLE(hqspi);
409 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
410 if(hqspi->MspDeInitCallback == NULL)
412 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
415 /* DeInit the low level hardware */
416 hqspi->MspDeInitCallback(hqspi);
417 #else
418 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
419 HAL_QSPI_MspDeInit(hqspi);
420 #endif
422 /* Set QSPI error code to none */
423 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
425 /* Initialize the QSPI state */
426 hqspi->State = HAL_QSPI_STATE_RESET;
428 /* Release Lock */
429 __HAL_UNLOCK(hqspi);
431 return HAL_OK;
435 * @brief Initialize the QSPI MSP.
436 * @param hqspi : QSPI handle
437 * @retval None
439 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
441 /* Prevent unused argument(s) compilation warning */
442 UNUSED(hqspi);
444 /* NOTE : This function should not be modified, when the callback is needed,
445 the HAL_QSPI_MspInit can be implemented in the user file
450 * @brief DeInitialize the QSPI MSP.
451 * @param hqspi : QSPI handle
452 * @retval None
454 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
456 /* Prevent unused argument(s) compilation warning */
457 UNUSED(hqspi);
459 /* NOTE : This function should not be modified, when the callback is needed,
460 the HAL_QSPI_MspDeInit can be implemented in the user file
465 * @}
468 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
469 * @brief QSPI Transmit/Receive functions
471 @verbatim
472 ===============================================================================
473 ##### IO operation functions #####
474 ===============================================================================
475 [..]
476 This subsection provides a set of functions allowing to :
477 (+) Handle the interrupts.
478 (+) Handle the command sequence.
479 (+) Transmit data in blocking, interrupt or DMA mode.
480 (+) Receive data in blocking, interrupt or DMA mode.
481 (+) Manage the auto-polling functional mode.
482 (+) Manage the memory-mapped functional mode.
484 @endverbatim
485 * @{
489 * @brief Handle QSPI interrupt request.
490 * @param hqspi : QSPI handle
491 * @retval None
493 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
495 __IO uint32_t *data_reg;
496 uint32_t flag = READ_REG(hqspi->Instance->SR);
497 uint32_t itsource = READ_REG(hqspi->Instance->CR);
499 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
500 if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
502 data_reg = &hqspi->Instance->DR;
504 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
506 /* Transmission process */
507 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
509 if (hqspi->TxXferCount > 0U)
511 /* Fill the FIFO until the threshold is reached */
512 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
513 hqspi->pTxBuffPtr++;
514 hqspi->TxXferCount--;
516 else
518 /* No more data available for the transfer */
519 /* Disable the QSPI FIFO Threshold Interrupt */
520 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
521 break;
525 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
527 /* Receiving Process */
528 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
530 if (hqspi->RxXferCount > 0U)
532 /* Read the FIFO until the threshold is reached */
533 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
534 hqspi->pRxBuffPtr++;
535 hqspi->RxXferCount--;
537 else
539 /* All data have been received for the transfer */
540 /* Disable the QSPI FIFO Threshold Interrupt */
541 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
542 break;
546 else
548 /* Nothing to do */
551 /* FIFO Threshold callback */
552 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
553 hqspi->FifoThresholdCallback(hqspi);
554 #else
555 HAL_QSPI_FifoThresholdCallback(hqspi);
556 #endif
559 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
560 else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
562 /* Clear interrupt */
563 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
565 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
566 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
568 /* Transfer complete callback */
569 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
571 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
573 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
574 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
576 /* Disable the DMA channel */
577 __HAL_DMA_DISABLE(hqspi->hdma);
581 /* Change state of QSPI */
582 hqspi->State = HAL_QSPI_STATE_READY;
584 /* TX Complete callback */
585 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
586 hqspi->TxCpltCallback(hqspi);
587 #else
588 HAL_QSPI_TxCpltCallback(hqspi);
589 #endif
591 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
593 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
595 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
596 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
598 /* Disable the DMA channel */
599 __HAL_DMA_DISABLE(hqspi->hdma);
601 else
603 data_reg = &hqspi->Instance->DR;
604 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
606 if (hqspi->RxXferCount > 0U)
608 /* Read the last data received in the FIFO until it is empty */
609 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
610 hqspi->pRxBuffPtr++;
611 hqspi->RxXferCount--;
613 else
615 /* All data have been received for the transfer */
616 break;
622 /* Change state of QSPI */
623 hqspi->State = HAL_QSPI_STATE_READY;
625 /* RX Complete callback */
626 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
627 hqspi->RxCpltCallback(hqspi);
628 #else
629 HAL_QSPI_RxCpltCallback(hqspi);
630 #endif
632 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
634 /* Change state of QSPI */
635 hqspi->State = HAL_QSPI_STATE_READY;
637 /* Command Complete callback */
638 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
639 hqspi->CmdCpltCallback(hqspi);
640 #else
641 HAL_QSPI_CmdCpltCallback(hqspi);
642 #endif
644 else if(hqspi->State == HAL_QSPI_STATE_ABORT)
646 /* Reset functional mode configuration to indirect write mode by default */
647 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
649 /* Change state of QSPI */
650 hqspi->State = HAL_QSPI_STATE_READY;
652 if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
654 /* Abort called by the user */
656 /* Abort Complete callback */
657 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
658 hqspi->AbortCpltCallback(hqspi);
659 #else
660 HAL_QSPI_AbortCpltCallback(hqspi);
661 #endif
663 else
665 /* Abort due to an error (eg : DMA error) */
667 /* Error callback */
668 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
669 hqspi->ErrorCallback(hqspi);
670 #else
671 HAL_QSPI_ErrorCallback(hqspi);
672 #endif
675 else
677 /* Nothing to do */
681 /* QSPI Status Match interrupt occurred ------------------------------------*/
682 else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
684 /* Clear interrupt */
685 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
687 /* Check if the automatic poll mode stop is activated */
688 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
690 /* Disable the QSPI Transfer Error and Status Match Interrupts */
691 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
693 /* Change state of QSPI */
694 hqspi->State = HAL_QSPI_STATE_READY;
697 /* Status match callback */
698 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
699 hqspi->StatusMatchCallback(hqspi);
700 #else
701 HAL_QSPI_StatusMatchCallback(hqspi);
702 #endif
705 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
706 else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
708 /* Clear interrupt */
709 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
711 /* Disable all the QSPI Interrupts */
712 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
714 /* Set error code */
715 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
717 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
719 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
720 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
722 /* Disable the DMA channel */
723 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
724 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
726 /* Set error code to DMA */
727 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
729 /* Change state of QSPI */
730 hqspi->State = HAL_QSPI_STATE_READY;
732 /* Error callback */
733 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
734 hqspi->ErrorCallback(hqspi);
735 #else
736 HAL_QSPI_ErrorCallback(hqspi);
737 #endif
740 else
742 /* Change state of QSPI */
743 hqspi->State = HAL_QSPI_STATE_READY;
745 /* Error callback */
746 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
747 hqspi->ErrorCallback(hqspi);
748 #else
749 HAL_QSPI_ErrorCallback(hqspi);
750 #endif
754 /* QSPI Timeout interrupt occurred -----------------------------------------*/
755 else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
757 /* Clear interrupt */
758 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
760 /* Timeout callback */
761 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
762 hqspi->TimeOutCallback(hqspi);
763 #else
764 HAL_QSPI_TimeOutCallback(hqspi);
765 #endif
768 else
770 /* Nothing to do */
775 * @brief Set the command configuration.
776 * @param hqspi : QSPI handle
777 * @param cmd : structure that contains the command configuration information
778 * @param Timeout : Timeout duration
779 * @note This function is used only in Indirect Read or Write Modes
780 * @retval HAL status
782 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
784 HAL_StatusTypeDef status;
785 uint32_t tickstart = HAL_GetTick();
787 /* Check the parameters */
788 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
789 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
791 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
794 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
795 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
797 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
800 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
801 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
803 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
806 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
807 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
809 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
810 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
811 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
813 /* Process locked */
814 __HAL_LOCK(hqspi);
816 if(hqspi->State == HAL_QSPI_STATE_READY)
818 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
820 /* Update QSPI state */
821 hqspi->State = HAL_QSPI_STATE_BUSY;
823 /* Wait till BUSY flag reset */
824 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
826 if (status == HAL_OK)
828 /* Call the configuration function */
829 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
831 if (cmd->DataMode == QSPI_DATA_NONE)
833 /* When there is no data phase, the transfer start as soon as the configuration is done
834 so wait until TC flag is set to go back in idle state */
835 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
837 if (status == HAL_OK)
839 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
841 /* Update QSPI state */
842 hqspi->State = HAL_QSPI_STATE_READY;
845 else
847 /* Update QSPI state */
848 hqspi->State = HAL_QSPI_STATE_READY;
852 else
854 status = HAL_BUSY;
857 /* Process unlocked */
858 __HAL_UNLOCK(hqspi);
860 /* Return function status */
861 return status;
865 * @brief Set the command configuration in interrupt mode.
866 * @param hqspi : QSPI handle
867 * @param cmd : structure that contains the command configuration information
868 * @note This function is used only in Indirect Read or Write Modes
869 * @retval HAL status
871 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
873 HAL_StatusTypeDef status;
874 uint32_t tickstart = HAL_GetTick();
876 /* Check the parameters */
877 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
878 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
880 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
883 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
884 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
886 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
889 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
890 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
892 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
895 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
896 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
898 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
899 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
900 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
902 /* Process locked */
903 __HAL_LOCK(hqspi);
905 if(hqspi->State == HAL_QSPI_STATE_READY)
907 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
909 /* Update QSPI state */
910 hqspi->State = HAL_QSPI_STATE_BUSY;
912 /* Wait till BUSY flag reset */
913 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
915 if (status == HAL_OK)
917 if (cmd->DataMode == QSPI_DATA_NONE)
919 /* Clear interrupt */
920 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
923 /* Call the configuration function */
924 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
926 if (cmd->DataMode == QSPI_DATA_NONE)
928 /* When there is no data phase, the transfer start as soon as the configuration is done
929 so activate TC and TE interrupts */
930 /* Process unlocked */
931 __HAL_UNLOCK(hqspi);
933 /* Enable the QSPI Transfer Error Interrupt */
934 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
936 else
938 /* Update QSPI state */
939 hqspi->State = HAL_QSPI_STATE_READY;
941 /* Process unlocked */
942 __HAL_UNLOCK(hqspi);
945 else
947 /* Process unlocked */
948 __HAL_UNLOCK(hqspi);
951 else
953 status = HAL_BUSY;
955 /* Process unlocked */
956 __HAL_UNLOCK(hqspi);
959 /* Return function status */
960 return status;
964 * @brief Transmit an amount of data in blocking mode.
965 * @param hqspi : QSPI handle
966 * @param pData : pointer to data buffer
967 * @param Timeout : Timeout duration
968 * @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 * @note If DMA peripheral access is configured as halfword, the number
1262 * of data and the fifo threshold should be aligned on halfword
1263 * @note If DMA peripheral access is configured as word, the number
1264 * of data and the fifo threshold should be aligned on word
1265 * @retval HAL status
1267 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1269 HAL_StatusTypeDef status = HAL_OK;
1270 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1272 /* Process locked */
1273 __HAL_LOCK(hqspi);
1275 if(hqspi->State == HAL_QSPI_STATE_READY)
1277 /* Clear the error code */
1278 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1280 if(pData != NULL )
1282 /* Configure counters of the handle */
1283 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1285 hqspi->TxXferCount = data_size;
1287 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1289 if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1291 /* The number of data or the fifo threshold is not aligned on halfword
1292 => no transfer possible with DMA peripheral access configured as halfword */
1293 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1294 status = HAL_ERROR;
1296 /* Process unlocked */
1297 __HAL_UNLOCK(hqspi);
1299 else
1301 hqspi->TxXferCount = (data_size >> 1U);
1304 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1306 if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1308 /* The number of data or the fifo threshold is not aligned on word
1309 => no transfer possible with DMA peripheral access configured as word */
1310 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1311 status = HAL_ERROR;
1313 /* Process unlocked */
1314 __HAL_UNLOCK(hqspi);
1316 else
1318 hqspi->TxXferCount = (data_size >> 2U);
1321 else
1323 /* Nothing to do */
1326 if (status == HAL_OK)
1328 /* Update state */
1329 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1331 /* Clear interrupt */
1332 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1334 /* Configure size and pointer of the handle */
1335 hqspi->TxXferSize = hqspi->TxXferCount;
1336 hqspi->pTxBuffPtr = pData;
1338 /* Configure QSPI: CCR register with functional mode as indirect write */
1339 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1341 /* Set the QSPI DMA transfer complete callback */
1342 hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
1344 /* Set the QSPI DMA Half transfer complete callback */
1345 hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
1347 /* Set the DMA error callback */
1348 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1350 /* Clear the DMA abort callback */
1351 hqspi->hdma->XferAbortCallback = NULL;
1353 /* Configure the direction of the DMA */
1354 hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1355 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
1357 /* Enable the QSPI transmit DMA Channel */
1358 if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
1360 /* Process unlocked */
1361 __HAL_UNLOCK(hqspi);
1363 /* Enable the QSPI transfer error Interrupt */
1364 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1366 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1367 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1369 else
1371 status = HAL_ERROR;
1372 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1373 hqspi->State = HAL_QSPI_STATE_READY;
1375 /* Process unlocked */
1376 __HAL_UNLOCK(hqspi);
1380 else
1382 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1383 status = HAL_ERROR;
1385 /* Process unlocked */
1386 __HAL_UNLOCK(hqspi);
1389 else
1391 status = HAL_BUSY;
1393 /* Process unlocked */
1394 __HAL_UNLOCK(hqspi);
1397 return status;
1401 * @brief Receive an amount of data in non-blocking mode with DMA.
1402 * @param hqspi : QSPI handle
1403 * @param pData : pointer to data buffer.
1404 * @note This function is used only in Indirect Read Mode
1405 * @note If DMA peripheral access is configured as halfword, the number
1406 * of data and the fifo threshold should be aligned on halfword
1407 * @note If DMA peripheral access is configured as word, the number
1408 * of data and the fifo threshold should be aligned on word
1409 * @retval HAL status
1411 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1413 HAL_StatusTypeDef status = HAL_OK;
1414 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1415 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1417 /* Process locked */
1418 __HAL_LOCK(hqspi);
1420 if(hqspi->State == HAL_QSPI_STATE_READY)
1422 /* Clear the error code */
1423 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1425 if(pData != NULL )
1427 /* Configure counters of the handle */
1428 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1430 hqspi->RxXferCount = data_size;
1432 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1434 if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
1436 /* The number of data or the fifo threshold is not aligned on halfword
1437 => no transfer possible with DMA peripheral access configured as halfword */
1438 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1439 status = HAL_ERROR;
1441 /* Process unlocked */
1442 __HAL_UNLOCK(hqspi);
1444 else
1446 hqspi->RxXferCount = (data_size >> 1U);
1449 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1451 if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
1453 /* The number of data or the fifo threshold is not aligned on word
1454 => no transfer possible with DMA peripheral access configured as word */
1455 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1456 status = HAL_ERROR;
1458 /* Process unlocked */
1459 __HAL_UNLOCK(hqspi);
1461 else
1463 hqspi->RxXferCount = (data_size >> 2U);
1466 else
1468 /* Nothing to do */
1471 if (status == HAL_OK)
1473 /* Update state */
1474 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1476 /* Clear interrupt */
1477 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1479 /* Configure size and pointer of the handle */
1480 hqspi->RxXferSize = hqspi->RxXferCount;
1481 hqspi->pRxBuffPtr = pData;
1483 /* Set the QSPI DMA transfer complete callback */
1484 hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
1486 /* Set the QSPI DMA Half transfer complete callback */
1487 hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
1489 /* Set the DMA error callback */
1490 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1492 /* Clear the DMA abort callback */
1493 hqspi->hdma->XferAbortCallback = NULL;
1495 /* Configure the direction of the DMA */
1496 hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1497 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
1499 /* Enable the DMA Channel */
1500 if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
1502 /* Configure QSPI: CCR register with functional as indirect read */
1503 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1505 /* Start the transfer by re-writing the address in AR register */
1506 WRITE_REG(hqspi->Instance->AR, addr_reg);
1508 /* Process unlocked */
1509 __HAL_UNLOCK(hqspi);
1511 /* Enable the QSPI transfer error Interrupt */
1512 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1514 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1515 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1517 else
1519 status = HAL_ERROR;
1520 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1521 hqspi->State = HAL_QSPI_STATE_READY;
1523 /* Process unlocked */
1524 __HAL_UNLOCK(hqspi);
1528 else
1530 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1531 status = HAL_ERROR;
1533 /* Process unlocked */
1534 __HAL_UNLOCK(hqspi);
1537 else
1539 status = HAL_BUSY;
1541 /* Process unlocked */
1542 __HAL_UNLOCK(hqspi);
1545 return status;
1549 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1550 * @param hqspi : QSPI handle
1551 * @param cmd : structure that contains the command configuration information.
1552 * @param cfg : structure that contains the polling configuration information.
1553 * @param Timeout : Timeout duration
1554 * @note This function is used only in Automatic Polling Mode
1555 * @retval HAL status
1557 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1559 HAL_StatusTypeDef status;
1560 uint32_t tickstart = HAL_GetTick();
1562 /* Check the parameters */
1563 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1564 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1566 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1569 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1570 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1572 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1575 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1576 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1578 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1581 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1582 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1584 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1585 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1586 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1588 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1589 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1590 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1592 /* Process locked */
1593 __HAL_LOCK(hqspi);
1595 if(hqspi->State == HAL_QSPI_STATE_READY)
1597 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1599 /* Update state */
1600 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1602 /* Wait till BUSY flag reset */
1603 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1605 if (status == HAL_OK)
1607 /* Configure QSPI: PSMAR register with the status match value */
1608 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1610 /* Configure QSPI: PSMKR register with the status mask value */
1611 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1613 /* Configure QSPI: PIR register with the interval value */
1614 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1616 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1617 (otherwise there will be an infinite loop in blocking mode) */
1618 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1619 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1621 /* Call the configuration function */
1622 cmd->NbData = cfg->StatusBytesSize;
1623 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1625 /* Wait until SM flag is set to go back in idle state */
1626 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1628 if (status == HAL_OK)
1630 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1632 /* Update state */
1633 hqspi->State = HAL_QSPI_STATE_READY;
1637 else
1639 status = HAL_BUSY;
1642 /* Process unlocked */
1643 __HAL_UNLOCK(hqspi);
1645 /* Return function status */
1646 return status;
1650 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1651 * @param hqspi : QSPI handle
1652 * @param cmd : structure that contains the command configuration information.
1653 * @param cfg : structure that contains the polling configuration information.
1654 * @note This function is used only in Automatic Polling Mode
1655 * @retval HAL status
1657 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1659 HAL_StatusTypeDef status;
1660 uint32_t tickstart = HAL_GetTick();
1662 /* Check the parameters */
1663 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1664 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1666 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1669 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1670 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1672 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1675 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1676 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1678 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1681 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1682 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1684 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1685 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1686 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1688 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1689 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1690 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1691 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1693 /* Process locked */
1694 __HAL_LOCK(hqspi);
1696 if(hqspi->State == HAL_QSPI_STATE_READY)
1698 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1700 /* Update state */
1701 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1703 /* Wait till BUSY flag reset */
1704 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1706 if (status == HAL_OK)
1708 /* Configure QSPI: PSMAR register with the status match value */
1709 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1711 /* Configure QSPI: PSMKR register with the status mask value */
1712 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1714 /* Configure QSPI: PIR register with the interval value */
1715 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1717 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1718 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1719 (cfg->MatchMode | cfg->AutomaticStop));
1721 /* Clear interrupt */
1722 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1724 /* Call the configuration function */
1725 cmd->NbData = cfg->StatusBytesSize;
1726 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1728 /* Process unlocked */
1729 __HAL_UNLOCK(hqspi);
1731 /* Enable the QSPI Transfer Error and status match Interrupt */
1732 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1735 else
1737 /* Process unlocked */
1738 __HAL_UNLOCK(hqspi);
1741 else
1743 status = HAL_BUSY;
1745 /* Process unlocked */
1746 __HAL_UNLOCK(hqspi);
1749 /* Return function status */
1750 return status;
1754 * @brief Configure the Memory Mapped mode.
1755 * @param hqspi : QSPI handle
1756 * @param cmd : structure that contains the command configuration information.
1757 * @param cfg : structure that contains the memory mapped configuration information.
1758 * @note This function is used only in Memory mapped Mode
1759 * @retval HAL status
1761 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1763 HAL_StatusTypeDef status;
1764 uint32_t tickstart = HAL_GetTick();
1766 /* Check the parameters */
1767 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1768 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1770 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1773 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1774 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1776 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1779 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1780 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1782 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1785 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1786 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1788 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1789 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1790 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1792 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1794 /* Process locked */
1795 __HAL_LOCK(hqspi);
1797 if(hqspi->State == HAL_QSPI_STATE_READY)
1799 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1801 /* Update state */
1802 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1804 /* Wait till BUSY flag reset */
1805 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1807 if (status == HAL_OK)
1809 /* Configure QSPI: CR register with timeout counter enable */
1810 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1812 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1814 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1816 /* Configure QSPI: LPTR register with the low-power timeout value */
1817 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1819 /* Clear interrupt */
1820 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1822 /* Enable the QSPI TimeOut Interrupt */
1823 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1826 /* Call the configuration function */
1827 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1830 else
1832 status = HAL_BUSY;
1835 /* Process unlocked */
1836 __HAL_UNLOCK(hqspi);
1838 /* Return function status */
1839 return status;
1843 * @brief Transfer Error callback.
1844 * @param hqspi : QSPI handle
1845 * @retval None
1847 __weak void HAL_QSPI_ErrorCallback(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_ErrorCallback could be implemented in the user file
1858 * @brief Abort completed callback.
1859 * @param hqspi : QSPI handle
1860 * @retval None
1862 __weak void HAL_QSPI_AbortCpltCallback(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_AbortCpltCallback could be implemented in the user file
1873 * @brief Command completed callback.
1874 * @param hqspi : QSPI handle
1875 * @retval None
1877 __weak void HAL_QSPI_CmdCpltCallback(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_CmdCpltCallback could be implemented in the user file
1888 * @brief Rx Transfer completed callback.
1889 * @param hqspi : QSPI handle
1890 * @retval None
1892 __weak void HAL_QSPI_RxCpltCallback(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_RxCpltCallback could be implemented in the user file
1903 * @brief Tx Transfer completed callback.
1904 * @param hqspi : QSPI handle
1905 * @retval None
1907 __weak void HAL_QSPI_TxCpltCallback(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_TxCpltCallback could be implemented in the user file
1918 * @brief Rx Half Transfer completed callback.
1919 * @param hqspi : QSPI handle
1920 * @retval None
1922 __weak void HAL_QSPI_RxHalfCpltCallback(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_RxHalfCpltCallback could be implemented in the user file
1933 * @brief Tx Half Transfer completed callback.
1934 * @param hqspi : QSPI handle
1935 * @retval None
1937 __weak void HAL_QSPI_TxHalfCpltCallback(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_TxHalfCpltCallback could be implemented in the user file
1948 * @brief FIFO Threshold callback.
1949 * @param hqspi : QSPI handle
1950 * @retval None
1952 __weak void HAL_QSPI_FifoThresholdCallback(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_FIFOThresholdCallback could be implemented in the user file
1963 * @brief Status Match callback.
1964 * @param hqspi : QSPI handle
1965 * @retval None
1967 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1969 /* Prevent unused argument(s) compilation warning */
1970 UNUSED(hqspi);
1972 /* NOTE : This function should not be modified, when the callback is needed,
1973 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1978 * @brief Timeout callback.
1979 * @param hqspi : QSPI handle
1980 * @retval None
1982 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1984 /* Prevent unused argument(s) compilation warning */
1985 UNUSED(hqspi);
1987 /* NOTE : This function should not be modified, when the callback is needed,
1988 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1991 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
1993 * @brief Register a User QSPI Callback
1994 * To be used instead of the weak (surcharged) predefined callback
1995 * @param hqspi : QSPI handle
1996 * @param CallbackId : ID of the callback to be registered
1997 * This parameter can be one of the following values:
1998 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
1999 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
2000 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2001 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
2002 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
2003 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
2004 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
2005 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
2006 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
2007 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
2008 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
2009 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
2010 * @param pCallback : pointer to the Callback function
2011 * @retval status
2013 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
2015 HAL_StatusTypeDef status = HAL_OK;
2017 if(pCallback == NULL)
2019 /* Update the error code */
2020 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2021 return HAL_ERROR;
2024 /* Process locked */
2025 __HAL_LOCK(hqspi);
2027 if(hqspi->State == HAL_QSPI_STATE_READY)
2029 switch (CallbackId)
2031 case HAL_QSPI_ERROR_CB_ID :
2032 hqspi->ErrorCallback = pCallback;
2033 break;
2034 case HAL_QSPI_ABORT_CB_ID :
2035 hqspi->AbortCpltCallback = pCallback;
2036 break;
2037 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2038 hqspi->FifoThresholdCallback = pCallback;
2039 break;
2040 case HAL_QSPI_CMD_CPLT_CB_ID :
2041 hqspi->CmdCpltCallback = pCallback;
2042 break;
2043 case HAL_QSPI_RX_CPLT_CB_ID :
2044 hqspi->RxCpltCallback = pCallback;
2045 break;
2046 case HAL_QSPI_TX_CPLT_CB_ID :
2047 hqspi->TxCpltCallback = pCallback;
2048 break;
2049 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2050 hqspi->RxHalfCpltCallback = pCallback;
2051 break;
2052 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2053 hqspi->TxHalfCpltCallback = pCallback;
2054 break;
2055 case HAL_QSPI_STATUS_MATCH_CB_ID :
2056 hqspi->StatusMatchCallback = pCallback;
2057 break;
2058 case HAL_QSPI_TIMEOUT_CB_ID :
2059 hqspi->TimeOutCallback = pCallback;
2060 break;
2061 case HAL_QSPI_MSP_INIT_CB_ID :
2062 hqspi->MspInitCallback = pCallback;
2063 break;
2064 case HAL_QSPI_MSP_DEINIT_CB_ID :
2065 hqspi->MspDeInitCallback = pCallback;
2066 break;
2067 default :
2068 /* Update the error code */
2069 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2070 /* update return status */
2071 status = HAL_ERROR;
2072 break;
2075 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2077 switch (CallbackId)
2079 case HAL_QSPI_MSP_INIT_CB_ID :
2080 hqspi->MspInitCallback = pCallback;
2081 break;
2082 case HAL_QSPI_MSP_DEINIT_CB_ID :
2083 hqspi->MspDeInitCallback = pCallback;
2084 break;
2085 default :
2086 /* Update the error code */
2087 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2088 /* update return status */
2089 status = HAL_ERROR;
2090 break;
2093 else
2095 /* Update the error code */
2096 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2097 /* update return status */
2098 status = HAL_ERROR;
2101 /* Release Lock */
2102 __HAL_UNLOCK(hqspi);
2103 return status;
2107 * @brief Unregister a User QSPI Callback
2108 * QSPI Callback is redirected to the weak (surcharged) predefined callback
2109 * @param hqspi : QSPI handle
2110 * @param CallbackId : ID of the callback to be unregistered
2111 * This parameter can be one of the following values:
2112 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
2113 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
2114 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2115 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
2116 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
2117 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
2118 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
2119 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
2120 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
2121 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
2122 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
2123 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
2124 * @retval status
2126 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2128 HAL_StatusTypeDef status = HAL_OK;
2130 /* Process locked */
2131 __HAL_LOCK(hqspi);
2133 if(hqspi->State == HAL_QSPI_STATE_READY)
2135 switch (CallbackId)
2137 case HAL_QSPI_ERROR_CB_ID :
2138 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2139 break;
2140 case HAL_QSPI_ABORT_CB_ID :
2141 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2142 break;
2143 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2144 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2145 break;
2146 case HAL_QSPI_CMD_CPLT_CB_ID :
2147 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2148 break;
2149 case HAL_QSPI_RX_CPLT_CB_ID :
2150 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2151 break;
2152 case HAL_QSPI_TX_CPLT_CB_ID :
2153 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2154 break;
2155 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2156 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
2157 break;
2158 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2159 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
2160 break;
2161 case HAL_QSPI_STATUS_MATCH_CB_ID :
2162 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2163 break;
2164 case HAL_QSPI_TIMEOUT_CB_ID :
2165 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2166 break;
2167 case HAL_QSPI_MSP_INIT_CB_ID :
2168 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2169 break;
2170 case HAL_QSPI_MSP_DEINIT_CB_ID :
2171 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2172 break;
2173 default :
2174 /* Update the error code */
2175 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2176 /* update return status */
2177 status = HAL_ERROR;
2178 break;
2181 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2183 switch (CallbackId)
2185 case HAL_QSPI_MSP_INIT_CB_ID :
2186 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2187 break;
2188 case HAL_QSPI_MSP_DEINIT_CB_ID :
2189 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2190 break;
2191 default :
2192 /* Update the error code */
2193 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2194 /* update return status */
2195 status = HAL_ERROR;
2196 break;
2199 else
2201 /* Update the error code */
2202 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2203 /* update return status */
2204 status = HAL_ERROR;
2207 /* Release Lock */
2208 __HAL_UNLOCK(hqspi);
2209 return status;
2211 #endif
2214 * @}
2217 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2218 * @brief QSPI control and State functions
2220 @verbatim
2221 ===============================================================================
2222 ##### Peripheral Control and State functions #####
2223 ===============================================================================
2224 [..]
2225 This subsection provides a set of functions allowing to :
2226 (+) Check in run-time the state of the driver.
2227 (+) Check the error code set during last operation.
2228 (+) Abort any operation.
2231 @endverbatim
2232 * @{
2236 * @brief Return the QSPI handle state.
2237 * @param hqspi : QSPI handle
2238 * @retval HAL state
2240 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2242 /* Return QSPI handle state */
2243 return hqspi->State;
2247 * @brief Return the QSPI error code.
2248 * @param hqspi : QSPI handle
2249 * @retval QSPI Error Code
2251 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2253 return hqspi->ErrorCode;
2257 * @brief Abort the current transmission.
2258 * @param hqspi : QSPI handle
2259 * @retval HAL status
2261 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2263 HAL_StatusTypeDef status = HAL_OK;
2264 uint32_t tickstart = HAL_GetTick();
2266 /* Check if the state is in one of the busy states */
2267 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2269 /* Process unlocked */
2270 __HAL_UNLOCK(hqspi);
2272 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2274 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2275 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2277 /* Abort DMA channel */
2278 status = HAL_DMA_Abort(hqspi->hdma);
2279 if(status != HAL_OK)
2281 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2285 /* Configure QSPI: CR register with Abort request */
2286 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2288 /* Wait until TC flag is set to go back in idle state */
2289 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2291 if (status == HAL_OK)
2293 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2295 /* Wait until BUSY flag is reset */
2296 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2299 if (status == HAL_OK)
2301 /* Reset functional mode configuration to indirect write mode by default */
2302 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2304 /* Update state */
2305 hqspi->State = HAL_QSPI_STATE_READY;
2309 return status;
2313 * @brief Abort the current transmission (non-blocking function)
2314 * @param hqspi : QSPI handle
2315 * @retval HAL status
2317 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2319 HAL_StatusTypeDef status = HAL_OK;
2321 /* Check if the state is in one of the busy states */
2322 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2324 /* Process unlocked */
2325 __HAL_UNLOCK(hqspi);
2327 /* Update QSPI state */
2328 hqspi->State = HAL_QSPI_STATE_ABORT;
2330 /* Disable all interrupts */
2331 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2333 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2335 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2336 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2338 /* Abort DMA channel */
2339 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
2340 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
2342 /* Change state of QSPI */
2343 hqspi->State = HAL_QSPI_STATE_READY;
2345 /* Abort Complete callback */
2346 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2347 hqspi->AbortCpltCallback(hqspi);
2348 #else
2349 HAL_QSPI_AbortCpltCallback(hqspi);
2350 #endif
2353 else
2355 /* Clear interrupt */
2356 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2358 /* Enable the QSPI Transfer Complete Interrupt */
2359 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2361 /* Configure QSPI: CR register with Abort request */
2362 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2365 return status;
2368 /** @brief Set QSPI timeout.
2369 * @param hqspi : QSPI handle.
2370 * @param Timeout : Timeout for the QSPI memory access.
2371 * @retval None
2373 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2375 hqspi->Timeout = Timeout;
2378 /** @brief Set QSPI Fifo threshold.
2379 * @param hqspi : QSPI handle.
2380 * @param Threshold : Threshold of the Fifo (value between 1 and 16).
2381 * @retval HAL status
2383 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2385 HAL_StatusTypeDef status = HAL_OK;
2387 /* Process locked */
2388 __HAL_LOCK(hqspi);
2390 if(hqspi->State == HAL_QSPI_STATE_READY)
2392 /* Synchronize init structure with new FIFO threshold value */
2393 hqspi->Init.FifoThreshold = Threshold;
2395 /* Configure QSPI FIFO Threshold */
2396 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2397 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2399 else
2401 status = HAL_BUSY;
2404 /* Process unlocked */
2405 __HAL_UNLOCK(hqspi);
2407 /* Return function status */
2408 return status;
2411 /** @brief Get QSPI Fifo threshold.
2412 * @param hqspi : QSPI handle.
2413 * @retval Fifo threshold (value between 1 and 16)
2415 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2417 return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2420 /** @brief Set FlashID.
2421 * @param hqspi : QSPI handle.
2422 * @param FlashID : Index of the flash memory to be accessed.
2423 * This parameter can be a value of @ref QSPI_Flash_Select.
2424 * @note The FlashID is ignored when dual flash mode is enabled.
2425 * @retval HAL status
2427 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2429 HAL_StatusTypeDef status = HAL_OK;
2431 /* Check the parameter */
2432 assert_param(IS_QSPI_FLASH_ID(FlashID));
2434 /* Process locked */
2435 __HAL_LOCK(hqspi);
2437 if(hqspi->State == HAL_QSPI_STATE_READY)
2439 /* Synchronize init structure with new FlashID value */
2440 hqspi->Init.FlashID = FlashID;
2442 /* Configure QSPI FlashID */
2443 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2445 else
2447 status = HAL_BUSY;
2450 /* Process unlocked */
2451 __HAL_UNLOCK(hqspi);
2453 /* Return function status */
2454 return status;
2458 * @}
2462 * @}
2465 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2466 * @{
2470 * @brief DMA QSPI receive process complete callback.
2471 * @param hdma : DMA handle
2472 * @retval None
2474 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
2476 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2477 hqspi->RxXferCount = 0U;
2479 /* Enable the QSPI transfer complete Interrupt */
2480 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2484 * @brief DMA QSPI transmit process complete callback.
2485 * @param hdma : DMA handle
2486 * @retval None
2488 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
2490 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2491 hqspi->TxXferCount = 0U;
2493 /* Enable the QSPI transfer complete Interrupt */
2494 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2498 * @brief DMA QSPI receive process half complete callback.
2499 * @param hdma : DMA handle
2500 * @retval None
2502 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2504 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2506 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2507 hqspi->RxHalfCpltCallback(hqspi);
2508 #else
2509 HAL_QSPI_RxHalfCpltCallback(hqspi);
2510 #endif
2514 * @brief DMA QSPI transmit process half complete callback.
2515 * @param hdma : DMA handle
2516 * @retval None
2518 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2520 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
2522 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2523 hqspi->TxHalfCpltCallback(hqspi);
2524 #else
2525 HAL_QSPI_TxHalfCpltCallback(hqspi);
2526 #endif
2530 * @brief DMA QSPI communication error callback.
2531 * @param hdma : DMA handle
2532 * @retval None
2534 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
2536 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2538 hqspi->RxXferCount = 0U;
2539 hqspi->TxXferCount = 0U;
2540 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2542 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2543 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2545 /* Abort the QSPI */
2546 (void)HAL_QSPI_Abort_IT(hqspi);
2551 * @brief DMA QSPI abort complete callback.
2552 * @param hdma : DMA handle
2553 * @retval None
2555 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2557 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
2559 hqspi->RxXferCount = 0U;
2560 hqspi->TxXferCount = 0U;
2562 if(hqspi->State == HAL_QSPI_STATE_ABORT)
2564 /* DMA Abort called by QSPI abort */
2565 /* Clear interrupt */
2566 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2568 /* Enable the QSPI Transfer Complete Interrupt */
2569 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2571 /* Configure QSPI: CR register with Abort request */
2572 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2574 else
2576 /* DMA Abort called due to a transfer error interrupt */
2577 /* Change state of QSPI */
2578 hqspi->State = HAL_QSPI_STATE_READY;
2580 /* Error callback */
2581 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2582 hqspi->ErrorCallback(hqspi);
2583 #else
2584 HAL_QSPI_ErrorCallback(hqspi);
2585 #endif
2590 * @brief Wait for a flag state until timeout.
2591 * @param hqspi : QSPI handle
2592 * @param Flag : Flag checked
2593 * @param State : Value of the flag expected
2594 * @param Tickstart : Tick start value
2595 * @param Timeout : Duration of the timeout
2596 * @retval HAL status
2598 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2599 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2601 /* Wait until flag is in expected state */
2602 while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2604 /* Check for the Timeout */
2605 if (Timeout != HAL_MAX_DELAY)
2607 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2609 hqspi->State = HAL_QSPI_STATE_ERROR;
2610 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2612 return HAL_ERROR;
2616 return HAL_OK;
2620 * @brief Configure the communication registers.
2621 * @param hqspi : QSPI handle
2622 * @param cmd : structure that contains the command configuration information
2623 * @param FunctionalMode : functional mode to configured
2624 * This parameter can be one of the following values:
2625 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2626 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2627 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2628 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2629 * @retval None
2631 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2633 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2635 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2637 /* Configure QSPI: DLR register with the number of data to read or write */
2638 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2641 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2643 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2645 /* Configure QSPI: ABR register with alternate bytes value */
2646 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2648 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2650 /*---- Command with instruction, address and alternate bytes ----*/
2651 /* Configure QSPI: CCR register with all communications parameters */
2652 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2653 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2654 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2655 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2656 cmd->Instruction | FunctionalMode));
2658 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2660 /* Configure QSPI: AR register with address value */
2661 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2664 else
2666 /*---- Command with instruction and alternate bytes ----*/
2667 /* Configure QSPI: CCR register with all communications parameters */
2668 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2669 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2670 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2671 cmd->AddressMode | cmd->InstructionMode |
2672 cmd->Instruction | FunctionalMode));
2675 else
2677 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2679 /*---- Command with instruction and address ----*/
2680 /* Configure QSPI: CCR register with all communications parameters */
2681 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2682 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2683 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2684 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2686 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2688 /* Configure QSPI: AR register with address value */
2689 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2692 else
2694 /*---- Command with only instruction ----*/
2695 /* Configure QSPI: CCR register with all communications parameters */
2696 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2697 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2698 cmd->AlternateByteMode | cmd->AddressMode |
2699 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2703 else
2705 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2707 /* Configure QSPI: ABR register with alternate bytes value */
2708 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2710 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2712 /*---- Command with address and alternate bytes ----*/
2713 /* Configure QSPI: CCR register with all communications parameters */
2714 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2715 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2716 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2717 cmd->AddressSize | cmd->AddressMode |
2718 cmd->InstructionMode | FunctionalMode));
2720 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2722 /* Configure QSPI: AR register with address value */
2723 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2726 else
2728 /*---- Command with only alternate bytes ----*/
2729 /* Configure QSPI: CCR register with all communications parameters */
2730 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2731 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2732 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2733 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2736 else
2738 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2740 /*---- Command with only address ----*/
2741 /* Configure QSPI: CCR register with all communications parameters */
2742 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2743 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2744 cmd->AlternateByteMode | cmd->AddressSize |
2745 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2747 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2749 /* Configure QSPI: AR register with address value */
2750 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2753 else
2755 /*---- Command with only data phase ----*/
2756 if (cmd->DataMode != QSPI_DATA_NONE)
2758 /* Configure QSPI: CCR register with all communications parameters */
2759 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2760 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2761 cmd->AlternateByteMode | cmd->AddressMode |
2762 cmd->InstructionMode | FunctionalMode));
2770 * @}
2774 * @}
2777 #endif /* HAL_QSPI_MODULE_ENABLED */
2779 * @}
2783 * @}
2786 #endif /* defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2) */
2788 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/