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