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