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