1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_hal_qspi.c
4 * @author MCD Application Team
5 * @brief QSPI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the QuadSPI interface (QSPI).
8 * + Initialization and de-initialization functions
9 * + Indirect functional mode management
10 * + Memory-mapped functional mode management
11 * + Auto-polling functional mode management
12 * + Interrupts and flags management
13 * + MDMA channel configuration for indirect functional mode
14 * + Errors management and abort functionality
15 *
16 ******************************************************************************
17 * @attention
18 *
19 * <h2><center>© Copyright (c) 2019 STMicroelectronics.
20 * All rights reserved.</center></h2>
21 *
22 * This software component is licensed by ST under BSD 3-Clause license,
23 * the "License"; You may not use this file except in compliance with the
24 * License. You may obtain a copy of the License at:
25 * opensource.org/licenses/BSD-3-Clause
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 MDMA
44 with __HAL_RCC_MDMA_CLK_ENABLE(), configure MDMA with HAL_MDMA_Init(),
45 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
46 MDMA 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_AbortIT() 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 @ref 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 @ref 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 @ref 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 @ref HAL_QSPI_Init
184 and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
185 If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref 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 @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
194 or @ref 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 /* Includes ------------------------------------------------------------------*/
210 #include "stm32mp1xx_hal.h"
211
212 #if defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2)
213
214 /** @addtogroup STM32MP1xx_HAL_Driver
215 * @{
216 */
217
218 /** @defgroup QSPI QSPI
219 * @brief QSPI HAL module driver
220 * @{
221 */
222 #ifdef HAL_QSPI_MODULE_ENABLED
223
224 /* Private typedef -----------------------------------------------------------*/
225
226 /* Private define ------------------------------------------------------------*/
227 /** @defgroup QSPI_Private_Constants QSPI Private Constants
228 * @{
229 */
230 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
232 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
233 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
234 /**
235 * @}
236 */
237
238 /* Private macro -------------------------------------------------------------*/
239 /** @defgroup QSPI_Private_Macros QSPI Private Macros
240 * @{
241 */
242 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
243 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
244 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
245 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
246 /**
247 * @}
248 */
249
250 /* Private variables ---------------------------------------------------------*/
251
252 /* Private function prototypes -----------------------------------------------*/
253 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma);
254 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma);
255 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma);
256 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma);
257 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
258 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
259
260 /* Exported functions --------------------------------------------------------*/
261
262 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
263 * @{
264 */
265
266 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
267 * @brief Initialization and Configuration functions
268 *
269 @verbatim
270 ===============================================================================
271 ##### Initialization and Configuration functions #####
272 ===============================================================================
273 [..]
274 This subsection provides a set of functions allowing to :
275 (+) Initialize the QuadSPI.
276 (+) De-initialize the QuadSPI.
277
278 @endverbatim
279 * @{
280 */
281
282 /**
283 * @brief Initialize the QSPI mode according to the specified parameters
284 * in the QSPI_InitTypeDef and initialize the associated handle.
285 * @param hqspi : QSPI handle
286 * @retval HAL status
287 */
HAL_QSPI_Init(QSPI_HandleTypeDef * hqspi)288 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
289 {
290 HAL_StatusTypeDef status;
291 uint32_t tickstart = HAL_GetTick();
292
293 /* Check the QSPI handle allocation */
294 if(hqspi == NULL)
295 {
296 return HAL_ERROR;
297 }
298
299 /* Check the parameters */
300 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
301 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
302 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
303 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
304 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
305 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
306 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
307 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
308
309 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
310 {
311 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
312 }
313
314 /* Process locked */
315 __HAL_LOCK(hqspi);
316
317 if(hqspi->State == HAL_QSPI_STATE_RESET)
318 {
319 /* Allocate lock resource and initialize it */
320 hqspi->Lock = HAL_UNLOCKED;
321
322 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
323 /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
324 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
325 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
326 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
327 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
328 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
329 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
330 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
331 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
332 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
333 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
334
335 if(hqspi->MspInitCallback == NULL)
336 {
337 hqspi->MspInitCallback = HAL_QSPI_MspInit;
338 }
339
340 /* Init the low level hardware */
341 hqspi->MspInitCallback(hqspi);
342 #else
343 /* Init the low level hardware : GPIO, CLOCK */
344 HAL_QSPI_MspInit(hqspi);
345 #endif
346
347 /* Configure the default timeout for the QSPI memory access */
348 HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
349 }
350
351 /* Configure QSPI FIFO Threshold */
352 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
353 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
354
355 /* Wait till BUSY flag reset */
356 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
357
358 if(status == HAL_OK)
359 {
360 /* Configure QSPI Clock Prescaler and Sample Shift */
361 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
362 ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
363 hqspi->Init.SampleShifting | hqspi->Init.FlashID | hqspi->Init.DualFlash));
364
365 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
366 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
367 ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
368 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
369
370 /* Enable the QSPI peripheral */
371 __HAL_QSPI_ENABLE(hqspi);
372
373 /* Set QSPI error code to none */
374 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
375
376 /* Initialize the QSPI state */
377 hqspi->State = HAL_QSPI_STATE_READY;
378 }
379
380 /* Release Lock */
381 __HAL_UNLOCK(hqspi);
382
383 /* Return function status */
384 return status;
385 }
386
387 /**
388 * @brief De-Initialize the QSPI peripheral.
389 * @param hqspi : QSPI handle
390 * @retval HAL status
391 */
HAL_QSPI_DeInit(QSPI_HandleTypeDef * hqspi)392 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
393 {
394 /* Check the QSPI handle allocation */
395 if(hqspi == NULL)
396 {
397 return HAL_ERROR;
398 }
399
400 /* Process locked */
401 __HAL_LOCK(hqspi);
402
403 /* Disable the QSPI Peripheral Clock */
404 __HAL_QSPI_DISABLE(hqspi);
405
406 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
407 if(hqspi->MspDeInitCallback == NULL)
408 {
409 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
410 }
411
412 /* DeInit the low level hardware */
413 hqspi->MspDeInitCallback(hqspi);
414 #else
415 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
416 HAL_QSPI_MspDeInit(hqspi);
417 #endif
418
419 /* Set QSPI error code to none */
420 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
421
422 /* Initialize the QSPI state */
423 hqspi->State = HAL_QSPI_STATE_RESET;
424
425 /* Release Lock */
426 __HAL_UNLOCK(hqspi);
427
428 return HAL_OK;
429 }
430
431 /**
432 * @brief Initialize the QSPI MSP.
433 * @param hqspi : QSPI handle
434 * @retval None
435 */
HAL_QSPI_MspInit(QSPI_HandleTypeDef * hqspi)436 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
437 {
438 /* Prevent unused argument(s) compilation warning */
439 UNUSED(hqspi);
440
441 /* NOTE : This function should not be modified, when the callback is needed,
442 the HAL_QSPI_MspInit can be implemented in the user file
443 */
444 }
445
446 /**
447 * @brief DeInitialize the QSPI MSP.
448 * @param hqspi : QSPI handle
449 * @retval None
450 */
HAL_QSPI_MspDeInit(QSPI_HandleTypeDef * hqspi)451 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
452 {
453 /* Prevent unused argument(s) compilation warning */
454 UNUSED(hqspi);
455
456 /* NOTE : This function should not be modified, when the callback is needed,
457 the HAL_QSPI_MspDeInit can be implemented in the user file
458 */
459 }
460
461 /**
462 * @}
463 */
464
465 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
466 * @brief QSPI Transmit/Receive functions
467 *
468 @verbatim
469 ===============================================================================
470 ##### IO operation functions #####
471 ===============================================================================
472 [..]
473 This subsection provides a set of functions allowing to :
474 (+) Handle the interrupts.
475 (+) Handle the command sequence.
476 (+) Transmit data in blocking, interrupt or DMA mode.
477 (+) Receive data in blocking, interrupt or DMA mode.
478 (+) Manage the auto-polling functional mode.
479 (+) Manage the memory-mapped functional mode.
480
481 @endverbatim
482 * @{
483 */
484
485 /**
486 * @brief Handle QSPI interrupt request.
487 * @param hqspi : QSPI handle
488 * @retval None
489 */
HAL_QSPI_IRQHandler(QSPI_HandleTypeDef * hqspi)490 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
491 {
492 __IO uint32_t *data_reg;
493 uint32_t flag = READ_REG(hqspi->Instance->SR);
494 uint32_t itsource = READ_REG(hqspi->Instance->CR);
495
496 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
497 if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
498 {
499 data_reg = &hqspi->Instance->DR;
500
501 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
502 {
503 /* Transmission process */
504 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
505 {
506 if (hqspi->TxXferCount > 0U)
507 {
508 /* Fill the FIFO until the threshold is reached */
509 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
510 hqspi->pTxBuffPtr++;
511 hqspi->TxXferCount--;
512 }
513 else
514 {
515 /* No more data available for the transfer */
516 /* Disable the QSPI FIFO Threshold Interrupt */
517 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
518 break;
519 }
520 }
521 }
522 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
523 {
524 /* Receiving Process */
525 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
526 {
527 if (hqspi->RxXferCount > 0U)
528 {
529 /* Read the FIFO until the threshold is reached */
530 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
531 hqspi->pRxBuffPtr++;
532 hqspi->RxXferCount--;
533 }
534 else
535 {
536 /* All data have been received for the transfer */
537 /* Disable the QSPI FIFO Threshold Interrupt */
538 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
539 break;
540 }
541 }
542 }
543 else
544 {
545 /* Nothing to do */
546 }
547
548 /* FIFO Threshold callback */
549 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
550 hqspi->FifoThresholdCallback(hqspi);
551 #else
552 HAL_QSPI_FifoThresholdCallback(hqspi);
553 #endif
554 }
555
556 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
557 else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
558 {
559 /* Clear interrupt */
560 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
561
562 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
563 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
564
565 /* Transfer complete callback */
566 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
567 {
568 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
569 {
570 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
571 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
572
573 /* Disable the MDMA channel */
574 __HAL_MDMA_DISABLE(hqspi->hmdma);
575 }
576
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 MDMA channel */
596 __HAL_MDMA_DISABLE(hqspi->hmdma);
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
619 /* Change state of QSPI */
620 hqspi->State = HAL_QSPI_STATE_READY;
621
622 /* RX Complete callback */
623 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
624 hqspi->RxCpltCallback(hqspi);
625 #else
626 HAL_QSPI_RxCpltCallback(hqspi);
627 #endif
628 }
629 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
630 {
631 /* Change state of QSPI */
632 hqspi->State = HAL_QSPI_STATE_READY;
633
634 /* Command Complete callback */
635 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
636 hqspi->CmdCpltCallback(hqspi);
637 #else
638 HAL_QSPI_CmdCpltCallback(hqspi);
639 #endif
640 }
641 else if(hqspi->State == HAL_QSPI_STATE_ABORT)
642 {
643 /* Reset functional mode configuration to indirect write mode by default */
644 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
645
646 /* Change state of QSPI */
647 hqspi->State = HAL_QSPI_STATE_READY;
648
649 if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
650 {
651 /* Abort called by the user */
652
653 /* Abort Complete callback */
654 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
655 hqspi->AbortCpltCallback(hqspi);
656 #else
657 HAL_QSPI_AbortCpltCallback(hqspi);
658 #endif
659 }
660 else
661 {
662 /* Abort due to an error (eg : MDMA error) */
663
664 /* Error callback */
665 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
666 hqspi->ErrorCallback(hqspi);
667 #else
668 HAL_QSPI_ErrorCallback(hqspi);
669 #endif
670 }
671 }
672 else
673 {
674 /* Nothing to do */
675 }
676 }
677
678 /* QSPI Status Match interrupt occurred ------------------------------------*/
679 else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
680 {
681 /* Clear interrupt */
682 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
683
684 /* Check if the automatic poll mode stop is activated */
685 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
686 {
687 /* Disable the QSPI Transfer Error and Status Match Interrupts */
688 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
689
690 /* Change state of QSPI */
691 hqspi->State = HAL_QSPI_STATE_READY;
692 }
693
694 /* Status match callback */
695 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
696 hqspi->StatusMatchCallback(hqspi);
697 #else
698 HAL_QSPI_StatusMatchCallback(hqspi);
699 #endif
700 }
701
702 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
703 else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
704 {
705 /* Clear interrupt */
706 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
707
708 /* Disable all the QSPI Interrupts */
709 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
710
711 /* Set error code */
712 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
713
714 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
715 {
716 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
717 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
718
719 /* Disable the MDMA channel */
720 hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
721 if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
722 {
723 /* Set error code to DMA */
724 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
725
726 /* Change state of QSPI */
727 hqspi->State = HAL_QSPI_STATE_READY;
728
729 /* Error callback */
730 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
731 hqspi->ErrorCallback(hqspi);
732 #else
733 HAL_QSPI_ErrorCallback(hqspi);
734 #endif
735 }
736 }
737 else
738 {
739 /* Change state of QSPI */
740 hqspi->State = HAL_QSPI_STATE_READY;
741
742 /* Error callback */
743 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
744 hqspi->ErrorCallback(hqspi);
745 #else
746 HAL_QSPI_ErrorCallback(hqspi);
747 #endif
748 }
749 }
750
751 /* QSPI Timeout interrupt occurred -----------------------------------------*/
752 else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
753 {
754 /* Clear interrupt */
755 WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
756
757 /* Timeout callback */
758 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
759 hqspi->TimeOutCallback(hqspi);
760 #else
761 HAL_QSPI_TimeOutCallback(hqspi);
762 #endif
763 }
764
765 else
766 {
767 /* Nothing to do */
768 }
769 }
770
771 /**
772 * @brief Set the command configuration.
773 * @param hqspi : QSPI handle
774 * @param cmd : structure that contains the command configuration information
775 * @param Timeout : Timeout duration
776 * @note This function is used only in Indirect Read or Write Modes
777 * @retval HAL status
778 */
HAL_QSPI_Command(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t Timeout)779 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
780 {
781 HAL_StatusTypeDef status;
782 uint32_t tickstart = HAL_GetTick();
783
784 /* Check the parameters */
785 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
786 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
787 {
788 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
789 }
790
791 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
792 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
793 {
794 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
795 }
796
797 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
798 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
799 {
800 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
801 }
802
803 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
804 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
805
806 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
807 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
808 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
809
810 /* Process locked */
811 __HAL_LOCK(hqspi);
812
813 if(hqspi->State == HAL_QSPI_STATE_READY)
814 {
815 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
816
817 /* Update QSPI state */
818 hqspi->State = HAL_QSPI_STATE_BUSY;
819
820 /* Wait till BUSY flag reset */
821 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
822
823 if (status == HAL_OK)
824 {
825 /* Call the configuration function */
826 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
827
828 if (cmd->DataMode == QSPI_DATA_NONE)
829 {
830 /* When there is no data phase, the transfer start as soon as the configuration is done
831 so wait until TC flag is set to go back in idle state */
832 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
833
834 if (status == HAL_OK)
835 {
836 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
837
838 /* Update QSPI state */
839 hqspi->State = HAL_QSPI_STATE_READY;
840 }
841 }
842 else
843 {
844 /* Update QSPI state */
845 hqspi->State = HAL_QSPI_STATE_READY;
846 }
847 }
848 }
849 else
850 {
851 status = HAL_BUSY;
852 }
853
854 /* Process unlocked */
855 __HAL_UNLOCK(hqspi);
856
857 /* Return function status */
858 return status;
859 }
860
861 /**
862 * @brief Set the command configuration in interrupt mode.
863 * @param hqspi : QSPI handle
864 * @param cmd : structure that contains the command configuration information
865 * @note This function is used only in Indirect Read or Write Modes
866 * @retval HAL status
867 */
HAL_QSPI_Command_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd)868 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
869 {
870 HAL_StatusTypeDef status;
871 uint32_t tickstart = HAL_GetTick();
872
873 /* Check the parameters */
874 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
875 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
876 {
877 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
878 }
879
880 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
881 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
882 {
883 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
884 }
885
886 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
887 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
888 {
889 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
890 }
891
892 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
893 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
894
895 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
896 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
897 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
898
899 /* Process locked */
900 __HAL_LOCK(hqspi);
901
902 if(hqspi->State == HAL_QSPI_STATE_READY)
903 {
904 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
905
906 /* Update QSPI state */
907 hqspi->State = HAL_QSPI_STATE_BUSY;
908
909 /* Wait till BUSY flag reset */
910 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
911
912 if (status == HAL_OK)
913 {
914 if (cmd->DataMode == QSPI_DATA_NONE)
915 {
916 /* Clear interrupt */
917 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
918 }
919
920 /* Call the configuration function */
921 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
922
923 if (cmd->DataMode == QSPI_DATA_NONE)
924 {
925 /* When there is no data phase, the transfer start as soon as the configuration is done
926 so activate TC and TE interrupts */
927 /* Process unlocked */
928 __HAL_UNLOCK(hqspi);
929
930 /* Enable the QSPI Transfer Error Interrupt */
931 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
932 }
933 else
934 {
935 /* Update QSPI state */
936 hqspi->State = HAL_QSPI_STATE_READY;
937
938 /* Process unlocked */
939 __HAL_UNLOCK(hqspi);
940 }
941 }
942 else
943 {
944 /* Process unlocked */
945 __HAL_UNLOCK(hqspi);
946 }
947 }
948 else
949 {
950 status = HAL_BUSY;
951
952 /* Process unlocked */
953 __HAL_UNLOCK(hqspi);
954 }
955
956 /* Return function status */
957 return status;
958 }
959
960 /**
961 * @brief Transmit an amount of data in blocking mode.
962 * @param hqspi : QSPI handle
963 * @param pData : pointer to data buffer
964 * @param Timeout : Timeout duration
965 * @note This function is used only in Indirect Write Mode
966 * @retval HAL status
967 */
HAL_QSPI_Transmit(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)968 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
969 {
970 HAL_StatusTypeDef status = HAL_OK;
971 uint32_t tickstart = HAL_GetTick();
972 __IO uint32_t *data_reg = &hqspi->Instance->DR;
973
974 /* Process locked */
975 __HAL_LOCK(hqspi);
976
977 if(hqspi->State == HAL_QSPI_STATE_READY)
978 {
979 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
980
981 if(pData != NULL )
982 {
983 /* Update state */
984 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
985
986 /* Configure counters and size of the handle */
987 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
988 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
989 hqspi->pTxBuffPtr = pData;
990
991 /* Configure QSPI: CCR register with functional as indirect write */
992 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
993
994 while(hqspi->TxXferCount > 0U)
995 {
996 /* Wait until FT flag is set to send data */
997 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
998
999 if (status != HAL_OK)
1000 {
1001 break;
1002 }
1003
1004 *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
1005 hqspi->pTxBuffPtr++;
1006 hqspi->TxXferCount--;
1007 }
1008
1009 if (status == HAL_OK)
1010 {
1011 /* Wait until TC flag is set to go back in idle state */
1012 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1013
1014 if (status == HAL_OK)
1015 {
1016 /* Clear Transfer Complete bit */
1017 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1018
1019 }
1020 }
1021
1022 /* Update QSPI state */
1023 hqspi->State = HAL_QSPI_STATE_READY;
1024 }
1025 else
1026 {
1027 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1028 status = HAL_ERROR;
1029 }
1030 }
1031 else
1032 {
1033 status = HAL_BUSY;
1034 }
1035
1036 /* Process unlocked */
1037 __HAL_UNLOCK(hqspi);
1038
1039 return status;
1040 }
1041
1042
1043 /**
1044 * @brief Receive an amount of data in blocking mode.
1045 * @param hqspi : QSPI handle
1046 * @param pData : pointer to data buffer
1047 * @param Timeout : Timeout duration
1048 * @note This function is used only in Indirect Read Mode
1049 * @retval HAL status
1050 */
HAL_QSPI_Receive(QSPI_HandleTypeDef * hqspi,uint8_t * pData,uint32_t Timeout)1051 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
1052 {
1053 HAL_StatusTypeDef status = HAL_OK;
1054 uint32_t tickstart = HAL_GetTick();
1055 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1056 __IO uint32_t *data_reg = &hqspi->Instance->DR;
1057
1058 /* Process locked */
1059 __HAL_LOCK(hqspi);
1060
1061 if(hqspi->State == HAL_QSPI_STATE_READY)
1062 {
1063 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1064
1065 if(pData != NULL )
1066 {
1067 /* Update state */
1068 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1069
1070 /* Configure counters and size of the handle */
1071 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1072 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1073 hqspi->pRxBuffPtr = pData;
1074
1075 /* Configure QSPI: CCR register with functional as indirect read */
1076 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1077
1078 /* Start the transfer by re-writing the address in AR register */
1079 WRITE_REG(hqspi->Instance->AR, addr_reg);
1080
1081 while(hqspi->RxXferCount > 0U)
1082 {
1083 /* Wait until FT or TC flag is set to read received data */
1084 status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
1085
1086 if (status != HAL_OK)
1087 {
1088 break;
1089 }
1090
1091 *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
1092 hqspi->pRxBuffPtr++;
1093 hqspi->RxXferCount--;
1094 }
1095
1096 if (status == HAL_OK)
1097 {
1098 /* Wait until TC flag is set to go back in idle state */
1099 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
1100
1101 if (status == HAL_OK)
1102 {
1103 /* Clear Transfer Complete bit */
1104 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1105
1106 }
1107 }
1108
1109 /* Update QSPI state */
1110 hqspi->State = HAL_QSPI_STATE_READY;
1111 }
1112 else
1113 {
1114 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1115 status = HAL_ERROR;
1116 }
1117 }
1118 else
1119 {
1120 status = HAL_BUSY;
1121 }
1122
1123 /* Process unlocked */
1124 __HAL_UNLOCK(hqspi);
1125
1126 return status;
1127 }
1128
1129 /**
1130 * @brief Send an amount of data in non-blocking mode with interrupt.
1131 * @param hqspi : QSPI handle
1132 * @param pData : pointer to data buffer
1133 * @note This function is used only in Indirect Write Mode
1134 * @retval HAL status
1135 */
HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1136 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1137 {
1138 HAL_StatusTypeDef status = HAL_OK;
1139
1140 /* Process locked */
1141 __HAL_LOCK(hqspi);
1142
1143 if(hqspi->State == HAL_QSPI_STATE_READY)
1144 {
1145 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1146
1147 if(pData != NULL )
1148 {
1149 /* Update state */
1150 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1151
1152 /* Configure counters and size of the handle */
1153 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1154 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1155 hqspi->pTxBuffPtr = pData;
1156
1157 /* Clear interrupt */
1158 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1159
1160 /* Configure QSPI: CCR register with functional as indirect write */
1161 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1162
1163 /* Process unlocked */
1164 __HAL_UNLOCK(hqspi);
1165
1166 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1167 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1168 }
1169 else
1170 {
1171 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1172 status = HAL_ERROR;
1173
1174 /* Process unlocked */
1175 __HAL_UNLOCK(hqspi);
1176 }
1177 }
1178 else
1179 {
1180 status = HAL_BUSY;
1181
1182 /* Process unlocked */
1183 __HAL_UNLOCK(hqspi);
1184 }
1185
1186 return status;
1187 }
1188
1189 /**
1190 * @brief Receive an amount of data in non-blocking mode with interrupt.
1191 * @param hqspi : QSPI handle
1192 * @param pData : pointer to data buffer
1193 * @note This function is used only in Indirect Read Mode
1194 * @retval HAL status
1195 */
HAL_QSPI_Receive_IT(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1196 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1197 {
1198 HAL_StatusTypeDef status = HAL_OK;
1199 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1200
1201 /* Process locked */
1202 __HAL_LOCK(hqspi);
1203
1204 if(hqspi->State == HAL_QSPI_STATE_READY)
1205 {
1206 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1207
1208 if(pData != NULL )
1209 {
1210 /* Update state */
1211 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1212
1213 /* Configure counters and size of the handle */
1214 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
1215 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
1216 hqspi->pRxBuffPtr = pData;
1217
1218 /* Clear interrupt */
1219 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
1220
1221 /* Configure QSPI: CCR register with functional as indirect read */
1222 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1223
1224 /* Start the transfer by re-writing the address in AR register */
1225 WRITE_REG(hqspi->Instance->AR, addr_reg);
1226
1227 /* Process unlocked */
1228 __HAL_UNLOCK(hqspi);
1229
1230 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1231 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
1232 }
1233 else
1234 {
1235 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1236 status = HAL_ERROR;
1237
1238 /* Process unlocked */
1239 __HAL_UNLOCK(hqspi);
1240 }
1241 }
1242 else
1243 {
1244 status = HAL_BUSY;
1245
1246 /* Process unlocked */
1247 __HAL_UNLOCK(hqspi);
1248 }
1249
1250 return status;
1251 }
1252
1253 /**
1254 * @brief Send an amount of data in non-blocking mode with DMA.
1255 * @param hqspi : QSPI handle
1256 * @param pData : pointer to data buffer
1257 * @note This function is used only in Indirect Write Mode
1258 * @retval HAL status
1259 */
HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1260 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1261 {
1262 HAL_StatusTypeDef status = HAL_OK;
1263 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1264
1265 /* Process locked */
1266 __HAL_LOCK(hqspi);
1267
1268 if(hqspi->State == HAL_QSPI_STATE_READY)
1269 {
1270 /* Clear the error code */
1271 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1272
1273 if(pData != NULL )
1274 {
1275 /* Configure counters of the handle */
1276 hqspi->TxXferCount = data_size;
1277
1278 /* Update state */
1279 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1280
1281 /* Clear interrupt */
1282 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1283
1284 /* Configure size and pointer of the handle */
1285 hqspi->TxXferSize = hqspi->TxXferCount;
1286 hqspi->pTxBuffPtr = pData;
1287
1288 /* Configure QSPI: CCR register with functional mode as indirect write */
1289 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1290
1291 /* Set the QSPI MDMA transfer complete callback */
1292 hqspi->hmdma->XferCpltCallback = QSPI_DMATxCplt;
1293
1294 /* Set the MDMA error callback */
1295 hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1296
1297 /* Clear the MDMA abort callback */
1298 hqspi->hmdma->XferAbortCallback = NULL;
1299
1300
1301 /* Enable the QSPI transmit MDMA */
1302 if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize, 1) == HAL_OK)
1303 {
1304 /* Process unlocked */
1305 __HAL_UNLOCK(hqspi);
1306
1307 /* Enable the QSPI transfer error Interrupt */
1308 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1309
1310 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1311 }
1312 else
1313 {
1314 status = HAL_ERROR;
1315 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1316 hqspi->State = HAL_QSPI_STATE_READY;
1317
1318 /* Process unlocked */
1319 __HAL_UNLOCK(hqspi);
1320 }
1321 }
1322 else
1323 {
1324 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1325 status = HAL_ERROR;
1326
1327 /* Process unlocked */
1328 __HAL_UNLOCK(hqspi);
1329 }
1330 }
1331 else
1332 {
1333 status = HAL_BUSY;
1334
1335 /* Process unlocked */
1336 __HAL_UNLOCK(hqspi);
1337 }
1338
1339 return status;
1340 }
1341
1342 /**
1343 * @brief Receive an amount of data in non-blocking mode with DMA.
1344 * @param hqspi : QSPI handle
1345 * @param pData : pointer to data buffer.
1346 * @note This function is used only in Indirect Read Mode
1347 * @retval HAL status
1348 */
HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef * hqspi,uint8_t * pData)1349 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1350 {
1351 HAL_StatusTypeDef status = HAL_OK;
1352 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1353 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1354
1355 /* Process locked */
1356 __HAL_LOCK(hqspi);
1357
1358 if(hqspi->State == HAL_QSPI_STATE_READY)
1359 {
1360 /* Clear the error code */
1361 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1362
1363 if(pData != NULL )
1364 {
1365 /* Configure counters of the handle */
1366 hqspi->RxXferCount = data_size;
1367 /* Update state */
1368 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
1369
1370 /* Clear interrupt */
1371 __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
1372
1373 /* Configure size and pointer of the handle */
1374 hqspi->RxXferSize = hqspi->RxXferCount;
1375 hqspi->pRxBuffPtr = pData;
1376
1377 /* Set the QSPI DMA transfer complete callback */
1378 hqspi->hmdma->XferCpltCallback = QSPI_DMARxCplt;
1379
1380 /* Set the MDMA error callback */
1381 hqspi->hmdma->XferErrorCallback = QSPI_DMAError;
1382
1383 /* Clear the MDMA abort callback */
1384 hqspi->hmdma->XferAbortCallback = NULL;
1385
1386 /* QSPI need to be configured to indirect mode before starting
1387 the MDMA to avoid primatury triggering for the MDMA transfert */
1388 /* Configure QSPI: CCR register with functional as indirect read */
1389 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1390
1391 /* Start the transfer by re-writing the address in AR register */
1392 WRITE_REG(hqspi->Instance->AR, addr_reg);
1393
1394 /* Enable the MDMA */
1395 if (HAL_MDMA_Start_IT(hqspi->hmdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize, 1) == HAL_OK)
1396 {
1397 /* Process unlocked */
1398 __HAL_UNLOCK(hqspi);
1399
1400 /* Enable the QSPI transfer error Interrupt */
1401 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
1402
1403 /* Enable the MDMA transfer by setting the DMAEN bit in the QSPI CR register */
1404 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1405 }
1406 else
1407 {
1408 status = HAL_ERROR;
1409 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1410 hqspi->State = HAL_QSPI_STATE_READY;
1411
1412 /* Process unlocked */
1413 __HAL_UNLOCK(hqspi);
1414 }
1415 }
1416 else
1417 {
1418 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1419 status = HAL_ERROR;
1420
1421 /* Process unlocked */
1422 __HAL_UNLOCK(hqspi);
1423 }
1424 }
1425 else
1426 {
1427 status = HAL_BUSY;
1428
1429 /* Process unlocked */
1430 __HAL_UNLOCK(hqspi);
1431 }
1432
1433 return status;
1434 }
1435
1436 /**
1437 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1438 * @param hqspi : QSPI handle
1439 * @param cmd : structure that contains the command configuration information.
1440 * @param cfg : structure that contains the polling configuration information.
1441 * @param Timeout : Timeout duration
1442 * @note This function is used only in Automatic Polling Mode
1443 * @retval HAL status
1444 */
HAL_QSPI_AutoPolling(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg,uint32_t Timeout)1445 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1446 {
1447 HAL_StatusTypeDef status;
1448 uint32_t tickstart = HAL_GetTick();
1449
1450 /* Check the parameters */
1451 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1452 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1453 {
1454 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1455 }
1456
1457 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1458 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1459 {
1460 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1461 }
1462
1463 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1464 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1465 {
1466 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1467 }
1468
1469 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1470 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1471
1472 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1473 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1474 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1475
1476 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1477 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1478 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1479
1480 /* Process locked */
1481 __HAL_LOCK(hqspi);
1482
1483 if(hqspi->State == HAL_QSPI_STATE_READY)
1484 {
1485 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1486
1487 /* Update state */
1488 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1489
1490 /* Wait till BUSY flag reset */
1491 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1492
1493 if (status == HAL_OK)
1494 {
1495 /* Configure QSPI: PSMAR register with the status match value */
1496 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1497
1498 /* Configure QSPI: PSMKR register with the status mask value */
1499 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1500
1501 /* Configure QSPI: PIR register with the interval value */
1502 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1503
1504 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1505 (otherwise there will be an infinite loop in blocking mode) */
1506 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1507 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1508
1509 /* Call the configuration function */
1510 cmd->NbData = cfg->StatusBytesSize;
1511 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1512
1513 /* Wait until SM flag is set to go back in idle state */
1514 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
1515
1516 if (status == HAL_OK)
1517 {
1518 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1519
1520 /* Update state */
1521 hqspi->State = HAL_QSPI_STATE_READY;
1522 }
1523 }
1524 }
1525 else
1526 {
1527 status = HAL_BUSY;
1528 }
1529
1530 /* Process unlocked */
1531 __HAL_UNLOCK(hqspi);
1532
1533 /* Return function status */
1534 return status;
1535 }
1536
1537 /**
1538 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1539 * @param hqspi : QSPI handle
1540 * @param cmd : structure that contains the command configuration information.
1541 * @param cfg : structure that contains the polling configuration information.
1542 * @note This function is used only in Automatic Polling Mode
1543 * @retval HAL status
1544 */
HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_AutoPollingTypeDef * cfg)1545 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1546 {
1547 HAL_StatusTypeDef status;
1548 uint32_t tickstart = HAL_GetTick();
1549
1550 /* Check the parameters */
1551 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1552 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1553 {
1554 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1555 }
1556
1557 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1558 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1559 {
1560 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1561 }
1562
1563 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1564 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1565 {
1566 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1567 }
1568
1569 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1570 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1571
1572 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1573 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1574 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1575
1576 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1577 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1578 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1579 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1580
1581 /* Process locked */
1582 __HAL_LOCK(hqspi);
1583
1584 if(hqspi->State == HAL_QSPI_STATE_READY)
1585 {
1586 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1587
1588 /* Update state */
1589 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1590
1591 /* Wait till BUSY flag reset */
1592 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1593
1594 if (status == HAL_OK)
1595 {
1596 /* Configure QSPI: PSMAR register with the status match value */
1597 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1598
1599 /* Configure QSPI: PSMKR register with the status mask value */
1600 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1601
1602 /* Configure QSPI: PIR register with the interval value */
1603 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1604
1605 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1606 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1607 (cfg->MatchMode | cfg->AutomaticStop));
1608
1609 /* Clear interrupt */
1610 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1611
1612 /* Call the configuration function */
1613 cmd->NbData = cfg->StatusBytesSize;
1614 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1615
1616 /* Process unlocked */
1617 __HAL_UNLOCK(hqspi);
1618
1619 /* Enable the QSPI Transfer Error and status match Interrupt */
1620 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1621
1622 }
1623 else
1624 {
1625 /* Process unlocked */
1626 __HAL_UNLOCK(hqspi);
1627 }
1628 }
1629 else
1630 {
1631 status = HAL_BUSY;
1632
1633 /* Process unlocked */
1634 __HAL_UNLOCK(hqspi);
1635 }
1636
1637 /* Return function status */
1638 return status;
1639 }
1640
1641 /**
1642 * @brief Configure the Memory Mapped mode.
1643 * @param hqspi : QSPI handle
1644 * @param cmd : structure that contains the command configuration information.
1645 * @param cfg : structure that contains the memory mapped configuration information.
1646 * @note This function is used only in Memory mapped Mode
1647 * @retval HAL status
1648 */
HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,QSPI_MemoryMappedTypeDef * cfg)1649 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1650 {
1651 HAL_StatusTypeDef status;
1652 uint32_t tickstart = HAL_GetTick();
1653
1654 /* Check the parameters */
1655 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1656 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1657 {
1658 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1659 }
1660
1661 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1662 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1663 {
1664 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1665 }
1666
1667 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1668 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1669 {
1670 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1671 }
1672
1673 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1674 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1675
1676 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1677 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1678 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1679
1680 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1681
1682 /* Process locked */
1683 __HAL_LOCK(hqspi);
1684
1685 if(hqspi->State == HAL_QSPI_STATE_READY)
1686 {
1687 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1688
1689 /* Update state */
1690 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1691
1692 /* Wait till BUSY flag reset */
1693 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
1694
1695 if (status == HAL_OK)
1696 {
1697 /* Configure QSPI: CR register with timeout counter enable */
1698 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1699
1700 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1701 {
1702 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1703
1704 /* Configure QSPI: LPTR register with the low-power timeout value */
1705 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1706
1707 /* Clear interrupt */
1708 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
1709
1710 /* Enable the QSPI TimeOut Interrupt */
1711 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1712 }
1713
1714 /* Call the configuration function */
1715 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1716 }
1717 }
1718 else
1719 {
1720 status = HAL_BUSY;
1721 }
1722
1723 /* Process unlocked */
1724 __HAL_UNLOCK(hqspi);
1725
1726 /* Return function status */
1727 return status;
1728 }
1729
1730 /**
1731 * @brief Transfer Error callback.
1732 * @param hqspi : QSPI handle
1733 * @retval None
1734 */
HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef * hqspi)1735 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1736 {
1737 /* Prevent unused argument(s) compilation warning */
1738 UNUSED(hqspi);
1739
1740 /* NOTE : This function should not be modified, when the callback is needed,
1741 the HAL_QSPI_ErrorCallback could be implemented in the user file
1742 */
1743 }
1744
1745 /**
1746 * @brief Abort completed callback.
1747 * @param hqspi : QSPI handle
1748 * @retval None
1749 */
HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef * hqspi)1750 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1751 {
1752 /* Prevent unused argument(s) compilation warning */
1753 UNUSED(hqspi);
1754
1755 /* NOTE: This function should not be modified, when the callback is needed,
1756 the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1757 */
1758 }
1759
1760 /**
1761 * @brief Command completed callback.
1762 * @param hqspi : QSPI handle
1763 * @retval None
1764 */
HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef * hqspi)1765 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1766 {
1767 /* Prevent unused argument(s) compilation warning */
1768 UNUSED(hqspi);
1769
1770 /* NOTE: This function should not be modified, when the callback is needed,
1771 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1772 */
1773 }
1774
1775 /**
1776 * @brief Rx Transfer completed callback.
1777 * @param hqspi : QSPI handle
1778 * @retval None
1779 */
HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef * hqspi)1780 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1781 {
1782 /* Prevent unused argument(s) compilation warning */
1783 UNUSED(hqspi);
1784
1785 /* NOTE: This function should not be modified, when the callback is needed,
1786 the HAL_QSPI_RxCpltCallback could be implemented in the user file
1787 */
1788 }
1789
1790 /**
1791 * @brief Tx Transfer completed callback.
1792 * @param hqspi : QSPI handle
1793 * @retval None
1794 */
HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef * hqspi)1795 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1796 {
1797 /* Prevent unused argument(s) compilation warning */
1798 UNUSED(hqspi);
1799
1800 /* NOTE: This function should not be modified, when the callback is needed,
1801 the HAL_QSPI_TxCpltCallback could be implemented in the user file
1802 */
1803 }
1804
1805 /**
1806 * @brief Rx Half Transfer completed callback.
1807 * @param hqspi : QSPI handle
1808 * @retval None
1809 */
HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)1810 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1811 {
1812 /* Prevent unused argument(s) compilation warning */
1813 UNUSED(hqspi);
1814
1815 /* NOTE: This function should not be modified, when the callback is needed,
1816 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
1817 */
1818 }
1819
1820 /**
1821 * @brief Tx Half Transfer completed callback.
1822 * @param hqspi : QSPI handle
1823 * @retval None
1824 */
HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef * hqspi)1825 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1826 {
1827 /* Prevent unused argument(s) compilation warning */
1828 UNUSED(hqspi);
1829
1830 /* NOTE: This function should not be modified, when the callback is needed,
1831 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
1832 */
1833 }
1834
1835 /**
1836 * @brief FIFO Threshold callback.
1837 * @param hqspi : QSPI handle
1838 * @retval None
1839 */
HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef * hqspi)1840 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1841 {
1842 /* Prevent unused argument(s) compilation warning */
1843 UNUSED(hqspi);
1844
1845 /* NOTE : This function should not be modified, when the callback is needed,
1846 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1847 */
1848 }
1849
1850 /**
1851 * @brief Status Match callback.
1852 * @param hqspi : QSPI handle
1853 * @retval None
1854 */
HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef * hqspi)1855 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1856 {
1857 /* Prevent unused argument(s) compilation warning */
1858 UNUSED(hqspi);
1859
1860 /* NOTE : This function should not be modified, when the callback is needed,
1861 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1862 */
1863 }
1864
1865 /**
1866 * @brief Timeout callback.
1867 * @param hqspi : QSPI handle
1868 * @retval None
1869 */
HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef * hqspi)1870 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1871 {
1872 /* Prevent unused argument(s) compilation warning */
1873 UNUSED(hqspi);
1874
1875 /* NOTE : This function should not be modified, when the callback is needed,
1876 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1877 */
1878 }
1879 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
1880 /**
1881 * @brief Register a User QSPI Callback
1882 * To be used instead of the weak (surcharged) predefined callback
1883 * @param hqspi : QSPI handle
1884 * @param CallbackId : ID of the callback to be registered
1885 * This parameter can be one of the following values:
1886 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
1887 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
1888 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
1889 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
1890 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
1891 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
1892 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
1893 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
1894 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
1895 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
1896 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
1897 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
1898 * @param pCallback : pointer to the Callback function
1899 * @retval status
1900 */
HAL_QSPI_RegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId,pQSPI_CallbackTypeDef pCallback)1901 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
1902 {
1903 HAL_StatusTypeDef status = HAL_OK;
1904
1905 if(pCallback == NULL)
1906 {
1907 /* Update the error code */
1908 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1909 return HAL_ERROR;
1910 }
1911
1912 /* Process locked */
1913 __HAL_LOCK(hqspi);
1914
1915 if(hqspi->State == HAL_QSPI_STATE_READY)
1916 {
1917 switch (CallbackId)
1918 {
1919 case HAL_QSPI_ERROR_CB_ID :
1920 hqspi->ErrorCallback = pCallback;
1921 break;
1922 case HAL_QSPI_ABORT_CB_ID :
1923 hqspi->AbortCpltCallback = pCallback;
1924 break;
1925 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
1926 hqspi->FifoThresholdCallback = pCallback;
1927 break;
1928 case HAL_QSPI_CMD_CPLT_CB_ID :
1929 hqspi->CmdCpltCallback = pCallback;
1930 break;
1931 case HAL_QSPI_RX_CPLT_CB_ID :
1932 hqspi->RxCpltCallback = pCallback;
1933 break;
1934 case HAL_QSPI_TX_CPLT_CB_ID :
1935 hqspi->TxCpltCallback = pCallback;
1936 break;
1937 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
1938 hqspi->RxHalfCpltCallback = pCallback;
1939 break;
1940 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
1941 hqspi->TxHalfCpltCallback = pCallback;
1942 break;
1943 case HAL_QSPI_STATUS_MATCH_CB_ID :
1944 hqspi->StatusMatchCallback = pCallback;
1945 break;
1946 case HAL_QSPI_TIMEOUT_CB_ID :
1947 hqspi->TimeOutCallback = pCallback;
1948 break;
1949 case HAL_QSPI_MSP_INIT_CB_ID :
1950 hqspi->MspInitCallback = pCallback;
1951 break;
1952 case HAL_QSPI_MSP_DEINIT_CB_ID :
1953 hqspi->MspDeInitCallback = pCallback;
1954 break;
1955 default :
1956 /* Update the error code */
1957 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1958 /* update return status */
1959 status = HAL_ERROR;
1960 break;
1961 }
1962 }
1963 else if (hqspi->State == HAL_QSPI_STATE_RESET)
1964 {
1965 switch (CallbackId)
1966 {
1967 case HAL_QSPI_MSP_INIT_CB_ID :
1968 hqspi->MspInitCallback = pCallback;
1969 break;
1970 case HAL_QSPI_MSP_DEINIT_CB_ID :
1971 hqspi->MspDeInitCallback = pCallback;
1972 break;
1973 default :
1974 /* Update the error code */
1975 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1976 /* update return status */
1977 status = HAL_ERROR;
1978 break;
1979 }
1980 }
1981 else
1982 {
1983 /* Update the error code */
1984 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
1985 /* update return status */
1986 status = HAL_ERROR;
1987 }
1988
1989 /* Release Lock */
1990 __HAL_UNLOCK(hqspi);
1991 return status;
1992 }
1993
1994 /**
1995 * @brief Unregister a User QSPI Callback
1996 * QSPI Callback is redirected to the weak (surcharged) predefined callback
1997 * @param hqspi : QSPI handle
1998 * @param CallbackId : ID of the callback to be unregistered
1999 * This parameter can be one of the following values:
2000 * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
2001 * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
2002 * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
2003 * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
2004 * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
2005 * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
2006 * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
2007 * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
2008 * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
2009 * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
2010 * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
2011 * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
2012 * @retval status
2013 */
HAL_QSPI_UnRegisterCallback(QSPI_HandleTypeDef * hqspi,HAL_QSPI_CallbackIDTypeDef CallbackId)2014 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
2015 {
2016 HAL_StatusTypeDef status = HAL_OK;
2017
2018 /* Process locked */
2019 __HAL_LOCK(hqspi);
2020
2021 if(hqspi->State == HAL_QSPI_STATE_READY)
2022 {
2023 switch (CallbackId)
2024 {
2025 case HAL_QSPI_ERROR_CB_ID :
2026 hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
2027 break;
2028 case HAL_QSPI_ABORT_CB_ID :
2029 hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
2030 break;
2031 case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
2032 hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
2033 break;
2034 case HAL_QSPI_CMD_CPLT_CB_ID :
2035 hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
2036 break;
2037 case HAL_QSPI_RX_CPLT_CB_ID :
2038 hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
2039 break;
2040 case HAL_QSPI_TX_CPLT_CB_ID :
2041 hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
2042 break;
2043 case HAL_QSPI_RX_HALF_CPLT_CB_ID :
2044 hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
2045 break;
2046 case HAL_QSPI_TX_HALF_CPLT_CB_ID :
2047 hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
2048 break;
2049 case HAL_QSPI_STATUS_MATCH_CB_ID :
2050 hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
2051 break;
2052 case HAL_QSPI_TIMEOUT_CB_ID :
2053 hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
2054 break;
2055 case HAL_QSPI_MSP_INIT_CB_ID :
2056 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2057 break;
2058 case HAL_QSPI_MSP_DEINIT_CB_ID :
2059 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2060 break;
2061 default :
2062 /* Update the error code */
2063 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2064 /* update return status */
2065 status = HAL_ERROR;
2066 break;
2067 }
2068 }
2069 else if (hqspi->State == HAL_QSPI_STATE_RESET)
2070 {
2071 switch (CallbackId)
2072 {
2073 case HAL_QSPI_MSP_INIT_CB_ID :
2074 hqspi->MspInitCallback = HAL_QSPI_MspInit;
2075 break;
2076 case HAL_QSPI_MSP_DEINIT_CB_ID :
2077 hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
2078 break;
2079 default :
2080 /* Update the error code */
2081 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2082 /* update return status */
2083 status = HAL_ERROR;
2084 break;
2085 }
2086 }
2087 else
2088 {
2089 /* Update the error code */
2090 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
2091 /* update return status */
2092 status = HAL_ERROR;
2093 }
2094
2095 /* Release Lock */
2096 __HAL_UNLOCK(hqspi);
2097 return status;
2098 }
2099 #endif
2100
2101 /**
2102 * @}
2103 */
2104
2105 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
2106 * @brief QSPI control and State functions
2107 *
2108 @verbatim
2109 ===============================================================================
2110 ##### Peripheral Control and State functions #####
2111 ===============================================================================
2112 [..]
2113 This subsection provides a set of functions allowing to :
2114 (+) Check in run-time the state of the driver.
2115 (+) Check the error code set during last operation.
2116 (+) Abort any operation.
2117
2118
2119 @endverbatim
2120 * @{
2121 */
2122
2123 /**
2124 * @brief Return the QSPI handle state.
2125 * @param hqspi : QSPI handle
2126 * @retval HAL state
2127 */
HAL_QSPI_GetState(QSPI_HandleTypeDef * hqspi)2128 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
2129 {
2130 /* Return QSPI handle state */
2131 return hqspi->State;
2132 }
2133
2134 /**
2135 * @brief Return the QSPI error code.
2136 * @param hqspi : QSPI handle
2137 * @retval QSPI Error Code
2138 */
HAL_QSPI_GetError(QSPI_HandleTypeDef * hqspi)2139 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
2140 {
2141 return hqspi->ErrorCode;
2142 }
2143
2144 /**
2145 * @brief Abort the current transmission.
2146 * @param hqspi : QSPI handle
2147 * @retval HAL status
2148 */
HAL_QSPI_Abort(QSPI_HandleTypeDef * hqspi)2149 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
2150 {
2151 HAL_StatusTypeDef status = HAL_OK;
2152 uint32_t tickstart = HAL_GetTick();
2153
2154 /* Check if the state is in one of the busy states */
2155 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2156 {
2157 /* Process unlocked */
2158 __HAL_UNLOCK(hqspi);
2159
2160 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2161 {
2162 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2163 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2164
2165 /* Abort MDMA */
2166 status = HAL_MDMA_Abort(hqspi->hmdma);
2167 if(status != HAL_OK)
2168 {
2169 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2170 }
2171 }
2172
2173 /* Configure QSPI: CR register with Abort request */
2174 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2175
2176 /* Wait until TC flag is set to go back in idle state */
2177 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
2178
2179 if (status == HAL_OK)
2180 {
2181 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2182
2183 /* Wait until BUSY flag is reset */
2184 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
2185 }
2186
2187 if (status == HAL_OK)
2188 {
2189 /* Reset functional mode configuration to indirect write mode by default */
2190 CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
2191
2192 /* Update state */
2193 hqspi->State = HAL_QSPI_STATE_READY;
2194 }
2195 }
2196
2197 return status;
2198 }
2199
2200 /**
2201 * @brief Abort the current transmission (non-blocking function)
2202 * @param hqspi : QSPI handle
2203 * @retval HAL status
2204 */
HAL_QSPI_Abort_IT(QSPI_HandleTypeDef * hqspi)2205 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
2206 {
2207 HAL_StatusTypeDef status = HAL_OK;
2208
2209 /* Check if the state is in one of the busy states */
2210 if (((uint32_t)hqspi->State & 0x2U) != 0U)
2211 {
2212 /* Process unlocked */
2213 __HAL_UNLOCK(hqspi);
2214
2215 /* Update QSPI state */
2216 hqspi->State = HAL_QSPI_STATE_ABORT;
2217
2218 /* Disable all interrupts */
2219 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
2220
2221 if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
2222 {
2223 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2224 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2225
2226 /* Abort MDMA channel */
2227 hqspi->hmdma->XferAbortCallback = QSPI_DMAAbortCplt;
2228 if (HAL_MDMA_Abort_IT(hqspi->hmdma) != HAL_OK)
2229 {
2230 /* Change state of QSPI */
2231 hqspi->State = HAL_QSPI_STATE_READY;
2232
2233 /* Abort Complete callback */
2234 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2235 hqspi->AbortCpltCallback(hqspi);
2236 #else
2237 HAL_QSPI_AbortCpltCallback(hqspi);
2238 #endif
2239 }
2240 }
2241 else
2242 {
2243 /* Clear interrupt */
2244 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2245
2246 /* Enable the QSPI Transfer Complete Interrupt */
2247 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2248
2249 /* Configure QSPI: CR register with Abort request */
2250 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2251 }
2252 }
2253 return status;
2254 }
2255
2256 /** @brief Set QSPI timeout.
2257 * @param hqspi : QSPI handle.
2258 * @param Timeout : Timeout for the QSPI memory access.
2259 * @retval None
2260 */
HAL_QSPI_SetTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Timeout)2261 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
2262 {
2263 hqspi->Timeout = Timeout;
2264 }
2265
2266 /** @brief Set QSPI Fifo threshold.
2267 * @param hqspi : QSPI handle.
2268 * @param Threshold : Threshold of the Fifo (value between 1 and 16).
2269 * @retval HAL status
2270 */
HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef * hqspi,uint32_t Threshold)2271 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
2272 {
2273 HAL_StatusTypeDef status = HAL_OK;
2274
2275 /* Process locked */
2276 __HAL_LOCK(hqspi);
2277
2278 if(hqspi->State == HAL_QSPI_STATE_READY)
2279 {
2280 /* Synchronize init structure with new FIFO threshold value */
2281 hqspi->Init.FifoThreshold = Threshold;
2282
2283 /* Configure QSPI FIFO Threshold */
2284 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
2285 ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
2286 }
2287 else
2288 {
2289 status = HAL_BUSY;
2290 }
2291
2292 /* Process unlocked */
2293 __HAL_UNLOCK(hqspi);
2294
2295 /* Return function status */
2296 return status;
2297 }
2298
2299 /** @brief Get QSPI Fifo threshold.
2300 * @param hqspi : QSPI handle.
2301 * @retval Fifo threshold (value between 1 and 16)
2302 */
HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef * hqspi)2303 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
2304 {
2305 return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
2306 }
2307
2308 /** @brief Set FlashID.
2309 * @param hqspi : QSPI handle.
2310 * @param FlashID : Index of the flash memory to be accessed.
2311 * This parameter can be a value of @ref QSPI_Flash_Select.
2312 * @note The FlashID is ignored when dual flash mode is enabled.
2313 * @retval HAL status
2314 */
HAL_QSPI_SetFlashID(QSPI_HandleTypeDef * hqspi,uint32_t FlashID)2315 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
2316 {
2317 HAL_StatusTypeDef status = HAL_OK;
2318
2319 /* Check the parameter */
2320 assert_param(IS_QSPI_FLASH_ID(FlashID));
2321
2322 /* Process locked */
2323 __HAL_LOCK(hqspi);
2324
2325 if(hqspi->State == HAL_QSPI_STATE_READY)
2326 {
2327 /* Synchronize init structure with new FlashID value */
2328 hqspi->Init.FlashID = FlashID;
2329
2330 /* Configure QSPI FlashID */
2331 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
2332 }
2333 else
2334 {
2335 status = HAL_BUSY;
2336 }
2337
2338 /* Process unlocked */
2339 __HAL_UNLOCK(hqspi);
2340
2341 /* Return function status */
2342 return status;
2343 }
2344
2345 /**
2346 * @}
2347 */
2348
2349 /**
2350 * @}
2351 */
2352
2353 /** @defgroup QSPI_Private_Functions QSPI Private Functions
2354 * @{
2355 */
2356
2357 /**
2358 * @brief DMA QSPI receive process complete callback.
2359 * @param hmdma : MDMA handle
2360 * @retval None
2361 */
QSPI_DMARxCplt(MDMA_HandleTypeDef * hmdma)2362 static void QSPI_DMARxCplt(MDMA_HandleTypeDef *hmdma)
2363 {
2364 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2365 hqspi->RxXferCount = 0U;
2366
2367 /* Enable the QSPI transfer complete Interrupt */
2368 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2369 }
2370
2371 /**
2372 * @brief DMA QSPI transmit process complete callback.
2373 * @param hmdma : MDMA handle
2374 * @retval None
2375 */
QSPI_DMATxCplt(MDMA_HandleTypeDef * hmdma)2376 static void QSPI_DMATxCplt(MDMA_HandleTypeDef *hmdma)
2377 {
2378 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hmdma->Parent);
2379 hqspi->TxXferCount = 0U;
2380
2381 /* Enable the QSPI transfer complete Interrupt */
2382 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2383 }
2384
2385 /**
2386 * @brief DMA QSPI communication error callback.
2387 * @param hmdma : MDMA handle
2388 * @retval None
2389 */
QSPI_DMAError(MDMA_HandleTypeDef * hmdma)2390 static void QSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2391 {
2392 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2393
2394 hqspi->RxXferCount = 0U;
2395 hqspi->TxXferCount = 0U;
2396 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
2397
2398 /* Disable the MDMA transfer by clearing the DMAEN bit in the QSPI CR register */
2399 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
2400
2401 /* Abort the QSPI */
2402 (void)HAL_QSPI_Abort_IT(hqspi);
2403
2404 }
2405
2406 /**
2407 * @brief MDMA QSPI abort complete callback.
2408 * @param hmdma : MDMA handle
2409 * @retval None
2410 */
QSPI_DMAAbortCplt(MDMA_HandleTypeDef * hmdma)2411 static void QSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2412 {
2413 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hmdma->Parent);
2414
2415 hqspi->RxXferCount = 0U;
2416 hqspi->TxXferCount = 0U;
2417
2418 if(hqspi->State == HAL_QSPI_STATE_ABORT)
2419 {
2420 /* MDMA Abort called by QSPI abort */
2421 /* Clear interrupt */
2422 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
2423
2424 /* Enable the QSPI Transfer Complete Interrupt */
2425 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
2426
2427 /* Configure QSPI: CR register with Abort request */
2428 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
2429 }
2430 else
2431 {
2432 /* MDMA Abort called due to a transfer error interrupt */
2433 /* Change state of QSPI */
2434 hqspi->State = HAL_QSPI_STATE_READY;
2435
2436 /* Error callback */
2437 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
2438 hqspi->ErrorCallback(hqspi);
2439 #else
2440 HAL_QSPI_ErrorCallback(hqspi);
2441 #endif
2442 }
2443 }
2444
2445 /**
2446 * @brief Wait for a flag state until timeout.
2447 * @param hqspi : QSPI handle
2448 * @param Flag : Flag checked
2449 * @param State : Value of the flag expected
2450 * @param Tickstart : Tick start value
2451 * @param Timeout : Duration of the timeout
2452 * @retval HAL status
2453 */
QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef * hqspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2454 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
2455 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2456 {
2457 /* Wait until flag is in expected state */
2458 while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
2459 {
2460 /* Check for the Timeout */
2461 if (Timeout != HAL_MAX_DELAY)
2462 {
2463 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2464 {
2465 hqspi->State = HAL_QSPI_STATE_ERROR;
2466 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
2467
2468 return HAL_ERROR;
2469 }
2470 }
2471 }
2472 return HAL_OK;
2473 }
2474
2475 /**
2476 * @brief Configure the communication registers.
2477 * @param hqspi : QSPI handle
2478 * @param cmd : structure that contains the command configuration information
2479 * @param FunctionalMode : functional mode to configured
2480 * This parameter can be one of the following values:
2481 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2482 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2483 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2484 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2485 * @retval None
2486 */
QSPI_Config(QSPI_HandleTypeDef * hqspi,QSPI_CommandTypeDef * cmd,uint32_t FunctionalMode)2487 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
2488 {
2489 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
2490
2491 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
2492 {
2493 /* Configure QSPI: DLR register with the number of data to read or write */
2494 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
2495 }
2496
2497 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
2498 {
2499 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2500 {
2501 /* Configure QSPI: ABR register with alternate bytes value */
2502 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2503
2504 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2505 {
2506 /*---- Command with instruction, address and alternate bytes ----*/
2507 /* Configure QSPI: CCR register with all communications parameters */
2508 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2509 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2510 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2511 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
2512 cmd->Instruction | FunctionalMode));
2513
2514 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2515 {
2516 /* Configure QSPI: AR register with address value */
2517 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2518 }
2519 }
2520 else
2521 {
2522 /*---- Command with instruction and alternate bytes ----*/
2523 /* Configure QSPI: CCR register with all communications parameters */
2524 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2525 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2526 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2527 cmd->AddressMode | cmd->InstructionMode |
2528 cmd->Instruction | FunctionalMode));
2529 }
2530 }
2531 else
2532 {
2533 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2534 {
2535 /*---- Command with instruction and address ----*/
2536 /* Configure QSPI: CCR register with all communications parameters */
2537 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2538 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2539 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
2540 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2541
2542 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2543 {
2544 /* Configure QSPI: AR register with address value */
2545 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2546 }
2547 }
2548 else
2549 {
2550 /*---- Command with only instruction ----*/
2551 /* Configure QSPI: CCR register with all communications parameters */
2552 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2553 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2554 cmd->AlternateByteMode | cmd->AddressMode |
2555 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
2556 }
2557 }
2558 }
2559 else
2560 {
2561 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
2562 {
2563 /* Configure QSPI: ABR register with alternate bytes value */
2564 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
2565
2566 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2567 {
2568 /*---- Command with address and alternate bytes ----*/
2569 /* Configure QSPI: CCR register with all communications parameters */
2570 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2571 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2572 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2573 cmd->AddressSize | cmd->AddressMode |
2574 cmd->InstructionMode | FunctionalMode));
2575
2576 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2577 {
2578 /* Configure QSPI: AR register with address value */
2579 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2580 }
2581 }
2582 else
2583 {
2584 /*---- Command with only alternate bytes ----*/
2585 /* Configure QSPI: CCR register with all communications parameters */
2586 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2587 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2588 cmd->AlternateBytesSize | cmd->AlternateByteMode |
2589 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2590 }
2591 }
2592 else
2593 {
2594 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
2595 {
2596 /*---- Command with only address ----*/
2597 /* Configure QSPI: CCR register with all communications parameters */
2598 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2599 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2600 cmd->AlternateByteMode | cmd->AddressSize |
2601 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
2602
2603 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2604 {
2605 /* Configure QSPI: AR register with address value */
2606 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2607 }
2608 }
2609 else
2610 {
2611 /*---- Command with only data phase ----*/
2612 if (cmd->DataMode != QSPI_DATA_NONE)
2613 {
2614 /* Configure QSPI: CCR register with all communications parameters */
2615 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
2616 cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
2617 cmd->AlternateByteMode | cmd->AddressMode |
2618 cmd->InstructionMode | FunctionalMode));
2619 }
2620 }
2621 }
2622 }
2623 }
2624
2625 /**
2626 * @}
2627 */
2628
2629 /**
2630 * @}
2631 */
2632
2633 #endif /* HAL_QSPI_MODULE_ENABLED */
2634 /**
2635 * @}
2636 */
2637
2638 /**
2639 * @}
2640 */
2641
2642 #endif /* defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2) */
2643
2644 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2645