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