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