source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

File size: 62.9 KB
Line 
1/**
2 ******************************************************************************
3 * @file stm32f4xx_hal_qspi.c
4 * @author MCD Application Team
5 * @version V1.4.1
6 * @date 09-October-2015
7 * @brief QSPI HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the QuadSPI interface (QSPI).
11 * + Initialization and de-initialization functions
12 * + Indirect functional mode management
13 * + Memory-mapped functional mode management
14 * + Auto-polling functional mode management
15 * + Interrupts and flags management
16 * + DMA channel configuration for indirect functional mode
17 * + Errors management and abort functionality
18 *
19 @verbatim
20 ===============================================================================
21 ##### How to use this driver #####
22 ===============================================================================
23 [..]
24 *** Initialization ***
25 ======================
26 [..]
27 (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
28 (+) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
29 (+) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
30 (+) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
31 (+) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
32 (+) If interrupt mode is used, enable and configure QuadSPI global
33 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
34 (+) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
35 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
36 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
37 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
38 (#) Configure the flash size, the clock prescaler, the fifo threshold, the
39 clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
40
41 *** Indirect functional mode ***
42 ================================
43 [..]
44 (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
45 functions :
46 (+) Instruction phase : the mode used and if present the instruction opcode.
47 (+) Address phase : the mode used and if present the size and the address value.
48 (+) Alternate-bytes phase : the mode used and if present the size and the alternate
49 bytes values.
50 (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
51 (+) Data phase : the mode used and if present the number of bytes.
52 (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
53 if activated.
54 (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
55 (#) If no data is required for the command, it is sent directly to the memory :
56 (+) In polling mode, the output of the function is done when the transfer is complete.
57 (+) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
58 (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
59 HAL_QSPI_Transmit_IT() after the command configuration :
60 (+) In polling mode, the output of the function is done when the transfer is complete.
61 (+) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
62 is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
63 (+) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
64 HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
65 (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
66 HAL_QSPI_Receive_IT() after the command configuration :
67 (+) In polling mode, the output of the function is done when the transfer is complete.
68 (+) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
69 is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
70 (+) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
71 HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
72
73 *** Auto-polling functional mode ***
74 ====================================
75 [..]
76 (#) Configure the command sequence and the auto-polling functional mode using the
77 HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
78 (+) Instruction phase : the mode used and if present the instruction opcode.
79 (+) Address phase : the mode used and if present the size and the address value.
80 (+) Alternate-bytes phase : the mode used and if present the size and the alternate
81 bytes values.
82 (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
83 (+) Data phase : the mode used.
84 (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
85 if activated.
86 (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
87 (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
88 the polling interval and the automatic stop activation.
89 (#) After the configuration :
90 (+) In polling mode, the output of the function is done when the status match is reached. The
91 automatic stop is activated to avoid an infinite loop.
92 (+) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
93
94 *** Memory-mapped functional mode ***
95 =====================================
96 [..]
97 (#) Configure the command sequence and the memory-mapped functional mode using the
98 HAL_QSPI_MemoryMapped() functions :
99 (+) Instruction phase : the mode used and if present the instruction opcode.
100 (+) Address phase : the mode used and the size.
101 (+) Alternate-bytes phase : the mode used and if present the size and the alternate
102 bytes values.
103 (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
104 (+) Data phase : the mode used.
105 (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
106 if activated.
107 (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
108 (+) The timeout activation and the timeout period.
109 (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
110 the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
111
112 *** Errors management and abort functionality ***
113 ==================================================
114 [..]
115 (#) HAL_QSPI_GetError() function gives the error rised during the last operation.
116 (#) HAL_QSPI_Abort() function aborts any on-going operation and flushes the fifo.
117 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
118
119 *** Workarounds linked to Silicon Limitation ***
120 ====================================================
121 [..]
122 (#) Workarounds Implemented inside HAL Driver
123 (+) Extra data written in the FIFO at the end of a read transfer
124
125 @endverbatim
126 ******************************************************************************
127 * @attention
128 *
129 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
130 *
131 * Redistribution and use in source and binary forms, with or without modification,
132 * are permitted provided that the following conditions are met:
133 * 1. Redistributions of source code must retain the above copyright notice,
134 * this list of conditions and the following disclaimer.
135 * 2. Redistributions in binary form must reproduce the above copyright notice,
136 * this list of conditions and the following disclaimer in the documentation
137 * and/or other materials provided with the distribution.
138 * 3. Neither the name of STMicroelectronics nor the names of its contributors
139 * may be used to endorse or promote products derived from this software
140 * without specific prior written permission.
141 *
142 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
143 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
144 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
146 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
147 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
148 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
149 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
150 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
151 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
152 *
153 ******************************************************************************
154 */
155
156/* Includes ------------------------------------------------------------------*/
157#include "stm32f4xx_hal.h"
158
159/** @addtogroup STM32F4xx_HAL_Driver
160 * @{
161 */
162
163/** @defgroup QSPI QSPI
164 * @brief HAL QSPI module driver
165 * @{
166 */
167#ifdef HAL_QSPI_MODULE_ENABLED
168
169#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
170
171/* Private typedef -----------------------------------------------------------*/
172/* Private define ------------------------------------------------------------*/
173/** @addtogroup QSPI_Private_Constants
174 * @{
175 */
176#define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!<Indirect write mode*/
177#define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
178#define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
179#define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
180/**
181 * @}
182 */
183
184/* Private macro -------------------------------------------------------------*/
185/** @addtogroup QSPI_Private_Macros QSPI Private Macros
186 * @{
187 */
188#define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
189 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
190 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
191 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
192/**
193 * @}
194 */
195
196/* Private variables ---------------------------------------------------------*/
197/* Private function prototypes -----------------------------------------------*/
198/** @addtogroup QSPI_Private_Functions QSPI Private Functions
199 * @{
200 */
201static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
202static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
203static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
204static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
205static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
206static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout);
207static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
208/**
209 * @}
210 */
211
212/* Exported functions ---------------------------------------------------------*/
213
214/** @defgroup QSPI_Exported_Functions QSPI Exported Functions
215 * @{
216 */
217
218/** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
219 * @brief Initialization and Configuration functions
220 *
221@verbatim
222===============================================================================
223 ##### Initialization and Configuration functions #####
224 ===============================================================================
225 [..]
226 This subsection provides a set of functions allowing to :
227 (+) Initialize the QuadSPI.
228 (+) De-initialize the QuadSPI.
229
230@endverbatim
231 * @{
232 */
233
234/**
235 * @brief Initializes the QSPI mode according to the specified parameters
236 * in the QSPI_InitTypeDef and creates the associated handle.
237 * @param hqspi: qspi handle
238 * @retval HAL status
239 */
240HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
241{
242 HAL_StatusTypeDef status = HAL_ERROR;
243
244 /* Check the QSPI handle allocation */
245 if(hqspi == NULL)
246 {
247 return HAL_ERROR;
248 }
249
250 /* Check the parameters */
251 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
252 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
253 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
254 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
255 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
256 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
257 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
258 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
259
260 if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
261 {
262 assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
263 }
264
265 /* Process locked */
266 __HAL_LOCK(hqspi);
267
268 if(hqspi->State == HAL_QSPI_STATE_RESET)
269 {
270 /* Allocate lock resource and initialize it */
271 hqspi->Lock = HAL_UNLOCKED;
272
273 /* Init the low level hardware : GPIO, CLOCK */
274 HAL_QSPI_MspInit(hqspi);
275
276 /* Configure the default timeout for the QSPI memory access */
277 HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
278 }
279
280 /* Configure QSPI FIFO Threshold */
281 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, ((hqspi->Init.FifoThreshold - 1) << 8));
282
283 /* Wait till BUSY flag reset */
284 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
285
286 if(status == HAL_OK)
287 {
288
289 /* Configure QSPI Clock Prescaler and Sample Shift */
290 MODIFY_REG(hqspi->Instance->CR,(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM), ((hqspi->Init.ClockPrescaler << 24)| hqspi->Init.SampleShifting | hqspi->Init.FlashID| hqspi->Init.DualFlash ));
291
292 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
293 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
294 ((hqspi->Init.FlashSize << 16) | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
295
296 /* Enable the QSPI peripheral */
297 __HAL_QSPI_ENABLE(hqspi);
298
299 /* Set QSPI error code to none */
300 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
301
302 /* Initialize the QSPI state */
303 hqspi->State = HAL_QSPI_STATE_READY;
304 }
305
306 /* Release Lock */
307 __HAL_UNLOCK(hqspi);
308
309 /* Return function status */
310 return status;
311}
312
313/**
314 * @brief DeInitializes the QSPI peripheral
315 * @param hqspi: qspi handle
316 * @retval HAL status
317 */
318HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
319{
320 /* Check the QSPI handle allocation */
321 if(hqspi == NULL)
322 {
323 return HAL_ERROR;
324 }
325
326 /* Process locked */
327 __HAL_LOCK(hqspi);
328
329 /* Disable the QSPI Peripheral Clock */
330 __HAL_QSPI_DISABLE(hqspi);
331
332 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
333 HAL_QSPI_MspDeInit(hqspi);
334
335 /* Set QSPI error code to none */
336 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
337
338 /* Initialize the QSPI state */
339 hqspi->State = HAL_QSPI_STATE_RESET;
340
341 /* Release Lock */
342 __HAL_UNLOCK(hqspi);
343
344 return HAL_OK;
345}
346
347/**
348 * @brief QSPI MSP Init
349 * @param hqspi: QSPI handle
350 * @retval None
351 */
352 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
353{
354 /* NOTE : This function should not be modified, when the callback is needed,
355 the HAL_QSPI_MspInit can be implemented in the user file
356 */
357}
358
359/**
360 * @brief QSPI MSP DeInit
361 * @param hqspi: QSPI handle
362 * @retval None
363 */
364 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
365{
366 /* NOTE : This function should not be modified, when the callback is needed,
367 the HAL_QSPI_MspDeInit can be implemented in the user file
368 */
369}
370
371/**
372 * @}
373 */
374
375/** @defgroup QSPI_Exported_Functions_Group2 IO operation functions
376 * @brief QSPI Transmit/Receive functions
377 *
378@verbatim
379 ===============================================================================
380 ##### IO operation functions #####
381 ===============================================================================
382 [..]
383 This subsection provides a set of functions allowing to :
384 (+) Handle the interrupts.
385 (+) Handle the command sequence.
386 (+) Transmit data in blocking, interrupt or DMA mode.
387 (+) Receive data in blocking, interrupt or DMA mode.
388 (+) Manage the auto-polling functional mode.
389 (+) Manage the memory-mapped functional mode.
390
391@endverbatim
392 * @{
393 */
394
395/**
396 * @brief This function handles QSPI interrupt request.
397 * @param hqspi: QSPI handle
398 * @retval None.
399 */
400void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
401{
402 __IO uint32_t *data_reg;
403 uint32_t flag = 0, itsource = 0;
404
405 /* QSPI FIFO Threshold interrupt occurred ----------------------------------*/
406 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT);
407 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_FT);
408
409 if((flag != RESET) && (itsource != RESET))
410 {
411 data_reg = &hqspi->Instance->DR;
412
413 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
414 {
415 /* Transmission process */
416 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
417 {
418 if (hqspi->TxXferCount > 0)
419 {
420 /* Fill the FIFO until it is full */
421 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
422 hqspi->TxXferCount--;
423 }
424 else
425 {
426 /* No more data available for the transfer */
427 break;
428 }
429 }
430 }
431 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
432 {
433 /* Receiving Process */
434 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
435 {
436 if (hqspi->RxXferCount > 0)
437 {
438 /* Read the FIFO until it is empty */
439 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
440 hqspi->RxXferCount--;
441 }
442 else
443 {
444 /* All data have been received for the transfer */
445 break;
446 }
447 }
448 }
449
450 /* FIFO Threshold callback */
451 HAL_QSPI_FifoThresholdCallback(hqspi);
452 }
453
454 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
455 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TC);
456 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TC);
457
458 if((flag != RESET) && (itsource != RESET))
459 {
460 /* Clear interrupt */
461 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
462
463 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
464 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
465
466 /* Transfer complete callback */
467 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
468 {
469 /* Clear Busy bit */
470 HAL_QSPI_Abort(hqspi);
471
472 /* TX Complete callback */
473 HAL_QSPI_TxCpltCallback(hqspi);
474 }
475 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
476 {
477 data_reg = &hqspi->Instance->DR;
478 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0)
479 {
480 if (hqspi->RxXferCount > 0)
481 {
482 /* Read the last data received in the FIFO until it is empty */
483 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
484 hqspi->RxXferCount--;
485 }
486 else
487 {
488 /* All data have been received for the transfer */
489 break;
490 }
491 }
492
493 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
494 HAL_QSPI_Abort(hqspi);
495
496 /* RX Complete callback */
497 HAL_QSPI_RxCpltCallback(hqspi);
498 }
499 else if(hqspi->State == HAL_QSPI_STATE_BUSY)
500 {
501 /* Command Complete callback */
502 HAL_QSPI_CmdCpltCallback(hqspi);
503 }
504
505 /* Change state of QSPI */
506 hqspi->State = HAL_QSPI_STATE_READY;
507 }
508
509 /* QSPI Status Match interrupt occurred ------------------------------------*/
510 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_SM);
511 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_SM);
512
513 if((flag != RESET) && (itsource != RESET))
514 {
515 /* Clear interrupt */
516 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
517
518 /* Check if the automatic poll mode stop is activated */
519 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0)
520 {
521 /* Disable the QSPI FIFO Threshold, Transfer Error and Status Match Interrupts */
522 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TE);
523
524 /* Change state of QSPI */
525 hqspi->State = HAL_QSPI_STATE_READY;
526 }
527
528 /* Status match callback */
529 HAL_QSPI_StatusMatchCallback(hqspi);
530 }
531
532 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
533 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TE);
534 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TE);
535
536 if((flag != RESET) && (itsource != RESET))
537 {
538 /* Clear interrupt */
539 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE);
540
541 /* Disable all the QSPI Interrupts */
542 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
543
544 /* Set error code */
545 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
546
547 /* Change state of QSPI */
548 hqspi->State = HAL_QSPI_STATE_ERROR;
549
550 /* Error callback */
551 HAL_QSPI_ErrorCallback(hqspi);
552 }
553
554 /* QSPI Time out interrupt occurred -----------------------------------------*/
555 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TO);
556 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TO);
557
558 if((flag != RESET) && (itsource != RESET))
559 {
560 /* Clear interrupt */
561 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
562
563 /* Time out callback */
564 HAL_QSPI_TimeOutCallback(hqspi);
565 }
566}
567
568/**
569 * @brief Sets the command configuration.
570 * @param hqspi: QSPI handle
571 * @param cmd : structure that contains the command configuration information
572 * @param Timeout : Time out duration
573 * @note This function is used only in Indirect Read or Write Modes
574 * @retval HAL status
575 */
576HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
577{
578 HAL_StatusTypeDef status = HAL_ERROR;
579
580 /* Check the parameters */
581 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
582 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
583 {
584 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
585 }
586
587 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
588 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
589 {
590 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
591 }
592
593 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
594 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
595 {
596 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
597 }
598
599 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
600 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
601
602 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
603 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
604 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
605
606 /* Process locked */
607 __HAL_LOCK(hqspi);
608
609 if(hqspi->State == HAL_QSPI_STATE_READY)
610 {
611 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
612
613 /* Update QSPI state */
614 hqspi->State = HAL_QSPI_STATE_BUSY;
615
616 /* Wait till BUSY flag reset */
617 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout);
618
619 if (status == HAL_OK)
620 {
621 /* Call the configuration function */
622 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
623
624 if (cmd->DataMode == QSPI_DATA_NONE)
625 {
626 /* When there is no data phase, the transfer start as soon as the configuration is done
627 so wait until TC flag is set to go back in idle state */
628 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
629 {
630 status = HAL_TIMEOUT;
631 }
632 else
633 {
634 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
635
636 /* Update QSPI state */
637 hqspi->State = HAL_QSPI_STATE_READY;
638 }
639
640 }
641 else
642 {
643 /* Update QSPI state */
644 hqspi->State = HAL_QSPI_STATE_READY;
645 }
646 }
647 }
648 else
649 {
650 status = HAL_BUSY;
651 }
652
653 /* Process unlocked */
654 __HAL_UNLOCK(hqspi);
655
656 /* Return function status */
657 return status;
658}
659
660/**
661 * @brief Sets the command configuration in interrupt mode.
662 * @param hqspi: QSPI handle
663 * @param cmd : structure that contains the command configuration information
664 * @note This function is used only in Indirect Read or Write Modes
665 * @retval HAL status
666 */
667HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
668{
669 HAL_StatusTypeDef status = HAL_ERROR;
670
671 /* Check the parameters */
672 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
673 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
674 {
675 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
676 }
677
678 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
679 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
680 {
681 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
682 }
683
684 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
685 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
686 {
687 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
688 }
689
690 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
691 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
692
693 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
694 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
695 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
696
697 /* Process locked */
698 __HAL_LOCK(hqspi);
699
700 if(hqspi->State == HAL_QSPI_STATE_READY)
701 {
702 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
703
704 /* Update QSPI state */
705 hqspi->State = HAL_QSPI_STATE_BUSY;
706
707 /* Wait till BUSY flag reset */
708 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
709
710 if (status == HAL_OK)
711 {
712 if (cmd->DataMode == QSPI_DATA_NONE)
713 {
714 /* When there is no data phase, the transfer start as soon as the configuration is done
715 so activate TC and TE interrupts */
716 /* Enable the QSPI Transfer Error Interrupt */
717 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
718 }
719
720 /* Call the configuration function */
721 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
722
723 if (cmd->DataMode != QSPI_DATA_NONE)
724 {
725 /* Update QSPI state */
726 hqspi->State = HAL_QSPI_STATE_READY;
727 }
728 }
729 }
730 else
731 {
732 status = HAL_BUSY;
733 }
734
735 /* Process unlocked */
736 __HAL_UNLOCK(hqspi);
737
738 /* Return function status */
739 return status;
740}
741
742/**
743 * @brief Transmit an amount of data in blocking mode.
744 * @param hqspi: QSPI handle
745 * @param pData: pointer to data buffer
746 * @param Timeout : Time out duration
747 * @note This function is used only in Indirect Write Mode
748 * @retval HAL status
749 */
750HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
751{
752 HAL_StatusTypeDef status = HAL_OK;
753 __IO uint32_t *data_reg = &hqspi->Instance->DR;
754
755 /* Process locked */
756 __HAL_LOCK(hqspi);
757
758 if(hqspi->State == HAL_QSPI_STATE_READY)
759 {
760 if(pData != NULL )
761 {
762 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
763
764 /* Update state */
765 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
766
767 /* Configure counters and size of the handle */
768 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
769 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
770 hqspi->pTxBuffPtr = pData;
771
772 /* Configure QSPI: CCR register with functional as indirect write */
773 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
774
775 while(hqspi->TxXferCount > 0)
776 {
777 /* Wait until FT flag is set to send data */
778 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, Timeout) != HAL_OK)
779 {
780 status = HAL_TIMEOUT;
781 break;
782 }
783
784 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
785 hqspi->TxXferCount--;
786 }
787
788 if (status == HAL_OK)
789 {
790 /* Wait until TC flag is set to go back in idle state */
791 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
792 {
793 status = HAL_TIMEOUT;
794 }
795 else
796 {
797 /* Clear Transfer Complete bit */
798 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
799
800 /* Clear Busy bit */
801 status = HAL_QSPI_Abort(hqspi);
802 }
803 }
804
805 /* Update QSPI state */
806 hqspi->State = HAL_QSPI_STATE_READY;
807 }
808 else
809 {
810 status = HAL_ERROR;
811 }
812 }
813 else
814 {
815 status = HAL_BUSY;
816 }
817
818 /* Process unlocked */
819 __HAL_UNLOCK(hqspi);
820
821 return status;
822}
823
824
825/**
826 * @brief Receive an amount of data in blocking mode
827 * @param hqspi: QSPI handle
828 * @param pData: pointer to data buffer
829 * @param Timeout : Time out duration
830 * @note This function is used only in Indirect Read Mode
831 * @retval HAL status
832 */
833HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
834{
835 HAL_StatusTypeDef status = HAL_OK;
836 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
837 __IO uint32_t *data_reg = &hqspi->Instance->DR;
838
839 /* Process locked */
840 __HAL_LOCK(hqspi);
841
842 if(hqspi->State == HAL_QSPI_STATE_READY)
843 {
844 if(pData != NULL )
845 {
846 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
847
848 /* Update state */
849 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
850
851 /* Configure counters and size of the handle */
852 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
853 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
854 hqspi->pRxBuffPtr = pData;
855
856 /* Configure QSPI: CCR register with functional as indirect read */
857 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
858
859 /* Start the transfer by re-writing the address in AR register */
860 WRITE_REG(hqspi->Instance->AR, addr_reg);
861
862 while(hqspi->RxXferCount > 0)
863 {
864 /* Wait until FT or TC flag is set to read received data */
865 if(QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, Timeout) != HAL_OK)
866 {
867 status = HAL_TIMEOUT;
868 break;
869 }
870
871 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
872 hqspi->RxXferCount--;
873 }
874
875 if (status == HAL_OK)
876 {
877 /* Wait until TC flag is set to go back in idle state */
878 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
879 {
880 status = HAL_TIMEOUT;
881 }
882 else
883 {
884 /* Clear Transfer Complete bit */
885 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
886
887 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
888 status = HAL_QSPI_Abort(hqspi);
889 }
890 }
891
892 /* Update QSPI state */
893 hqspi->State = HAL_QSPI_STATE_READY;
894 }
895 else
896 {
897 status = HAL_ERROR;
898 }
899 }
900 else
901 {
902 status = HAL_BUSY;
903 }
904
905 /* Process unlocked */
906 __HAL_UNLOCK(hqspi);
907
908 return status;
909}
910
911/**
912 * @brief Send an amount of data in interrupt mode
913 * @param hqspi: QSPI handle
914 * @param pData: pointer to data buffer
915 * @note This function is used only in Indirect Write Mode
916 * @retval HAL status
917 */
918HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
919{
920 HAL_StatusTypeDef status = HAL_OK;
921
922 /* Process locked */
923 __HAL_LOCK(hqspi);
924
925 if(hqspi->State == HAL_QSPI_STATE_READY)
926 {
927 if(pData != NULL )
928 {
929 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
930
931 /* Update state */
932 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
933
934 /* Configure counters and size of the handle */
935 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
936 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
937 hqspi->pTxBuffPtr = pData;
938
939 /* Configure QSPI: CCR register with functional as indirect write */
940 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
941
942 /* Enable the QSPI transfer error, FIFO threshold and transfert complete Interrupts */
943 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
944
945 }
946 else
947 {
948 status = HAL_ERROR;
949 }
950 }
951 else
952 {
953 status = HAL_BUSY;
954 }
955
956 /* Process unlocked */
957 __HAL_UNLOCK(hqspi);
958
959 return status;
960}
961
962/**
963 * @brief Receive an amount of data in no-blocking mode with Interrupt
964 * @param hqspi: QSPI handle
965 * @param pData: pointer to data buffer
966 * @note This function is used only in Indirect Read Mode
967 * @retval HAL status
968 */
969HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
970{
971 HAL_StatusTypeDef status = HAL_OK;
972 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
973
974 /* Process locked */
975 __HAL_LOCK(hqspi);
976
977 if(hqspi->State == HAL_QSPI_STATE_READY)
978 {
979 if(pData != NULL )
980 {
981 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
982
983 /* Update state */
984 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
985
986 /* Configure counters and size of the handle */
987 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
988 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
989 hqspi->pRxBuffPtr = pData;
990
991 /* Configure QSPI: CCR register with functional as indirect read */
992 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
993
994 /* Start the transfer by re-writing the address in AR register */
995 WRITE_REG(hqspi->Instance->AR, addr_reg);
996
997 /* Enable the QSPI transfer error, FIFO threshold and transfert complete Interrupts */
998 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
999 }
1000 else
1001 {
1002 status = HAL_ERROR;
1003 }
1004 }
1005 else
1006 {
1007 status = HAL_BUSY;
1008 }
1009
1010 /* Process unlocked */
1011 __HAL_UNLOCK(hqspi);
1012
1013 return status;
1014}
1015
1016/**
1017 * @brief Sends an amount of data in non blocking mode with DMA.
1018 * @param hqspi: QSPI handle
1019 * @param pData: pointer to data buffer
1020 * @note This function is used only in Indirect Write Mode
1021 * @retval HAL status
1022 */
1023HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1024{
1025 HAL_StatusTypeDef status = HAL_OK;
1026 uint32_t *tmp;
1027
1028 /* Process locked */
1029 __HAL_LOCK(hqspi);
1030
1031 if(hqspi->State == HAL_QSPI_STATE_READY)
1032 {
1033 if(pData != NULL )
1034 {
1035 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1036
1037 /* Update state */
1038 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
1039
1040 /* Configure counters and size of the handle */
1041 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
1042 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
1043 hqspi->pTxBuffPtr = pData;
1044
1045 /* Configure QSPI: CCR register with functional mode as indirect write */
1046 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1047
1048 /* Set the QSPI DMA transfer complete callback */
1049 hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
1050
1051 /* Set the QSPI DMA Half transfer complete callback */
1052 hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
1053
1054 /* Set the DMA error callback */
1055 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1056
1057 /* Configure the direction of the DMA */
1058 hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1059 MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1060
1061 /* Enable the QSPI transmit DMA Channel */
1062 tmp = (uint32_t*)&pData;
1063 HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize);
1064
1065 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1066 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1067 }
1068 else
1069 {
1070 status = HAL_OK;
1071 }
1072 }
1073 else
1074 {
1075 status = HAL_BUSY;
1076 }
1077
1078 /* Process unlocked */
1079 __HAL_UNLOCK(hqspi);
1080
1081 return status;
1082}
1083
1084/**
1085 * @brief Receives an amount of data in non blocking mode with DMA.
1086 * @param hqspi: QSPI handle
1087 * @param pData: pointer to data buffer.
1088 * @note This function is used only in Indirect Read Mode
1089 * @retval HAL status
1090 */
1091HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
1092{
1093 HAL_StatusTypeDef status = HAL_OK;
1094 uint32_t *tmp;
1095 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1096
1097 /* Process locked */
1098 __HAL_LOCK(hqspi);
1099
1100 if(hqspi->State == HAL_QSPI_STATE_READY)
1101 {
1102 if(pData != NULL )
1103 {
1104 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
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) + 1;
1111 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
1112 hqspi->pRxBuffPtr = pData;
1113
1114 /* Set the QSPI DMA transfer complete callback */
1115 hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
1116
1117 /* Set the QSPI DMA Half transfer complete callback */
1118 hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
1119
1120 /* Set the DMA error callback */
1121 hqspi->hdma->XferErrorCallback = QSPI_DMAError;
1122
1123 /* Configure the direction of the DMA */
1124 hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1125 MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
1126
1127 /* Enable the DMA Channel */
1128 tmp = (uint32_t*)&pData;
1129 HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
1130
1131 /* Configure QSPI: CCR register with functional as indirect read */
1132 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1133
1134 /* Start the transfer by re-writing the address in AR register */
1135 WRITE_REG(hqspi->Instance->AR, addr_reg);
1136
1137 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1138 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1139 }
1140 else
1141 {
1142 status = HAL_ERROR;
1143 }
1144 }
1145 else
1146 {
1147 status = HAL_BUSY;
1148 }
1149
1150 /* Process unlocked */
1151 __HAL_UNLOCK(hqspi);
1152
1153 return status;
1154}
1155
1156/**
1157 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1158 * @param hqspi: QSPI handle
1159 * @param cmd: structure that contains the command configuration information.
1160 * @param cfg: structure that contains the polling configuration information.
1161 * @param Timeout : Time out duration
1162 * @note This function is used only in Automatic Polling Mode
1163 * @retval HAL status
1164 */
1165HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1166{
1167 HAL_StatusTypeDef status = HAL_ERROR;
1168
1169 /* Check the parameters */
1170 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1171 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1172 {
1173 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1174 }
1175
1176 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1177 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1178 {
1179 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1180 }
1181
1182 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1183 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1184 {
1185 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1186 }
1187
1188 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1189 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1190
1191 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1192 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1193 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1194
1195 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1196 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1197 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1198
1199 /* Process locked */
1200 __HAL_LOCK(hqspi);
1201
1202 if(hqspi->State == HAL_QSPI_STATE_READY)
1203 {
1204
1205 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1206
1207 /* Update state */
1208 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1209
1210 /* Wait till BUSY flag reset */
1211 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout);
1212
1213 if (status == HAL_OK)
1214 {
1215 /* Configure QSPI: PSMAR register with the status match value */
1216 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1217
1218 /* Configure QSPI: PSMKR register with the status mask value */
1219 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1220
1221 /* Configure QSPI: PIR register with the interval value */
1222 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1223
1224 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1225 (otherwise there will be an infinite loop in blocking mode) */
1226 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1227 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
1228
1229 /* Call the configuration function */
1230 cmd->NbData = cfg->StatusBytesSize;
1231 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1232
1233 /* Wait until SM flag is set to go back in idle state */
1234 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, Timeout) != HAL_OK)
1235 {
1236 status = HAL_TIMEOUT;
1237 }
1238 else
1239 {
1240 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
1241
1242 /* Update state */
1243 hqspi->State = HAL_QSPI_STATE_READY;
1244 }
1245 }
1246 }
1247 else
1248 {
1249 status = HAL_BUSY;
1250 }
1251 /* Process unlocked */
1252 __HAL_UNLOCK(hqspi);
1253
1254 /* Return function status */
1255 return status;
1256}
1257
1258/**
1259 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1260 * @param hqspi: QSPI handle
1261 * @param cmd: structure that contains the command configuration information.
1262 * @param cfg: structure that contains the polling configuration information.
1263 * @note This function is used only in Automatic Polling Mode
1264 * @retval HAL status
1265 */
1266HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
1267{
1268 HAL_StatusTypeDef status = HAL_ERROR;
1269
1270 /* Check the parameters */
1271 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1272 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1273 {
1274 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1275 }
1276
1277 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1278 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1279 {
1280 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1281 }
1282
1283 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1284 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1285 {
1286 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1287 }
1288
1289 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1290 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1291
1292 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1293 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1294 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1295
1296 assert_param(IS_QSPI_INTERVAL(cfg->Interval));
1297 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
1298 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
1299 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1300
1301 /* Process locked */
1302 __HAL_LOCK(hqspi);
1303
1304if(hqspi->State == HAL_QSPI_STATE_READY)
1305 {
1306 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1307
1308 /* Update state */
1309 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1310
1311 /* Wait till BUSY flag reset */
1312 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
1313
1314 if (status == HAL_OK)
1315 {
1316 /* Configure QSPI: PSMAR register with the status match value */
1317 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
1318
1319 /* Configure QSPI: PSMKR register with the status mask value */
1320 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
1321
1322 /* Configure QSPI: PIR register with the interval value */
1323 WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
1324
1325 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1326 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
1327 (cfg->MatchMode | cfg->AutomaticStop));
1328
1329 /* Clear interrupt */
1330 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
1331
1332 /* Enable the QSPI Transfer Error and status match Interrupt */
1333 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
1334
1335 /* Call the configuration function */
1336 cmd->NbData = cfg->StatusBytesSize;
1337 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
1338 }
1339 }
1340 else
1341 {
1342 status = HAL_BUSY;
1343 }
1344
1345 /* Process unlocked */
1346 __HAL_UNLOCK(hqspi);
1347
1348 /* Return function status */
1349 return status;
1350}
1351
1352/**
1353 * @brief Configure the Memory Mapped mode.
1354 * @param hqspi: QSPI handle
1355 * @param cmd: structure that contains the command configuration information.
1356 * @param cfg: structure that contains the memory mapped configuration information.
1357 * @note This function is used only in Memory mapped Mode
1358 * @retval HAL status
1359 */
1360HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
1361{
1362 HAL_StatusTypeDef status = HAL_ERROR;
1363
1364 /* Check the parameters */
1365 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
1366 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1367 {
1368 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
1369 }
1370
1371 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
1372 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1373 {
1374 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
1375 }
1376
1377 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
1378 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1379 {
1380 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
1381 }
1382
1383 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
1384 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
1385
1386 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
1387 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
1388 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
1389
1390 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1391
1392 /* Process locked */
1393 __HAL_LOCK(hqspi);
1394
1395 if(hqspi->State == HAL_QSPI_STATE_READY)
1396 {
1397 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1398
1399 /* Update state */
1400 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
1401
1402 /* Wait till BUSY flag reset */
1403 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
1404
1405 if (status == HAL_OK)
1406 {
1407 /* Configure QSPI: CR register with time out counter enable */
1408 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
1409
1410 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
1411 {
1412 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1413
1414 /* Configure QSPI: LPTR register with the low-power time out value */
1415 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
1416
1417 /* Enable the QSPI TimeOut Interrupt */
1418 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
1419 }
1420
1421 /* Call the configuration function */
1422 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
1423
1424 }
1425 }
1426 else
1427 {
1428 status = HAL_BUSY;
1429
1430 }
1431
1432 /* Process unlocked */
1433 __HAL_UNLOCK(hqspi);
1434
1435 /* Return function status */
1436 return status;
1437}
1438
1439/**
1440 * @brief Transfer Error callbacks
1441 * @param hqspi: QSPI handle
1442 * @retval None
1443 */
1444__weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1445{
1446 /* NOTE : This function Should not be modified, when the callback is needed,
1447 the HAL_QSPI_ErrorCallback could be implemented in the user file
1448 */
1449}
1450
1451/**
1452 * @brief Command completed callbacks.
1453 * @param hqspi: QSPI handle
1454 * @retval None
1455 */
1456__weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1457{
1458 /* NOTE: This function Should not be modified, when the callback is needed,
1459 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1460 */
1461}
1462
1463/**
1464 * @brief Rx Transfer completed callbacks.
1465 * @param hqspi: QSPI handle
1466 * @retval None
1467 */
1468__weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1469{
1470 /* NOTE: This function Should not be modified, when the callback is needed,
1471 the HAL_QSPI_RxCpltCallback could be implemented in the user file
1472 */
1473}
1474
1475/**
1476 * @brief Tx Transfer completed callbacks.
1477 * @param hqspi: QSPI handle
1478 * @retval None
1479 */
1480 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1481{
1482 /* NOTE: This function Should not be modified, when the callback is needed,
1483 the HAL_QSPI_TxCpltCallback could be implemented in the user file
1484 */
1485}
1486
1487/**
1488 * @brief Rx Half Transfer completed callbacks.
1489 * @param hqspi: QSPI handle
1490 * @retval None
1491 */
1492__weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1493{
1494 /* NOTE: This function Should not be modified, when the callback is needed,
1495 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
1496 */
1497}
1498
1499/**
1500 * @brief Tx Half Transfer completed callbacks.
1501 * @param hqspi: QSPI handle
1502 * @retval None
1503 */
1504 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1505{
1506 /* NOTE: This function Should not be modified, when the callback is needed,
1507 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
1508 */
1509}
1510
1511/**
1512 * @brief FIFO Threshold callbacks
1513 * @param hqspi: QSPI handle
1514 * @retval None
1515 */
1516__weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1517{
1518 /* NOTE : This function Should not be modified, when the callback is needed,
1519 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1520 */
1521}
1522
1523/**
1524 * @brief Status Match callbacks
1525 * @param hqspi: QSPI handle
1526 * @retval None
1527 */
1528__weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1529{
1530 /* NOTE : This function Should not be modified, when the callback is needed,
1531 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1532 */
1533}
1534
1535/**
1536 * @brief Timeout callbacks
1537 * @param hqspi: QSPI handle
1538 * @retval None
1539 */
1540__weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1541{
1542 /* NOTE : This function Should not be modified, when the callback is needed,
1543 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1544 */
1545}
1546
1547/**
1548 * @}
1549 */
1550
1551/** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
1552 * @brief QSPI control and State functions
1553 *
1554@verbatim
1555 ===============================================================================
1556 ##### Peripheral Control and State functions #####
1557 ===============================================================================
1558 [..]
1559 This subsection provides a set of functions allowing to :
1560 (+) Check in run-time the state of the driver.
1561 (+) Check the error code set during last operation.
1562 (+) Abort any operation.
1563.....
1564@endverbatim
1565 * @{
1566 */
1567
1568/**
1569 * @brief Return the QSPI state.
1570 * @param hqspi: QSPI handle
1571 * @retval HAL state
1572 */
1573HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
1574{
1575 return hqspi->State;
1576}
1577
1578/**
1579* @brief Return the QSPI error code
1580* @param hqspi: QSPI handle
1581* @retval QSPI Error Code
1582*/
1583uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
1584{
1585 return hqspi->ErrorCode;
1586}
1587
1588/**
1589* @brief Abort the current transmission
1590* @param hqspi: QSPI handle
1591* @retval HAL status
1592*/
1593HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
1594{
1595 HAL_StatusTypeDef status = HAL_ERROR;
1596
1597 /* Configure QSPI: CR register with Abort request */
1598 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
1599
1600 /* Wait until TC flag is set to go back in idle state */
1601 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
1602 {
1603 status = HAL_TIMEOUT;
1604 }
1605 else
1606 {
1607 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1608
1609 /* Wait until BUSY flag is reset */
1610 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
1611
1612 /* Update state */
1613 hqspi->State = HAL_QSPI_STATE_READY;
1614 }
1615
1616 return status;
1617}
1618
1619/** @brief Set QSPI timeout
1620 * @param hqspi: QSPI handle.
1621 * @param Timeout: Timeout for the QSPI memory access.
1622 * @retval None
1623 */
1624void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
1625{
1626 hqspi->Timeout = Timeout;
1627}
1628
1629/**
1630* @}
1631*/
1632
1633/* Private functions ---------------------------------------------------------*/
1634
1635/**
1636 * @brief DMA QSPI receive process complete callback.
1637 * @param hdma: DMA handle
1638 * @retval None
1639 */
1640static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
1641{
1642 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1643 hqspi->RxXferCount = 0;
1644
1645 /* Wait for QSPI TC Flag */
1646 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
1647 {
1648 /* Time out Occurred */
1649 HAL_QSPI_ErrorCallback(hqspi);
1650 }
1651 else
1652 {
1653 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
1654 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1655
1656 /* Disable the DMA channel */
1657 HAL_DMA_Abort(hdma);
1658
1659 /* Clear Transfer Complete bit */
1660 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1661
1662 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
1663 HAL_QSPI_Abort(hqspi);
1664
1665 /* Update state */
1666 hqspi->State = HAL_QSPI_STATE_READY;
1667
1668 HAL_QSPI_RxCpltCallback(hqspi);
1669 }
1670}
1671
1672/**
1673 * @brief DMA QSPI transmit process complete callback.
1674 * @param hdma: DMA handle
1675 * @retval None
1676 */
1677static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
1678{
1679 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1680 hqspi->TxXferCount = 0;
1681
1682 /* Wait for QSPI TC Flag */
1683 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
1684 {
1685 /* Time out Occurred */
1686 HAL_QSPI_ErrorCallback(hqspi);
1687 }
1688 else
1689 {
1690 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
1691 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
1692
1693 /* Disable the DMA channel */
1694 HAL_DMA_Abort(hdma);
1695
1696 /* Clear Transfer Complete bit */
1697 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
1698
1699 /* Clear Busy bit */
1700 HAL_QSPI_Abort(hqspi);
1701
1702 /* Update state */
1703 hqspi->State = HAL_QSPI_STATE_READY;
1704
1705 HAL_QSPI_TxCpltCallback(hqspi);
1706 }
1707}
1708
1709/**
1710 * @brief DMA QSPI receive process half complete callback
1711 * @param hdma : DMA handle
1712 * @retval None
1713 */
1714static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1715{
1716 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1717
1718 HAL_QSPI_RxHalfCpltCallback(hqspi);
1719}
1720
1721/**
1722 * @brief DMA QSPI transmit process half complete callback
1723 * @param hdma : DMA handle
1724 * @retval None
1725 */
1726static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1727{
1728 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1729
1730 HAL_QSPI_TxHalfCpltCallback(hqspi);
1731}
1732
1733/**
1734 * @brief DMA QSPI communication error callback.
1735 * @param hdma: DMA handle
1736 * @retval None
1737 */
1738static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
1739{
1740 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1741
1742 hqspi->RxXferCount = 0;
1743 hqspi->TxXferCount = 0;
1744 hqspi->State = HAL_QSPI_STATE_ERROR;
1745 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
1746
1747 HAL_QSPI_ErrorCallback(hqspi);
1748}
1749
1750/**
1751 * @brief This function wait a flag state until time out.
1752 * @param hqspi: QSPI handle
1753 * @param Flag: Flag checked
1754 * @param State: Value of the flag expected
1755 * @param Timeout: Duration of the time out
1756 * @retval HAL status
1757 */
1758static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
1759 FlagStatus State, uint32_t Timeout)
1760{
1761 uint32_t tickstart = HAL_GetTick();
1762
1763 /* Wait until flag is in expected state */
1764 while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
1765 {
1766 /* Check for the Timeout */
1767 if (Timeout != HAL_MAX_DELAY)
1768 {
1769 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1770 {
1771 hqspi->State = HAL_QSPI_STATE_ERROR;
1772 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
1773
1774 return HAL_TIMEOUT;
1775 }
1776 }
1777 }
1778 return HAL_OK;
1779}
1780
1781/**
1782 * @brief This function configures the communication registers
1783 * @param hqspi: QSPI handle
1784 * @param cmd: structure that contains the command configuration information
1785 * @param FunctionalMode: functional mode to configured
1786 * This parameter can be one of the following values:
1787 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
1788 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
1789 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
1790 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
1791 * @retval None
1792 */
1793static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
1794{
1795 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
1796
1797 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
1798 {
1799 /* Configure QSPI: DLR register with the number of data to read or write */
1800 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1));
1801 }
1802
1803 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
1804 {
1805 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1806 {
1807 /* Configure QSPI: ABR register with alternate bytes value */
1808 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
1809
1810 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1811 {
1812 /*---- Command with instruction, address and alternate bytes ----*/
1813 /* Configure QSPI: CCR register with all communications parameters */
1814 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1815 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
1816 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
1817 cmd->InstructionMode | cmd->Instruction | FunctionalMode));
1818
1819 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
1820 {
1821 /* Configure QSPI: AR register with address value */
1822 WRITE_REG(hqspi->Instance->AR, cmd->Address);
1823 }
1824 }
1825 else
1826 {
1827 /*---- Command with instruction and alternate bytes ----*/
1828 /* Configure QSPI: CCR register with all communications parameters */
1829 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1830 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
1831 cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
1832 cmd->Instruction | FunctionalMode));
1833 }
1834 }
1835 else
1836 {
1837 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1838 {
1839 /*---- Command with instruction and address ----*/
1840 /* Configure QSPI: CCR register with all communications parameters */
1841 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1842 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
1843 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
1844 cmd->Instruction | FunctionalMode));
1845
1846 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
1847 {
1848 /* Configure QSPI: AR register with address value */
1849 WRITE_REG(hqspi->Instance->AR, cmd->Address);
1850 }
1851 }
1852 else
1853 {
1854 /*---- Command with only instruction ----*/
1855 /* Configure QSPI: CCR register with all communications parameters */
1856 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1857 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
1858 cmd->AddressMode | cmd->InstructionMode | cmd->Instruction |
1859 FunctionalMode));
1860 }
1861 }
1862 }
1863 else
1864 {
1865 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
1866 {
1867 /* Configure QSPI: ABR register with alternate bytes value */
1868 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
1869
1870 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1871 {
1872 /*---- Command with address and alternate bytes ----*/
1873 /* Configure QSPI: CCR register with all communications parameters */
1874 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1875 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
1876 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
1877 cmd->InstructionMode | FunctionalMode));
1878
1879 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
1880 {
1881 /* Configure QSPI: AR register with address value */
1882 WRITE_REG(hqspi->Instance->AR, cmd->Address);
1883 }
1884 }
1885 else
1886 {
1887 /*---- Command with only alternate bytes ----*/
1888 /* Configure QSPI: CCR register with all communications parameters */
1889 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1890 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
1891 cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
1892 FunctionalMode));
1893 }
1894 }
1895 else
1896 {
1897 if (cmd->AddressMode != QSPI_ADDRESS_NONE)
1898 {
1899 /*---- Command with only address ----*/
1900 /* Configure QSPI: CCR register with all communications parameters */
1901 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1902 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
1903 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
1904 FunctionalMode));
1905
1906 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
1907 {
1908 /* Configure QSPI: AR register with address value */
1909 WRITE_REG(hqspi->Instance->AR, cmd->Address);
1910 }
1911 }
1912 else
1913 {
1914 /*---- Command with only data phase ----*/
1915 if (cmd->DataMode != QSPI_DATA_NONE)
1916 {
1917 /* Configure QSPI: CCR register with all communications parameters */
1918 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
1919 cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
1920 cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
1921 }
1922 }
1923 }
1924 }
1925}
1926
1927/**
1928 * @}
1929 */
1930
1931/**
1932 * @}
1933 */
1934#endif /* STM32F446xx || STM32F469xx || STM32F479xx */
1935
1936#endif /* HAL_QSPI_MODULE_ENABLED */
1937/**
1938 * @}
1939 */
1940
1941/**
1942 * @}
1943 */
1944
1945/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.