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