2 ******************************************************************************
\r
3 * @file stm32l4xx_hal_qspi.c
\r
4 * @author MCD Application Team
\r
5 * @brief QSPI HAL module driver.
\r
6 * This file provides firmware functions to manage the following
\r
7 * functionalities of the QuadSPI interface (QSPI).
\r
8 * + Initialization and de-initialization functions
\r
9 * + Indirect functional mode management
\r
10 * + Memory-mapped functional mode management
\r
11 * + Auto-polling functional mode management
\r
12 * + Interrupts and flags management
\r
13 * + DMA channel configuration for indirect functional mode
\r
14 * + Errors management and abort functionality
\r
18 ===============================================================================
\r
19 ##### How to use this driver #####
\r
20 ===============================================================================
\r
22 *** Initialization ***
\r
23 ======================
\r
25 (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
\r
26 (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
\r
27 (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
\r
28 (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
\r
29 (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
\r
30 (++) If interrupt mode is used, enable and configure QuadSPI global
\r
31 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
\r
32 (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
\r
33 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
\r
34 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
\r
35 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
\r
36 (#) Configure the flash size, the clock prescaler, the fifo threshold, the
\r
37 clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
\r
39 *** Indirect functional mode ***
\r
40 ================================
\r
42 (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
\r
44 (++) Instruction phase : the mode used and if present the instruction opcode.
\r
45 (++) Address phase : the mode used and if present the size and the address value.
\r
46 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
\r
48 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
\r
49 (++) Data phase : the mode used and if present the number of bytes.
\r
50 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
\r
52 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
\r
53 (#) If no data is required for the command, it is sent directly to the memory :
\r
54 (++) In polling mode, the output of the function is done when the transfer is complete.
\r
55 (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
\r
56 (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
\r
57 HAL_QSPI_Transmit_IT() after the command configuration :
\r
58 (++) In polling mode, the output of the function is done when the transfer is complete.
\r
59 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
\r
60 is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
\r
61 (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
\r
62 HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
\r
63 (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
\r
64 HAL_QSPI_Receive_IT() after the command configuration :
\r
65 (++) In polling mode, the output of the function is done when the transfer is complete.
\r
66 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
\r
67 is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
\r
68 (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
\r
69 HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
\r
71 *** Auto-polling functional mode ***
\r
72 ====================================
\r
74 (#) Configure the command sequence and the auto-polling functional mode using the
\r
75 HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
\r
76 (++) Instruction phase : the mode used and if present the instruction opcode.
\r
77 (++) Address phase : the mode used and if present the size and the address value.
\r
78 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
\r
80 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
\r
81 (++) Data phase : the mode used.
\r
82 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
\r
84 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
\r
85 (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
\r
86 the polling interval and the automatic stop activation.
\r
87 (#) After the configuration :
\r
88 (++) In polling mode, the output of the function is done when the status match is reached. The
\r
89 automatic stop is activated to avoid an infinite loop.
\r
90 (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
\r
92 *** Memory-mapped functional mode ***
\r
93 =====================================
\r
95 (#) Configure the command sequence and the memory-mapped functional mode using the
\r
96 HAL_QSPI_MemoryMapped() functions :
\r
97 (++) Instruction phase : the mode used and if present the instruction opcode.
\r
98 (++) Address phase : the mode used and the size.
\r
99 (++) Alternate-bytes phase : the mode used and if present the size and the alternate
\r
101 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
\r
102 (++) Data phase : the mode used.
\r
103 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
\r
105 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
\r
106 (++) The timeout activation and the timeout period.
\r
107 (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
\r
108 the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
\r
110 *** Errors management and abort functionality ***
\r
111 =================================================
\r
113 (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
\r
114 (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
\r
116 (++) In polling mode, the output of the function is done when the transfer
\r
117 complete bit is set and the busy bit cleared.
\r
118 (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
\r
119 the transfer complete bit is set.
\r
121 *** Control functions ***
\r
122 =========================
\r
124 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
\r
125 (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
\r
126 (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
\r
127 (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
\r
128 (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
\r
130 *** Callback registration ***
\r
131 =============================================
\r
133 The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
\r
134 allows the user to configure dynamically the driver callbacks.
\r
136 Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,
\r
137 it allows to register following callbacks:
\r
138 (+) ErrorCallback : callback when error occurs.
\r
139 (+) AbortCpltCallback : callback when abort is completed.
\r
140 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
\r
141 (+) CmdCpltCallback : callback when a command without data is completed.
\r
142 (+) RxCpltCallback : callback when a reception transfer is completed.
\r
143 (+) TxCpltCallback : callback when a transmission transfer is completed.
\r
144 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
\r
145 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
\r
146 (+) StatusMatchCallback : callback when a status match occurs.
\r
147 (+) TimeOutCallback : callback when the timeout perioed expires.
\r
148 (+) MspInitCallback : QSPI MspInit.
\r
149 (+) MspDeInitCallback : QSPI MspDeInit.
\r
150 This function takes as parameters the HAL peripheral handle, the Callback ID
\r
151 and a pointer to the user callback function.
\r
153 Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default
\r
154 weak (surcharged) function. It allows to reset following callbacks:
\r
155 (+) ErrorCallback : callback when error occurs.
\r
156 (+) AbortCpltCallback : callback when abort is completed.
\r
157 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
\r
158 (+) CmdCpltCallback : callback when a command without data is completed.
\r
159 (+) RxCpltCallback : callback when a reception transfer is completed.
\r
160 (+) TxCpltCallback : callback when a transmission transfer is completed.
\r
161 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
\r
162 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
\r
163 (+) StatusMatchCallback : callback when a status match occurs.
\r
164 (+) TimeOutCallback : callback when the timeout perioed expires.
\r
165 (+) MspInitCallback : QSPI MspInit.
\r
166 (+) MspDeInitCallback : QSPI MspDeInit.
\r
167 This function) takes as parameters the HAL peripheral handle and the Callback ID.
\r
169 By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
\r
170 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
\r
171 Exception done for MspInit and MspDeInit callbacks that are respectively
\r
172 reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init
\r
173 and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
\r
174 If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit
\r
175 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
\r
177 Callbacks can be registered/unregistered in READY state only.
\r
178 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
\r
179 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
\r
180 during the Init/DeInit.
\r
181 In that case first register the MspInit/MspDeInit user callbacks
\r
182 using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
\r
183 or @ref HAL_QSPI_Init function.
\r
185 When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
\r
186 not defined, the callback registering feature is not available
\r
187 and weak (surcharged) callbacks are used.
\r
189 *** Workarounds linked to Silicon Limitation ***
\r
190 ====================================================
\r
192 (#) Workarounds Implemented inside HAL Driver
\r
193 (++) Extra data written in the FIFO at the end of a read transfer
\r
196 ******************************************************************************
\r
199 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
\r
200 * All rights reserved.</center></h2>
\r
202 * This software component is licensed by ST under BSD 3-Clause license,
\r
203 * the "License"; You may not use this file except in compliance with the
\r
204 * License. You may obtain a copy of the License at:
\r
205 * opensource.org/licenses/BSD-3-Clause
\r
207 ******************************************************************************
\r
210 /* Includes ------------------------------------------------------------------*/
\r
211 #include "stm32l4xx_hal.h"
\r
213 #if defined(QUADSPI)
\r
215 /** @addtogroup STM32L4xx_HAL_Driver
\r
219 /** @defgroup QSPI QSPI
\r
220 * @brief QSPI HAL module driver
\r
223 #ifdef HAL_QSPI_MODULE_ENABLED
\r
225 /* Private typedef -----------------------------------------------------------*/
\r
227 /* Private define ------------------------------------------------------------*/
\r
228 /** @defgroup QSPI_Private_Constants QSPI Private Constants
\r
231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
\r
232 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
\r
233 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
\r
234 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
\r
239 /* Private macro -------------------------------------------------------------*/
\r
240 /** @defgroup QSPI_Private_Macros QSPI Private Macros
\r
243 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
\r
244 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
\r
245 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
\r
246 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
\r
251 /* Private variables ---------------------------------------------------------*/
\r
253 /* Private function prototypes -----------------------------------------------*/
\r
254 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
\r
255 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
\r
256 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
\r
257 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
\r
258 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
\r
259 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
\r
260 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
\r
261 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
\r
263 /* Exported functions --------------------------------------------------------*/
\r
265 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
\r
269 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
\r
270 * @brief Initialization and Configuration functions
\r
273 ===============================================================================
\r
274 ##### Initialization and Configuration functions #####
\r
275 ===============================================================================
\r
277 This subsection provides a set of functions allowing to :
\r
278 (+) Initialize the QuadSPI.
\r
279 (+) De-initialize the QuadSPI.
\r
286 * @brief Initialize the QSPI mode according to the specified parameters
\r
287 * in the QSPI_InitTypeDef and initialize the associated handle.
\r
288 * @param hqspi : QSPI handle
\r
289 * @retval HAL status
\r
291 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
\r
293 HAL_StatusTypeDef status;
\r
294 uint32_t tickstart = HAL_GetTick();
\r
296 /* Check the QSPI handle allocation */
\r
302 /* Check the parameters */
\r
303 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
\r
304 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
\r
305 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
\r
306 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
\r
307 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
\r
308 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
\r
309 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
\r
310 #if defined(QUADSPI_CR_DFM)
\r
311 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
\r
313 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
\r
315 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
\r
319 /* Process locked */
\r
322 if(hqspi->State == HAL_QSPI_STATE_RESET)
\r
324 /* Allocate lock resource and initialize it */
\r
325 hqspi->Lock = HAL_UNLOCKED;
\r
327 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
328 /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
\r
329 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
\r
330 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
\r
331 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
\r
332 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
\r
333 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
\r
334 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
\r
335 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
\r
336 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
\r
337 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
\r
338 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
\r
340 if(hqspi->MspInitCallback == NULL)
\r
342 hqspi->MspInitCallback = HAL_QSPI_MspInit;
\r
345 /* Init the low level hardware */
\r
346 hqspi->MspInitCallback(hqspi);
\r
348 /* Init the low level hardware : GPIO, CLOCK */
\r
349 HAL_QSPI_MspInit(hqspi);
\r
352 /* Configure the default timeout for the QSPI memory access */
\r
353 HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
\r
356 /* Configure QSPI FIFO Threshold */
\r
357 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
\r
358 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
\r
360 /* Wait till BUSY flag reset */
\r
361 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
\r
363 if(status == HAL_OK)
\r
365 /* Configure QSPI Clock Prescaler and Sample Shift */
\r
366 #if defined(QUADSPI_CR_DFM)
\r
367 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
\r
368 ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
\r
369 hqspi->Init.SampleShifting | hqspi->Init.FlashID | hqspi->Init.DualFlash));
\r
371 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT),
\r
372 ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
\r
373 hqspi->Init.SampleShifting));
\r
376 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
\r
377 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
\r
378 ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
\r
379 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
\r
381 /* Enable the QSPI peripheral */
\r
382 __HAL_QSPI_ENABLE(hqspi);
\r
384 /* Set QSPI error code to none */
\r
385 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
387 /* Initialize the QSPI state */
\r
388 hqspi->State = HAL_QSPI_STATE_READY;
\r
392 __HAL_UNLOCK(hqspi);
\r
394 /* Return function status */
\r
399 * @brief De-Initialize the QSPI peripheral.
\r
400 * @param hqspi : QSPI handle
\r
401 * @retval HAL status
\r
403 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
\r
405 /* Check the QSPI handle allocation */
\r
411 /* Process locked */
\r
414 /* Disable the QSPI Peripheral Clock */
\r
415 __HAL_QSPI_DISABLE(hqspi);
\r
417 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
418 if(hqspi->MspDeInitCallback == NULL)
\r
420 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
\r
423 /* DeInit the low level hardware */
\r
424 hqspi->MspDeInitCallback(hqspi);
\r
426 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
\r
427 HAL_QSPI_MspDeInit(hqspi);
\r
430 /* Set QSPI error code to none */
\r
431 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
433 /* Initialize the QSPI state */
\r
434 hqspi->State = HAL_QSPI_STATE_RESET;
\r
437 __HAL_UNLOCK(hqspi);
\r
443 * @brief Initialize the QSPI MSP.
\r
444 * @param hqspi : QSPI handle
\r
447 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
\r
449 /* Prevent unused argument(s) compilation warning */
\r
452 /* NOTE : This function should not be modified, when the callback is needed,
\r
453 the HAL_QSPI_MspInit can be implemented in the user file
\r
458 * @brief DeInitialize the QSPI MSP.
\r
459 * @param hqspi : QSPI handle
\r
462 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
\r
464 /* Prevent unused argument(s) compilation warning */
\r
467 /* NOTE : This function should not be modified, when the callback is needed,
\r
468 the HAL_QSPI_MspDeInit can be implemented in the user file
\r
476 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
\r
477 * @brief QSPI Transmit/Receive functions
\r
480 ===============================================================================
\r
481 ##### IO operation functions #####
\r
482 ===============================================================================
\r
484 This subsection provides a set of functions allowing to :
\r
485 (+) Handle the interrupts.
\r
486 (+) Handle the command sequence.
\r
487 (+) Transmit data in blocking, interrupt or DMA mode.
\r
488 (+) Receive data in blocking, interrupt or DMA mode.
\r
489 (+) Manage the auto-polling functional mode.
\r
490 (+) Manage the memory-mapped functional mode.
\r
497 * @brief Handle QSPI interrupt request.
\r
498 * @param hqspi : QSPI handle
\r
501 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
\r
503 __IO uint32_t *data_reg;
\r
504 uint32_t flag = READ_REG(hqspi->Instance->SR);
\r
505 uint32_t itsource = READ_REG(hqspi->Instance->CR);
\r
507 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
\r
508 if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
\r
510 data_reg = &hqspi->Instance->DR;
\r
512 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
\r
514 /* Transmission process */
\r
515 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
\r
517 if (hqspi->TxXferCount > 0U)
\r
519 /* Fill the FIFO until the threshold is reached */
\r
520 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
\r
521 hqspi->pTxBuffPtr++;
\r
522 hqspi->TxXferCount--;
\r
526 /* No more data available for the transfer */
\r
527 /* Disable the QSPI FIFO Threshold Interrupt */
\r
528 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
\r
533 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
\r
535 /* Receiving Process */
\r
536 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
\r
538 if (hqspi->RxXferCount > 0U)
\r
540 /* Read the FIFO until the threshold is reached */
\r
541 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
\r
542 hqspi->pRxBuffPtr++;
\r
543 hqspi->RxXferCount--;
\r
547 /* All data have been received for the transfer */
\r
548 /* Disable the QSPI FIFO Threshold Interrupt */
\r
549 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
\r
556 /* Nothing to do */
\r
559 /* FIFO Threshold callback */
\r
560 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
561 hqspi->FifoThresholdCallback(hqspi);
\r
563 HAL_QSPI_FifoThresholdCallback(hqspi);
\r
567 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
\r
568 else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
\r
570 /* Clear interrupt */
\r
571 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
\r
573 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
\r
574 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
\r
576 /* Transfer complete callback */
\r
577 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
\r
579 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
\r
581 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
582 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
584 /* Disable the DMA channel */
\r
585 __HAL_DMA_DISABLE(hqspi->hdma);
\r
588 #if (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
\r
589 /* Clear Busy bit */
\r
590 HAL_QSPI_Abort_IT(hqspi);
\r
593 /* Change state of QSPI */
\r
594 hqspi->State = HAL_QSPI_STATE_READY;
\r
596 /* TX Complete callback */
\r
597 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
598 hqspi->TxCpltCallback(hqspi);
\r
600 HAL_QSPI_TxCpltCallback(hqspi);
\r
603 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
\r
605 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
\r
607 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
608 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
610 /* Disable the DMA channel */
\r
611 __HAL_DMA_DISABLE(hqspi->hdma);
\r
615 data_reg = &hqspi->Instance->DR;
\r
616 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
\r
618 if (hqspi->RxXferCount > 0U)
\r
620 /* Read the last data received in the FIFO until it is empty */
\r
621 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
\r
622 hqspi->pRxBuffPtr++;
\r
623 hqspi->RxXferCount--;
\r
627 /* All data have been received for the transfer */
\r
633 #if (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
\r
634 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
\r
635 HAL_QSPI_Abort_IT(hqspi);
\r
638 /* Change state of QSPI */
\r
639 hqspi->State = HAL_QSPI_STATE_READY;
\r
641 /* RX Complete callback */
\r
642 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
643 hqspi->RxCpltCallback(hqspi);
\r
645 HAL_QSPI_RxCpltCallback(hqspi);
\r
648 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
\r
650 /* Change state of QSPI */
\r
651 hqspi->State = HAL_QSPI_STATE_READY;
\r
653 /* Command Complete callback */
\r
654 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
655 hqspi->CmdCpltCallback(hqspi);
\r
657 HAL_QSPI_CmdCpltCallback(hqspi);
\r
660 else if(hqspi->State == HAL_QSPI_STATE_ABORT)
\r
662 /* Reset functional mode configuration to indirect write mode by default */
\r
663 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
\r
665 /* Change state of QSPI */
\r
666 hqspi->State = HAL_QSPI_STATE_READY;
\r
668 if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
\r
670 /* Abort called by the user */
\r
672 /* Abort Complete callback */
\r
673 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
674 hqspi->AbortCpltCallback(hqspi);
\r
676 HAL_QSPI_AbortCpltCallback(hqspi);
\r
681 /* Abort due to an error (eg : DMA error) */
\r
683 /* Error callback */
\r
684 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
685 hqspi->ErrorCallback(hqspi);
\r
687 HAL_QSPI_ErrorCallback(hqspi);
\r
693 /* Nothing to do */
\r
697 /* QSPI Status Match interrupt occurred ------------------------------------*/
\r
698 else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
\r
700 /* Clear interrupt */
\r
701 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
\r
703 /* Check if the automatic poll mode stop is activated */
\r
704 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
\r
706 /* Disable the QSPI Transfer Error and Status Match Interrupts */
\r
707 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
\r
709 /* Change state of QSPI */
\r
710 hqspi->State = HAL_QSPI_STATE_READY;
\r
713 /* Status match callback */
\r
714 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
715 hqspi->StatusMatchCallback(hqspi);
\r
717 HAL_QSPI_StatusMatchCallback(hqspi);
\r
721 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
\r
722 else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
\r
724 /* Clear interrupt */
\r
725 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
\r
727 /* Disable all the QSPI Interrupts */
\r
728 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
\r
730 /* Set error code */
\r
731 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
\r
733 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
\r
735 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
736 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
738 /* Disable the DMA channel */
\r
739 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
\r
740 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
\r
742 /* Set error code to DMA */
\r
743 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
\r
745 /* Change state of QSPI */
\r
746 hqspi->State = HAL_QSPI_STATE_READY;
\r
748 /* Error callback */
\r
749 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
750 hqspi->ErrorCallback(hqspi);
\r
752 HAL_QSPI_ErrorCallback(hqspi);
\r
758 /* Change state of QSPI */
\r
759 hqspi->State = HAL_QSPI_STATE_READY;
\r
761 /* Error callback */
\r
762 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
763 hqspi->ErrorCallback(hqspi);
\r
765 HAL_QSPI_ErrorCallback(hqspi);
\r
770 /* QSPI Timeout interrupt occurred -----------------------------------------*/
\r
771 else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
\r
773 /* Clear interrupt */
\r
774 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
\r
776 /* Timeout callback */
\r
777 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
778 hqspi->TimeOutCallback(hqspi);
\r
780 HAL_QSPI_TimeOutCallback(hqspi);
\r
786 /* Nothing to do */
\r
791 * @brief Set the command configuration.
\r
792 * @param hqspi : QSPI handle
\r
793 * @param cmd : structure that contains the command configuration information
\r
794 * @param Timeout : Timeout duration
\r
795 * @note This function is used only in Indirect Read or Write Modes
\r
796 * @retval HAL status
\r
798 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
\r
800 HAL_StatusTypeDef status;
\r
801 uint32_t tickstart = HAL_GetTick();
\r
803 /* Check the parameters */
\r
804 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
\r
805 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
807 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
\r
810 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
\r
811 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
813 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
\r
816 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
\r
817 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
819 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
\r
822 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
\r
823 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
\r
825 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
\r
826 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
\r
827 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
\r
829 /* Process locked */
\r
832 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
834 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
836 /* Update QSPI state */
\r
837 hqspi->State = HAL_QSPI_STATE_BUSY;
\r
839 /* Wait till BUSY flag reset */
\r
840 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
\r
842 if (status == HAL_OK)
\r
844 /* Call the configuration function */
\r
845 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
\r
847 if (cmd->DataMode == QSPI_DATA_NONE)
\r
849 /* When there is no data phase, the transfer start as soon as the configuration is done
\r
850 so wait until TC flag is set to go back in idle state */
\r
851 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
\r
853 if (status == HAL_OK)
\r
855 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
857 /* Update QSPI state */
\r
858 hqspi->State = HAL_QSPI_STATE_READY;
\r
863 /* Update QSPI state */
\r
864 hqspi->State = HAL_QSPI_STATE_READY;
\r
873 /* Process unlocked */
\r
874 __HAL_UNLOCK(hqspi);
\r
876 /* Return function status */
\r
881 * @brief Set the command configuration in interrupt mode.
\r
882 * @param hqspi : QSPI handle
\r
883 * @param cmd : structure that contains the command configuration information
\r
884 * @note This function is used only in Indirect Read or Write Modes
\r
885 * @retval HAL status
\r
887 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
\r
889 HAL_StatusTypeDef status;
\r
890 uint32_t tickstart = HAL_GetTick();
\r
892 /* Check the parameters */
\r
893 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
\r
894 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
896 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
\r
899 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
\r
900 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
902 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
\r
905 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
\r
906 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
908 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
\r
911 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
\r
912 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
\r
914 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
\r
915 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
\r
916 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
\r
918 /* Process locked */
\r
921 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
923 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
925 /* Update QSPI state */
\r
926 hqspi->State = HAL_QSPI_STATE_BUSY;
\r
928 /* Wait till BUSY flag reset */
\r
929 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
\r
931 if (status == HAL_OK)
\r
933 if (cmd->DataMode == QSPI_DATA_NONE)
\r
935 /* Clear interrupt */
\r
936 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
\r
939 /* Call the configuration function */
\r
940 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
\r
942 if (cmd->DataMode == QSPI_DATA_NONE)
\r
944 /* When there is no data phase, the transfer start as soon as the configuration is done
\r
945 so activate TC and TE interrupts */
\r
946 /* Process unlocked */
\r
947 __HAL_UNLOCK(hqspi);
\r
949 /* Enable the QSPI Transfer Error Interrupt */
\r
950 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
\r
954 /* Update QSPI state */
\r
955 hqspi->State = HAL_QSPI_STATE_READY;
\r
957 /* Process unlocked */
\r
958 __HAL_UNLOCK(hqspi);
\r
963 /* Process unlocked */
\r
964 __HAL_UNLOCK(hqspi);
\r
971 /* Process unlocked */
\r
972 __HAL_UNLOCK(hqspi);
\r
975 /* Return function status */
\r
980 * @brief Transmit an amount of data in blocking mode.
\r
981 * @param hqspi : QSPI handle
\r
982 * @param pData : pointer to data buffer
\r
983 * @param Timeout : Timeout duration
\r
984 * @note This function is used only in Indirect Write Mode
\r
985 * @retval HAL status
\r
987 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
\r
989 HAL_StatusTypeDef status = HAL_OK;
\r
990 uint32_t tickstart = HAL_GetTick();
\r
991 __IO uint32_t *data_reg = &hqspi->Instance->DR;
\r
993 /* Process locked */
\r
996 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
998 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1000 if(pData != NULL )
\r
1002 /* Update state */
\r
1003 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
\r
1005 /* Configure counters and size of the handle */
\r
1006 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1007 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1008 hqspi->pTxBuffPtr = pData;
\r
1010 /* Configure QSPI: CCR register with functional as indirect write */
\r
1011 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
\r
1013 while(hqspi->TxXferCount > 0U)
\r
1015 /* Wait until FT flag is set to send data */
\r
1016 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
\r
1018 if (status != HAL_OK)
\r
1023 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
\r
1024 hqspi->pTxBuffPtr++;
\r
1025 hqspi->TxXferCount--;
\r
1028 if (status == HAL_OK)
\r
1030 /* Wait until TC flag is set to go back in idle state */
\r
1031 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
\r
1033 if (status == HAL_OK)
\r
1035 /* Clear Transfer Complete bit */
\r
1036 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
1038 #if (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
\r
1039 /* Clear Busy bit */
\r
1040 status = HAL_QSPI_Abort(hqspi);
\r
1045 /* Update QSPI state */
\r
1046 hqspi->State = HAL_QSPI_STATE_READY;
\r
1050 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1051 status = HAL_ERROR;
\r
1056 status = HAL_BUSY;
\r
1059 /* Process unlocked */
\r
1060 __HAL_UNLOCK(hqspi);
\r
1067 * @brief Receive an amount of data in blocking mode.
\r
1068 * @param hqspi : QSPI handle
\r
1069 * @param pData : pointer to data buffer
\r
1070 * @param Timeout : Timeout duration
\r
1071 * @note This function is used only in Indirect Read Mode
\r
1072 * @retval HAL status
\r
1074 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
\r
1076 HAL_StatusTypeDef status = HAL_OK;
\r
1077 uint32_t tickstart = HAL_GetTick();
\r
1078 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
\r
1079 __IO uint32_t *data_reg = &hqspi->Instance->DR;
\r
1081 /* Process locked */
\r
1082 __HAL_LOCK(hqspi);
\r
1084 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1086 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1088 if(pData != NULL )
\r
1090 /* Update state */
\r
1091 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
\r
1093 /* Configure counters and size of the handle */
\r
1094 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1095 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1096 hqspi->pRxBuffPtr = pData;
\r
1098 /* Configure QSPI: CCR register with functional as indirect read */
\r
1099 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
\r
1101 /* Start the transfer by re-writing the address in AR register */
\r
1102 WRITE_REG(hqspi->Instance->AR, addr_reg);
\r
1104 while(hqspi->RxXferCount > 0U)
\r
1106 /* Wait until FT or TC flag is set to read received data */
\r
1107 status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
\r
1109 if (status != HAL_OK)
\r
1114 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
\r
1115 hqspi->pRxBuffPtr++;
\r
1116 hqspi->RxXferCount--;
\r
1119 if (status == HAL_OK)
\r
1121 /* Wait until TC flag is set to go back in idle state */
\r
1122 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
\r
1124 if (status == HAL_OK)
\r
1126 /* Clear Transfer Complete bit */
\r
1127 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
1129 #if (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))
\r
1130 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
\r
1131 status = HAL_QSPI_Abort(hqspi);
\r
1136 /* Update QSPI state */
\r
1137 hqspi->State = HAL_QSPI_STATE_READY;
\r
1141 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1142 status = HAL_ERROR;
\r
1147 status = HAL_BUSY;
\r
1150 /* Process unlocked */
\r
1151 __HAL_UNLOCK(hqspi);
\r
1157 * @brief Send an amount of data in non-blocking mode with interrupt.
\r
1158 * @param hqspi : QSPI handle
\r
1159 * @param pData : pointer to data buffer
\r
1160 * @note This function is used only in Indirect Write Mode
\r
1161 * @retval HAL status
\r
1163 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
\r
1165 HAL_StatusTypeDef status = HAL_OK;
\r
1167 /* Process locked */
\r
1168 __HAL_LOCK(hqspi);
\r
1170 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1172 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1174 if(pData != NULL )
\r
1176 /* Update state */
\r
1177 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
\r
1179 /* Configure counters and size of the handle */
\r
1180 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1181 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1182 hqspi->pTxBuffPtr = pData;
\r
1184 /* Clear interrupt */
\r
1185 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
\r
1187 /* Configure QSPI: CCR register with functional as indirect write */
\r
1188 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
\r
1190 /* Process unlocked */
\r
1191 __HAL_UNLOCK(hqspi);
\r
1193 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
\r
1194 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
\r
1198 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1199 status = HAL_ERROR;
\r
1201 /* Process unlocked */
\r
1202 __HAL_UNLOCK(hqspi);
\r
1207 status = HAL_BUSY;
\r
1209 /* Process unlocked */
\r
1210 __HAL_UNLOCK(hqspi);
\r
1217 * @brief Receive an amount of data in non-blocking mode with interrupt.
\r
1218 * @param hqspi : QSPI handle
\r
1219 * @param pData : pointer to data buffer
\r
1220 * @note This function is used only in Indirect Read Mode
\r
1221 * @retval HAL status
\r
1223 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
\r
1225 HAL_StatusTypeDef status = HAL_OK;
\r
1226 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
\r
1228 /* Process locked */
\r
1229 __HAL_LOCK(hqspi);
\r
1231 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1233 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1235 if(pData != NULL )
\r
1237 /* Update state */
\r
1238 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
\r
1240 /* Configure counters and size of the handle */
\r
1241 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1242 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
\r
1243 hqspi->pRxBuffPtr = pData;
\r
1245 /* Clear interrupt */
\r
1246 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
\r
1248 /* Configure QSPI: CCR register with functional as indirect read */
\r
1249 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
\r
1251 /* Start the transfer by re-writing the address in AR register */
\r
1252 WRITE_REG(hqspi->Instance->AR, addr_reg);
\r
1254 /* Process unlocked */
\r
1255 __HAL_UNLOCK(hqspi);
\r
1257 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
\r
1258 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
\r
1262 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1263 status = HAL_ERROR;
\r
1265 /* Process unlocked */
\r
1266 __HAL_UNLOCK(hqspi);
\r
1271 status = HAL_BUSY;
\r
1273 /* Process unlocked */
\r
1274 __HAL_UNLOCK(hqspi);
\r
1281 * @brief Send an amount of data in non-blocking mode with DMA.
\r
1282 * @param hqspi : QSPI handle
\r
1283 * @param pData : pointer to data buffer
\r
1284 * @note This function is used only in Indirect Write Mode
\r
1285 * @note If DMA peripheral access is configured as halfword, the number
\r
1286 * of data and the fifo threshold should be aligned on halfword
\r
1287 * @note If DMA peripheral access is configured as word, the number
\r
1288 * of data and the fifo threshold should be aligned on word
\r
1289 * @retval HAL status
\r
1291 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
\r
1293 HAL_StatusTypeDef status = HAL_OK;
\r
1294 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
\r
1296 /* Process locked */
\r
1297 __HAL_LOCK(hqspi);
\r
1299 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1301 /* Clear the error code */
\r
1302 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1304 if(pData != NULL )
\r
1306 /* Configure counters of the handle */
\r
1307 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
\r
1309 hqspi->TxXferCount = data_size;
\r
1311 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
\r
1313 if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
\r
1315 /* The number of data or the fifo threshold is not aligned on halfword
\r
1316 => no transfer possible with DMA peripheral access configured as halfword */
\r
1317 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1318 status = HAL_ERROR;
\r
1320 /* Process unlocked */
\r
1321 __HAL_UNLOCK(hqspi);
\r
1325 hqspi->TxXferCount = (data_size >> 1U);
\r
1328 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
\r
1330 if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
\r
1332 /* The number of data or the fifo threshold is not aligned on word
\r
1333 => no transfer possible with DMA peripheral access configured as word */
\r
1334 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1335 status = HAL_ERROR;
\r
1337 /* Process unlocked */
\r
1338 __HAL_UNLOCK(hqspi);
\r
1342 hqspi->TxXferCount = (data_size >> 2U);
\r
1347 /* Nothing to do */
\r
1350 if (status == HAL_OK)
\r
1352 /* Update state */
\r
1353 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
\r
1355 /* Clear interrupt */
\r
1356 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
\r
1358 /* Configure size and pointer of the handle */
\r
1359 hqspi->TxXferSize = hqspi->TxXferCount;
\r
1360 hqspi->pTxBuffPtr = pData;
\r
1362 /* Configure QSPI: CCR register with functional mode as indirect write */
\r
1363 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
\r
1365 /* Set the QSPI DMA transfer complete callback */
\r
1366 hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
\r
1368 /* Set the QSPI DMA Half transfer complete callback */
\r
1369 hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
\r
1371 /* Set the DMA error callback */
\r
1372 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
\r
1374 /* Clear the DMA abort callback */
\r
1375 hqspi->hdma->XferAbortCallback = NULL;
\r
1377 /* Configure the direction of the DMA */
\r
1378 hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
\r
1379 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
\r
1381 /* Enable the QSPI transmit DMA Channel */
\r
1382 if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
\r
1384 /* Process unlocked */
\r
1385 __HAL_UNLOCK(hqspi);
\r
1387 /* Enable the QSPI transfer error Interrupt */
\r
1388 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
\r
1390 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
\r
1391 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
1395 status = HAL_ERROR;
\r
1396 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
\r
1397 hqspi->State = HAL_QSPI_STATE_READY;
\r
1399 /* Process unlocked */
\r
1400 __HAL_UNLOCK(hqspi);
\r
1406 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1407 status = HAL_ERROR;
\r
1409 /* Process unlocked */
\r
1410 __HAL_UNLOCK(hqspi);
\r
1415 status = HAL_BUSY;
\r
1417 /* Process unlocked */
\r
1418 __HAL_UNLOCK(hqspi);
\r
1425 * @brief Receive an amount of data in non-blocking mode with DMA.
\r
1426 * @param hqspi : QSPI handle
\r
1427 * @param pData : pointer to data buffer.
\r
1428 * @note This function is used only in Indirect Read Mode
\r
1429 * @note If DMA peripheral access is configured as halfword, the number
\r
1430 * of data and the fifo threshold should be aligned on halfword
\r
1431 * @note If DMA peripheral access is configured as word, the number
\r
1432 * of data and the fifo threshold should be aligned on word
\r
1433 * @retval HAL status
\r
1435 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
\r
1437 HAL_StatusTypeDef status = HAL_OK;
\r
1438 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
\r
1439 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
\r
1441 /* Process locked */
\r
1442 __HAL_LOCK(hqspi);
\r
1444 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1446 /* Clear the error code */
\r
1447 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1449 if(pData != NULL )
\r
1451 /* Configure counters of the handle */
\r
1452 if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
\r
1454 hqspi->RxXferCount = data_size;
\r
1456 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
\r
1458 if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
\r
1460 /* The number of data or the fifo threshold is not aligned on halfword
\r
1461 => no transfer possible with DMA peripheral access configured as halfword */
\r
1462 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1463 status = HAL_ERROR;
\r
1465 /* Process unlocked */
\r
1466 __HAL_UNLOCK(hqspi);
\r
1470 hqspi->RxXferCount = (data_size >> 1U);
\r
1473 else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
\r
1475 if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
\r
1477 /* The number of data or the fifo threshold is not aligned on word
\r
1478 => no transfer possible with DMA peripheral access configured as word */
\r
1479 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1480 status = HAL_ERROR;
\r
1482 /* Process unlocked */
\r
1483 __HAL_UNLOCK(hqspi);
\r
1487 hqspi->RxXferCount = (data_size >> 2U);
\r
1492 /* Nothing to do */
\r
1495 if (status == HAL_OK)
\r
1497 /* Update state */
\r
1498 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
\r
1500 /* Clear interrupt */
\r
1501 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
\r
1503 /* Configure size and pointer of the handle */
\r
1504 hqspi->RxXferSize = hqspi->RxXferCount;
\r
1505 hqspi->pRxBuffPtr = pData;
\r
1507 /* Set the QSPI DMA transfer complete callback */
\r
1508 hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
\r
1510 /* Set the QSPI DMA Half transfer complete callback */
\r
1511 hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
\r
1513 /* Set the DMA error callback */
\r
1514 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
\r
1516 /* Clear the DMA abort callback */
\r
1517 hqspi->hdma->XferAbortCallback = NULL;
\r
1519 /* Configure the direction of the DMA */
\r
1520 hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
\r
1521 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
\r
1523 /* Enable the DMA Channel */
\r
1524 if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
\r
1526 /* Configure QSPI: CCR register with functional as indirect read */
\r
1527 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
\r
1529 /* Start the transfer by re-writing the address in AR register */
\r
1530 WRITE_REG(hqspi->Instance->AR, addr_reg);
\r
1532 /* Process unlocked */
\r
1533 __HAL_UNLOCK(hqspi);
\r
1535 /* Enable the QSPI transfer error Interrupt */
\r
1536 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
\r
1538 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
\r
1539 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
1543 status = HAL_ERROR;
\r
1544 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
\r
1545 hqspi->State = HAL_QSPI_STATE_READY;
\r
1547 /* Process unlocked */
\r
1548 __HAL_UNLOCK(hqspi);
\r
1554 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
\r
1555 status = HAL_ERROR;
\r
1557 /* Process unlocked */
\r
1558 __HAL_UNLOCK(hqspi);
\r
1563 status = HAL_BUSY;
\r
1565 /* Process unlocked */
\r
1566 __HAL_UNLOCK(hqspi);
\r
1573 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
\r
1574 * @param hqspi : QSPI handle
\r
1575 * @param cmd : structure that contains the command configuration information.
\r
1576 * @param cfg : structure that contains the polling configuration information.
\r
1577 * @param Timeout : Timeout duration
\r
1578 * @note This function is used only in Automatic Polling Mode
\r
1579 * @retval HAL status
\r
1581 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
\r
1583 HAL_StatusTypeDef status;
\r
1584 uint32_t tickstart = HAL_GetTick();
\r
1586 /* Check the parameters */
\r
1587 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
\r
1588 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
1590 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
\r
1593 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
\r
1594 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
1596 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
\r
1599 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
\r
1600 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
1602 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
\r
1605 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
\r
1606 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
\r
1608 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
\r
1609 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
\r
1610 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
\r
1612 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
\r
1613 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
\r
1614 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
\r
1616 /* Process locked */
\r
1617 __HAL_LOCK(hqspi);
\r
1619 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1621 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1623 /* Update state */
\r
1624 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
\r
1626 /* Wait till BUSY flag reset */
\r
1627 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
\r
1629 if (status == HAL_OK)
\r
1631 /* Configure QSPI: PSMAR register with the status match value */
\r
1632 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
\r
1634 /* Configure QSPI: PSMKR register with the status mask value */
\r
1635 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
\r
1637 /* Configure QSPI: PIR register with the interval value */
\r
1638 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
\r
1640 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
\r
1641 (otherwise there will be an infinite loop in blocking mode) */
\r
1642 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
\r
1643 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
\r
1645 /* Call the configuration function */
\r
1646 cmd->NbData = cfg->StatusBytesSize;
\r
1647 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
\r
1649 /* Wait until SM flag is set to go back in idle state */
\r
1650 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
\r
1652 if (status == HAL_OK)
\r
1654 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
\r
1656 /* Update state */
\r
1657 hqspi->State = HAL_QSPI_STATE_READY;
\r
1663 status = HAL_BUSY;
\r
1666 /* Process unlocked */
\r
1667 __HAL_UNLOCK(hqspi);
\r
1669 /* Return function status */
\r
1674 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
\r
1675 * @param hqspi : QSPI handle
\r
1676 * @param cmd : structure that contains the command configuration information.
\r
1677 * @param cfg : structure that contains the polling configuration information.
\r
1678 * @note This function is used only in Automatic Polling Mode
\r
1679 * @retval HAL status
\r
1681 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
\r
1683 HAL_StatusTypeDef status;
\r
1684 uint32_t tickstart = HAL_GetTick();
\r
1686 /* Check the parameters */
\r
1687 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
\r
1688 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
1690 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
\r
1693 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
\r
1694 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
1696 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
\r
1699 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
\r
1700 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
1702 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
\r
1705 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
\r
1706 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
\r
1708 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
\r
1709 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
\r
1710 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
\r
1712 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
\r
1713 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
\r
1714 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
\r
1715 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
\r
1717 /* Process locked */
\r
1718 __HAL_LOCK(hqspi);
\r
1720 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1722 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1724 /* Update state */
\r
1725 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
\r
1727 /* Wait till BUSY flag reset */
\r
1728 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
\r
1730 if (status == HAL_OK)
\r
1732 /* Configure QSPI: PSMAR register with the status match value */
\r
1733 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
\r
1735 /* Configure QSPI: PSMKR register with the status mask value */
\r
1736 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
\r
1738 /* Configure QSPI: PIR register with the interval value */
\r
1739 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
\r
1741 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
\r
1742 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
\r
1743 (cfg->MatchMode | cfg->AutomaticStop));
\r
1745 /* Clear interrupt */
\r
1746 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
\r
1748 /* Call the configuration function */
\r
1749 cmd->NbData = cfg->StatusBytesSize;
\r
1750 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
\r
1752 /* Process unlocked */
\r
1753 __HAL_UNLOCK(hqspi);
\r
1755 /* Enable the QSPI Transfer Error and status match Interrupt */
\r
1756 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
\r
1761 /* Process unlocked */
\r
1762 __HAL_UNLOCK(hqspi);
\r
1767 status = HAL_BUSY;
\r
1769 /* Process unlocked */
\r
1770 __HAL_UNLOCK(hqspi);
\r
1773 /* Return function status */
\r
1778 * @brief Configure the Memory Mapped mode.
\r
1779 * @param hqspi : QSPI handle
\r
1780 * @param cmd : structure that contains the command configuration information.
\r
1781 * @param cfg : structure that contains the memory mapped configuration information.
\r
1782 * @note This function is used only in Memory mapped Mode
\r
1783 * @retval HAL status
\r
1785 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
\r
1787 HAL_StatusTypeDef status;
\r
1788 uint32_t tickstart = HAL_GetTick();
\r
1790 /* Check the parameters */
\r
1791 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
\r
1792 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
1794 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
\r
1797 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
\r
1798 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
1800 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
\r
1803 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
\r
1804 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
1806 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
\r
1809 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
\r
1810 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
\r
1812 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
\r
1813 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
\r
1814 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
\r
1816 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
\r
1818 /* Process locked */
\r
1819 __HAL_LOCK(hqspi);
\r
1821 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
1823 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
\r
1825 /* Update state */
\r
1826 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
\r
1828 /* Wait till BUSY flag reset */
\r
1829 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
\r
1831 if (status == HAL_OK)
\r
1833 /* Configure QSPI: CR register with timeout counter enable */
\r
1834 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
\r
1836 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
\r
1838 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
\r
1840 /* Configure QSPI: LPTR register with the low-power timeout value */
\r
1841 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
\r
1843 /* Clear interrupt */
\r
1844 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
\r
1846 /* Enable the QSPI TimeOut Interrupt */
\r
1847 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
\r
1850 /* Call the configuration function */
\r
1851 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
\r
1856 status = HAL_BUSY;
\r
1859 /* Process unlocked */
\r
1860 __HAL_UNLOCK(hqspi);
\r
1862 /* Return function status */
\r
1867 * @brief Transfer Error callback.
\r
1868 * @param hqspi : QSPI handle
\r
1871 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
\r
1873 /* Prevent unused argument(s) compilation warning */
\r
1876 /* NOTE : This function should not be modified, when the callback is needed,
\r
1877 the HAL_QSPI_ErrorCallback could be implemented in the user file
\r
1882 * @brief Abort completed callback.
\r
1883 * @param hqspi : QSPI handle
\r
1886 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1888 /* Prevent unused argument(s) compilation warning */
\r
1891 /* NOTE: This function should not be modified, when the callback is needed,
\r
1892 the HAL_QSPI_AbortCpltCallback could be implemented in the user file
\r
1897 * @brief Command completed callback.
\r
1898 * @param hqspi : QSPI handle
\r
1901 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1903 /* Prevent unused argument(s) compilation warning */
\r
1906 /* NOTE: This function should not be modified, when the callback is needed,
\r
1907 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
\r
1912 * @brief Rx Transfer completed callback.
\r
1913 * @param hqspi : QSPI handle
\r
1916 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1918 /* Prevent unused argument(s) compilation warning */
\r
1921 /* NOTE: This function should not be modified, when the callback is needed,
\r
1922 the HAL_QSPI_RxCpltCallback could be implemented in the user file
\r
1927 * @brief Tx Transfer completed callback.
\r
1928 * @param hqspi : QSPI handle
\r
1931 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1933 /* Prevent unused argument(s) compilation warning */
\r
1936 /* NOTE: This function should not be modified, when the callback is needed,
\r
1937 the HAL_QSPI_TxCpltCallback could be implemented in the user file
\r
1942 * @brief Rx Half Transfer completed callback.
\r
1943 * @param hqspi : QSPI handle
\r
1946 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1948 /* Prevent unused argument(s) compilation warning */
\r
1951 /* NOTE: This function should not be modified, when the callback is needed,
\r
1952 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
\r
1957 * @brief Tx Half Transfer completed callback.
\r
1958 * @param hqspi : QSPI handle
\r
1961 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
\r
1963 /* Prevent unused argument(s) compilation warning */
\r
1966 /* NOTE: This function should not be modified, when the callback is needed,
\r
1967 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
\r
1972 * @brief FIFO Threshold callback.
\r
1973 * @param hqspi : QSPI handle
\r
1976 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
\r
1978 /* Prevent unused argument(s) compilation warning */
\r
1981 /* NOTE : This function should not be modified, when the callback is needed,
\r
1982 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
\r
1987 * @brief Status Match callback.
\r
1988 * @param hqspi : QSPI handle
\r
1991 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
\r
1993 /* Prevent unused argument(s) compilation warning */
\r
1996 /* NOTE : This function should not be modified, when the callback is needed,
\r
1997 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
\r
2002 * @brief Timeout callback.
\r
2003 * @param hqspi : QSPI handle
\r
2006 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
\r
2008 /* Prevent unused argument(s) compilation warning */
\r
2011 /* NOTE : This function should not be modified, when the callback is needed,
\r
2012 the HAL_QSPI_TimeOutCallback could be implemented in the user file
\r
2015 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
2017 * @brief Register a User QSPI Callback
\r
2018 * To be used instead of the weak (surcharged) predefined callback
\r
2019 * @param hqspi : QSPI handle
\r
2020 * @param CallbackId : ID of the callback to be registered
\r
2021 * This parameter can be one of the following values:
\r
2022 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
\r
2023 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
\r
2024 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
\r
2025 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
\r
2026 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
\r
2027 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
\r
2028 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
\r
2029 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
\r
2030 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
\r
2031 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
\r
2032 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
\r
2033 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
\r
2034 * @param pCallback : pointer to the Callback function
\r
2037 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
\r
2039 HAL_StatusTypeDef status = HAL_OK;
\r
2041 if(pCallback == NULL)
\r
2043 /* Update the error code */
\r
2044 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2048 /* Process locked */
\r
2049 __HAL_LOCK(hqspi);
\r
2051 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
2053 switch (CallbackId)
\r
2055 case HAL_QSPI_ERROR_CB_ID :
\r
2056 hqspi->ErrorCallback = pCallback;
\r
2058 case HAL_QSPI_ABORT_CB_ID :
\r
2059 hqspi->AbortCpltCallback = pCallback;
\r
2061 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
\r
2062 hqspi->FifoThresholdCallback = pCallback;
\r
2064 case HAL_QSPI_CMD_CPLT_CB_ID :
\r
2065 hqspi->CmdCpltCallback = pCallback;
\r
2067 case HAL_QSPI_RX_CPLT_CB_ID :
\r
2068 hqspi->RxCpltCallback = pCallback;
\r
2070 case HAL_QSPI_TX_CPLT_CB_ID :
\r
2071 hqspi->TxCpltCallback = pCallback;
\r
2073 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
\r
2074 hqspi->RxHalfCpltCallback = pCallback;
\r
2076 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
\r
2077 hqspi->TxHalfCpltCallback = pCallback;
\r
2079 case HAL_QSPI_STATUS_MATCH_CB_ID :
\r
2080 hqspi->StatusMatchCallback = pCallback;
\r
2082 case HAL_QSPI_TIMEOUT_CB_ID :
\r
2083 hqspi->TimeOutCallback = pCallback;
\r
2085 case HAL_QSPI_MSP_INIT_CB_ID :
\r
2086 hqspi->MspInitCallback = pCallback;
\r
2088 case HAL_QSPI_MSP_DEINIT_CB_ID :
\r
2089 hqspi->MspDeInitCallback = pCallback;
\r
2092 /* Update the error code */
\r
2093 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2094 /* update return status */
\r
2095 status = HAL_ERROR;
\r
2099 else if (hqspi->State == HAL_QSPI_STATE_RESET)
\r
2101 switch (CallbackId)
\r
2103 case HAL_QSPI_MSP_INIT_CB_ID :
\r
2104 hqspi->MspInitCallback = pCallback;
\r
2106 case HAL_QSPI_MSP_DEINIT_CB_ID :
\r
2107 hqspi->MspDeInitCallback = pCallback;
\r
2110 /* Update the error code */
\r
2111 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2112 /* update return status */
\r
2113 status = HAL_ERROR;
\r
2119 /* Update the error code */
\r
2120 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2121 /* update return status */
\r
2122 status = HAL_ERROR;
\r
2125 /* Release Lock */
\r
2126 __HAL_UNLOCK(hqspi);
\r
2131 * @brief Unregister a User QSPI Callback
\r
2132 * QSPI Callback is redirected to the weak (surcharged) predefined callback
\r
2133 * @param hqspi : QSPI handle
\r
2134 * @param CallbackId : ID of the callback to be unregistered
\r
2135 * This parameter can be one of the following values:
\r
2136 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
\r
2137 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
\r
2138 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
\r
2139 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
\r
2140 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
\r
2141 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
\r
2142 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
\r
2143 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
\r
2144 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
\r
2145 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
\r
2146 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
\r
2147 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
\r
2150 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
\r
2152 HAL_StatusTypeDef status = HAL_OK;
\r
2154 /* Process locked */
\r
2155 __HAL_LOCK(hqspi);
\r
2157 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
2159 switch (CallbackId)
\r
2161 case HAL_QSPI_ERROR_CB_ID :
\r
2162 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
\r
2164 case HAL_QSPI_ABORT_CB_ID :
\r
2165 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
\r
2167 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
\r
2168 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
\r
2170 case HAL_QSPI_CMD_CPLT_CB_ID :
\r
2171 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
\r
2173 case HAL_QSPI_RX_CPLT_CB_ID :
\r
2174 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
\r
2176 case HAL_QSPI_TX_CPLT_CB_ID :
\r
2177 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
\r
2179 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
\r
2180 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
\r
2182 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
\r
2183 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
\r
2185 case HAL_QSPI_STATUS_MATCH_CB_ID :
\r
2186 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
\r
2188 case HAL_QSPI_TIMEOUT_CB_ID :
\r
2189 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
\r
2191 case HAL_QSPI_MSP_INIT_CB_ID :
\r
2192 hqspi->MspInitCallback = HAL_QSPI_MspInit;
\r
2194 case HAL_QSPI_MSP_DEINIT_CB_ID :
\r
2195 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
\r
2198 /* Update the error code */
\r
2199 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2200 /* update return status */
\r
2201 status = HAL_ERROR;
\r
2205 else if (hqspi->State == HAL_QSPI_STATE_RESET)
\r
2207 switch (CallbackId)
\r
2209 case HAL_QSPI_MSP_INIT_CB_ID :
\r
2210 hqspi->MspInitCallback = HAL_QSPI_MspInit;
\r
2212 case HAL_QSPI_MSP_DEINIT_CB_ID :
\r
2213 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
\r
2216 /* Update the error code */
\r
2217 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2218 /* update return status */
\r
2219 status = HAL_ERROR;
\r
2225 /* Update the error code */
\r
2226 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
\r
2227 /* update return status */
\r
2228 status = HAL_ERROR;
\r
2231 /* Release Lock */
\r
2232 __HAL_UNLOCK(hqspi);
\r
2241 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
\r
2242 * @brief QSPI control and State functions
\r
2245 ===============================================================================
\r
2246 ##### Peripheral Control and State functions #####
\r
2247 ===============================================================================
\r
2249 This subsection provides a set of functions allowing to :
\r
2250 (+) Check in run-time the state of the driver.
\r
2251 (+) Check the error code set during last operation.
\r
2252 (+) Abort any operation.
\r
2260 * @brief Return the QSPI handle state.
\r
2261 * @param hqspi : QSPI handle
\r
2262 * @retval HAL state
\r
2264 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
\r
2266 /* Return QSPI handle state */
\r
2267 return hqspi->State;
\r
2271 * @brief Return the QSPI error code.
\r
2272 * @param hqspi : QSPI handle
\r
2273 * @retval QSPI Error Code
\r
2275 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
\r
2277 return hqspi->ErrorCode;
\r
2281 * @brief Abort the current transmission.
\r
2282 * @param hqspi : QSPI handle
\r
2283 * @retval HAL status
\r
2285 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
\r
2287 HAL_StatusTypeDef status = HAL_OK;
\r
2288 uint32_t tickstart = HAL_GetTick();
\r
2290 /* Check if the state is in one of the busy states */
\r
2291 if (((uint32_t)hqspi->State & 0x2U) != 0U)
\r
2293 /* Process unlocked */
\r
2294 __HAL_UNLOCK(hqspi);
\r
2296 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
\r
2298 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
2299 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
2301 /* Abort DMA channel */
\r
2302 status = HAL_DMA_Abort(hqspi->hdma);
\r
2303 if(status != HAL_OK)
\r
2305 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
\r
2309 /* Configure QSPI: CR register with Abort request */
\r
2310 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
\r
2312 /* Wait until TC flag is set to go back in idle state */
\r
2313 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
\r
2315 if (status == HAL_OK)
\r
2317 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
2319 /* Wait until BUSY flag is reset */
\r
2320 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
\r
2323 if (status == HAL_OK)
\r
2325 /* Reset functional mode configuration to indirect write mode by default */
\r
2326 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
\r
2328 /* Update state */
\r
2329 hqspi->State = HAL_QSPI_STATE_READY;
\r
2337 * @brief Abort the current transmission (non-blocking function)
\r
2338 * @param hqspi : QSPI handle
\r
2339 * @retval HAL status
\r
2341 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
\r
2343 HAL_StatusTypeDef status = HAL_OK;
\r
2345 /* Check if the state is in one of the busy states */
\r
2346 if (((uint32_t)hqspi->State & 0x2U) != 0U)
\r
2348 /* Process unlocked */
\r
2349 __HAL_UNLOCK(hqspi);
\r
2351 /* Update QSPI state */
\r
2352 hqspi->State = HAL_QSPI_STATE_ABORT;
\r
2354 /* Disable all interrupts */
\r
2355 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
\r
2357 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
\r
2359 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
2360 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
2362 /* Abort DMA channel */
\r
2363 hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
\r
2364 if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
\r
2366 /* Change state of QSPI */
\r
2367 hqspi->State = HAL_QSPI_STATE_READY;
\r
2369 /* Abort Complete callback */
\r
2370 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
2371 hqspi->AbortCpltCallback(hqspi);
\r
2373 HAL_QSPI_AbortCpltCallback(hqspi);
\r
2379 /* Clear interrupt */
\r
2380 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
2382 /* Enable the QSPI Transfer Complete Interrupt */
\r
2383 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
\r
2385 /* Configure QSPI: CR register with Abort request */
\r
2386 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
\r
2392 /** @brief Set QSPI timeout.
\r
2393 * @param hqspi : QSPI handle.
\r
2394 * @param Timeout : Timeout for the QSPI memory access.
\r
2397 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
\r
2399 hqspi->Timeout = Timeout;
\r
2402 /** @brief Set QSPI Fifo threshold.
\r
2403 * @param hqspi : QSPI handle.
\r
2404 * @param Threshold : Threshold of the Fifo (value between 1 and 16).
\r
2405 * @retval HAL status
\r
2407 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
\r
2409 HAL_StatusTypeDef status = HAL_OK;
\r
2411 /* Process locked */
\r
2412 __HAL_LOCK(hqspi);
\r
2414 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
2416 /* Synchronize init structure with new FIFO threshold value */
\r
2417 hqspi->Init.FifoThreshold = Threshold;
\r
2419 /* Configure QSPI FIFO Threshold */
\r
2420 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
\r
2421 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
\r
2425 status = HAL_BUSY;
\r
2428 /* Process unlocked */
\r
2429 __HAL_UNLOCK(hqspi);
\r
2431 /* Return function status */
\r
2435 /** @brief Get QSPI Fifo threshold.
\r
2436 * @param hqspi : QSPI handle.
\r
2437 * @retval Fifo threshold (value between 1 and 16)
\r
2439 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
\r
2441 return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
\r
2444 #if defined(QUADSPI_CR_DFM)
\r
2445 /** @brief Set FlashID.
\r
2446 * @param hqspi : QSPI handle.
\r
2447 * @param FlashID : Index of the flash memory to be accessed.
\r
2448 * This parameter can be a value of @ref QSPI_Flash_Select.
\r
2449 * @note The FlashID is ignored when dual flash mode is enabled.
\r
2450 * @retval HAL status
\r
2452 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
\r
2454 HAL_StatusTypeDef status = HAL_OK;
\r
2456 /* Check the parameter */
\r
2457 assert_param(IS_QSPI_FLASH_ID(FlashID));
\r
2459 /* Process locked */
\r
2460 __HAL_LOCK(hqspi);
\r
2462 if(hqspi->State == HAL_QSPI_STATE_READY)
\r
2464 /* Synchronize init structure with new FlashID value */
\r
2465 hqspi->Init.FlashID = FlashID;
\r
2467 /* Configure QSPI FlashID */
\r
2468 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
\r
2472 status = HAL_BUSY;
\r
2475 /* Process unlocked */
\r
2476 __HAL_UNLOCK(hqspi);
\r
2478 /* Return function status */
\r
2491 /** @defgroup QSPI_Private_Functions QSPI Private Functions
\r
2496 * @brief DMA QSPI receive process complete callback.
\r
2497 * @param hdma : DMA handle
\r
2500 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
\r
2502 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
\r
2503 hqspi->RxXferCount = 0U;
\r
2505 /* Enable the QSPI transfer complete Interrupt */
\r
2506 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
\r
2510 * @brief DMA QSPI transmit process complete callback.
\r
2511 * @param hdma : DMA handle
\r
2514 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
\r
2516 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
\r
2517 hqspi->TxXferCount = 0U;
\r
2519 /* Enable the QSPI transfer complete Interrupt */
\r
2520 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
\r
2524 * @brief DMA QSPI receive process half complete callback.
\r
2525 * @param hdma : DMA handle
\r
2528 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
\r
2530 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
\r
2532 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
2533 hqspi->RxHalfCpltCallback(hqspi);
\r
2535 HAL_QSPI_RxHalfCpltCallback(hqspi);
\r
2540 * @brief DMA QSPI transmit process half complete callback.
\r
2541 * @param hdma : DMA handle
\r
2544 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
\r
2546 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
\r
2548 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
2549 hqspi->TxHalfCpltCallback(hqspi);
\r
2551 HAL_QSPI_TxHalfCpltCallback(hqspi);
\r
2556 * @brief DMA QSPI communication error callback.
\r
2557 * @param hdma : DMA handle
\r
2560 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
\r
2562 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
\r
2564 hqspi->RxXferCount = 0U;
\r
2565 hqspi->TxXferCount = 0U;
\r
2566 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
\r
2568 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
\r
2569 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
\r
2571 /* Abort the QSPI */
\r
2572 (void)HAL_QSPI_Abort_IT(hqspi);
\r
2577 * @brief DMA QSPI abort complete callback.
\r
2578 * @param hdma : DMA handle
\r
2581 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
\r
2583 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
\r
2585 hqspi->RxXferCount = 0U;
\r
2586 hqspi->TxXferCount = 0U;
\r
2588 if(hqspi->State == HAL_QSPI_STATE_ABORT)
\r
2590 /* DMA Abort called by QSPI abort */
\r
2591 /* Clear interrupt */
\r
2592 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
\r
2594 /* Enable the QSPI Transfer Complete Interrupt */
\r
2595 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
\r
2597 /* Configure QSPI: CR register with Abort request */
\r
2598 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
\r
2602 /* DMA Abort called due to a transfer error interrupt */
\r
2603 /* Change state of QSPI */
\r
2604 hqspi->State = HAL_QSPI_STATE_READY;
\r
2606 /* Error callback */
\r
2607 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
\r
2608 hqspi->ErrorCallback(hqspi);
\r
2610 HAL_QSPI_ErrorCallback(hqspi);
\r
2616 * @brief Wait for a flag state until timeout.
\r
2617 * @param hqspi : QSPI handle
\r
2618 * @param Flag : Flag checked
\r
2619 * @param State : Value of the flag expected
\r
2620 * @param Tickstart : Tick start value
\r
2621 * @param Timeout : Duration of the timeout
\r
2622 * @retval HAL status
\r
2624 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
\r
2625 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
\r
2627 /* Wait until flag is in expected state */
\r
2628 while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
\r
2630 /* Check for the Timeout */
\r
2631 if (Timeout != HAL_MAX_DELAY)
\r
2633 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
\r
2635 hqspi->State = HAL_QSPI_STATE_ERROR;
\r
2636 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
\r
2646 * @brief Configure the communication registers.
\r
2647 * @param hqspi : QSPI handle
\r
2648 * @param cmd : structure that contains the command configuration information
\r
2649 * @param FunctionalMode : functional mode to configured
\r
2650 * This parameter can be one of the following values:
\r
2651 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
\r
2652 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
\r
2653 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
\r
2654 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
\r
2657 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
\r
2659 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
\r
2661 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
\r
2663 /* Configure QSPI: DLR register with the number of data to read or write */
\r
2664 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
\r
2667 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
\r
2669 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
2671 /* Configure QSPI: ABR register with alternate bytes value */
\r
2672 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
\r
2674 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
2676 /*---- Command with instruction, address and alternate bytes ----*/
\r
2677 /* Configure QSPI: CCR register with all communications parameters */
\r
2678 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2679 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2680 cmd->AlternateBytesSize | cmd->AlternateByteMode |
\r
2681 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
\r
2682 cmd->Instruction | FunctionalMode));
\r
2684 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
\r
2686 /* Configure QSPI: AR register with address value */
\r
2687 WRITE_REG(hqspi->Instance->AR, cmd->Address);
\r
2692 /*---- Command with instruction and alternate bytes ----*/
\r
2693 /* Configure QSPI: CCR register with all communications parameters */
\r
2694 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2695 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2696 cmd->AlternateBytesSize | cmd->AlternateByteMode |
\r
2697 cmd->AddressMode | cmd->InstructionMode |
\r
2698 cmd->Instruction | FunctionalMode));
\r
2703 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
2705 /*---- Command with instruction and address ----*/
\r
2706 /* Configure QSPI: CCR register with all communications parameters */
\r
2707 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2708 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2709 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
\r
2710 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
\r
2712 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
\r
2714 /* Configure QSPI: AR register with address value */
\r
2715 WRITE_REG(hqspi->Instance->AR, cmd->Address);
\r
2720 /*---- Command with only instruction ----*/
\r
2721 /* Configure QSPI: CCR register with all communications parameters */
\r
2722 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2723 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2724 cmd->AlternateByteMode | cmd->AddressMode |
\r
2725 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
\r
2731 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
\r
2733 /* Configure QSPI: ABR register with alternate bytes value */
\r
2734 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
\r
2736 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
2738 /*---- Command with address and alternate bytes ----*/
\r
2739 /* Configure QSPI: CCR register with all communications parameters */
\r
2740 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2741 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2742 cmd->AlternateBytesSize | cmd->AlternateByteMode |
\r
2743 cmd->AddressSize | cmd->AddressMode |
\r
2744 cmd->InstructionMode | FunctionalMode));
\r
2746 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
\r
2748 /* Configure QSPI: AR register with address value */
\r
2749 WRITE_REG(hqspi->Instance->AR, cmd->Address);
\r
2754 /*---- Command with only alternate bytes ----*/
\r
2755 /* Configure QSPI: CCR register with all communications parameters */
\r
2756 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2757 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2758 cmd->AlternateBytesSize | cmd->AlternateByteMode |
\r
2759 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
\r
2764 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
\r
2766 /*---- Command with only address ----*/
\r
2767 /* Configure QSPI: CCR register with all communications parameters */
\r
2768 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2769 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2770 cmd->AlternateByteMode | cmd->AddressSize |
\r
2771 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
\r
2773 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
\r
2775 /* Configure QSPI: AR register with address value */
\r
2776 WRITE_REG(hqspi->Instance->AR, cmd->Address);
\r
2781 /*---- Command with only data phase ----*/
\r
2782 if (cmd->DataMode != QSPI_DATA_NONE)
\r
2784 /* Configure QSPI: CCR register with all communications parameters */
\r
2785 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
\r
2786 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
\r
2787 cmd->AlternateByteMode | cmd->AddressMode |
\r
2788 cmd->InstructionMode | FunctionalMode));
\r
2803 #endif /* HAL_QSPI_MODULE_ENABLED */
\r
2812 #endif /* defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2) */
\r
2814 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r