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