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