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