2 ******************************************************************************
3 * @file stm32f4xx_hal_qspi.c
4 * @author MCD Application Team
7 * @brief QSPI HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the QuadSPI interface (QSPI).
10 * + Initialization and de-initialization functions
11 * + Indirect functional mode management
12 * + Memory-mapped functional mode management
13 * + Auto-polling functional mode management
14 * + Interrupts and flags management
15 * + DMA channel configuration for indirect functional mode
16 * + Errors management and abort functionality
20 ===============================================================================
21 ##### How to use this driver #####
22 ===============================================================================
24 *** Initialization ***
25 ======================
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.
41 *** Indirect functional mode ***
42 ================================
44 (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
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
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
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.
73 *** Auto-polling functional mode ***
74 ====================================
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
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
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.
94 *** Memory-mapped functional mode ***
95 =====================================
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
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
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.
112 *** Errors management and abort functionality ***
113 ==================================================
115 (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
116 (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
118 (++) In polling mode, the output of the function is done when the transfer
119 complete bit is set and the busy bit cleared.
120 (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
121 the transfer complete bi is set.
123 *** Control functions ***
124 =========================
126 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
127 (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
128 (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
129 (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
131 *** Workarounds linked to Silicon Limitation ***
132 ====================================================
134 (#) Workarounds Implemented inside HAL Driver
135 (++) Extra data written in the FIFO at the end of a read transfer
138 ******************************************************************************
141 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
143 * Redistribution and use in source and binary forms, with or without modification,
144 * are permitted provided that the following conditions are met:
145 * 1. Redistributions of source code must retain the above copyright notice,
146 * this list of conditions and the following disclaimer.
147 * 2. Redistributions in binary form must reproduce the above copyright notice,
148 * this list of conditions and the following disclaimer in the documentation
149 * and/or other materials provided with the distribution.
150 * 3. Neither the name of STMicroelectronics nor the names of its contributors
151 * may be used to endorse or promote products derived from this software
152 * without specific prior written permission.
154 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
155 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
156 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
157 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
158 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
159 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
160 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
161 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
162 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
163 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
165 ******************************************************************************
168 /* Includes ------------------------------------------------------------------*/
169 #include "stm32f4xx_hal.h"
171 /** @addtogroup STM32F4xx_HAL_Driver
175 /** @defgroup QSPI QSPI
176 * @brief QSPI HAL module driver
179 #ifdef HAL_QSPI_MODULE_ENABLED
181 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
182 defined(STM32F412Rx) || defined(STM32F413xx) || defined(STM32F423xx)
184 /* Private typedef -----------------------------------------------------------*/
185 /* Private define ------------------------------------------------------------*/
186 /** @addtogroup QSPI_Private_Constants
189 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
190 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
191 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
192 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
197 /* Private macro -------------------------------------------------------------*/
198 /** @addtogroup QSPI_Private_Macros QSPI Private Macros
201 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
202 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
203 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
204 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
209 /* Private variables ---------------------------------------------------------*/
210 /* Private function prototypes -----------------------------------------------*/
211 /** @addtogroup QSPI_Private_Functions QSPI Private Functions
214 static void QSPI_DMARxCplt(DMA_HandleTypeDef
*hdma
);
215 static void QSPI_DMATxCplt(DMA_HandleTypeDef
*hdma
);
216 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
217 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
218 static void QSPI_DMAError(DMA_HandleTypeDef
*hdma
);
219 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef
*hdma
);
220 static HAL_StatusTypeDef
QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef
*hqspi
, uint32_t Flag
, FlagStatus State
, uint32_t tickstart
, uint32_t Timeout
);
221 static void QSPI_Config(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, uint32_t FunctionalMode
);
226 /* Exported functions ---------------------------------------------------------*/
228 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
232 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
233 * @brief Initialization and Configuration functions
236 ===============================================================================
237 ##### Initialization and Configuration functions #####
238 ===============================================================================
240 This subsection provides a set of functions allowing to :
241 (+) Initialize the QuadSPI.
242 (+) De-initialize the QuadSPI.
249 * @brief Initializes the QSPI mode according to the specified parameters
250 * in the QSPI_InitTypeDef and creates the associated handle.
251 * @param hqspi: qspi handle
254 HAL_StatusTypeDef
HAL_QSPI_Init(QSPI_HandleTypeDef
*hqspi
)
256 HAL_StatusTypeDef status
= HAL_ERROR
;
257 uint32_t tickstart
= HAL_GetTick();
259 /* Check the QSPI handle allocation */
265 /* Check the parameters */
266 assert_param(IS_QSPI_ALL_INSTANCE(hqspi
->Instance
));
267 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi
->Init
.ClockPrescaler
));
268 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi
->Init
.FifoThreshold
));
269 assert_param(IS_QSPI_SSHIFT(hqspi
->Init
.SampleShifting
));
270 assert_param(IS_QSPI_FLASH_SIZE(hqspi
->Init
.FlashSize
));
271 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi
->Init
.ChipSelectHighTime
));
272 assert_param(IS_QSPI_CLOCK_MODE(hqspi
->Init
.ClockMode
));
273 assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi
->Init
.DualFlash
));
275 if (hqspi
->Init
.DualFlash
!= QSPI_DUALFLASH_ENABLE
)
277 assert_param(IS_QSPI_FLASH_ID(hqspi
->Init
.FlashID
));
283 if(hqspi
->State
== HAL_QSPI_STATE_RESET
)
285 /* Allocate lock resource and initialize it */
286 hqspi
->Lock
= HAL_UNLOCKED
;
288 /* Init the low level hardware : GPIO, CLOCK */
289 HAL_QSPI_MspInit(hqspi
);
291 /* Configure the default timeout for the QSPI memory access */
292 HAL_QSPI_SetTimeout(hqspi
, HAL_QPSI_TIMEOUT_DEFAULT_VALUE
);
295 /* Configure QSPI FIFO Threshold */
296 MODIFY_REG(hqspi
->Instance
->CR
, QUADSPI_CR_FTHRES
, ((hqspi
->Init
.FifoThreshold
- 1U) << 8U));
298 /* Wait till BUSY flag reset */
299 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_BUSY
, RESET
, tickstart
, hqspi
->Timeout
);
304 /* Configure QSPI Clock Prescaler and Sample Shift */
305 MODIFY_REG(hqspi
->Instance
->CR
,(QUADSPI_CR_PRESCALER
| QUADSPI_CR_SSHIFT
| QUADSPI_CR_FSEL
| QUADSPI_CR_DFM
), ((hqspi
->Init
.ClockPrescaler
<< 24U)| hqspi
->Init
.SampleShifting
| hqspi
->Init
.FlashID
| hqspi
->Init
.DualFlash
));
307 /* Configure QSPI Flash Size, CS High Time and Clock Mode */
308 MODIFY_REG(hqspi
->Instance
->DCR
, (QUADSPI_DCR_FSIZE
| QUADSPI_DCR_CSHT
| QUADSPI_DCR_CKMODE
),
309 ((hqspi
->Init
.FlashSize
<< 16U) | hqspi
->Init
.ChipSelectHighTime
| hqspi
->Init
.ClockMode
));
311 /* Enable the QSPI peripheral */
312 __HAL_QSPI_ENABLE(hqspi
);
314 /* Set QSPI error code to none */
315 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
317 /* Initialize the QSPI state */
318 hqspi
->State
= HAL_QSPI_STATE_READY
;
324 /* Return function status */
329 * @brief DeInitializes the QSPI peripheral
330 * @param hqspi: qspi handle
333 HAL_StatusTypeDef
HAL_QSPI_DeInit(QSPI_HandleTypeDef
*hqspi
)
335 /* Check the QSPI handle allocation */
344 /* Disable the QSPI Peripheral Clock */
345 __HAL_QSPI_DISABLE(hqspi
);
347 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
348 HAL_QSPI_MspDeInit(hqspi
);
350 /* Set QSPI error code to none */
351 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
353 /* Initialize the QSPI state */
354 hqspi
->State
= HAL_QSPI_STATE_RESET
;
363 * @brief QSPI MSP Init
364 * @param hqspi: QSPI handle
367 __weak
void HAL_QSPI_MspInit(QSPI_HandleTypeDef
*hqspi
)
369 /* Prevent unused argument(s) compilation warning */
372 /* NOTE : This function should not be modified, when the callback is needed,
373 the HAL_QSPI_MspInit can be implemented in the user file
378 * @brief QSPI MSP DeInit
379 * @param hqspi: QSPI handle
382 __weak
void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef
*hqspi
)
384 /* Prevent unused argument(s) compilation warning */
387 /* NOTE : This function should not be modified, when the callback is needed,
388 the HAL_QSPI_MspDeInit can be implemented in the user file
396 /** @defgroup QSPI_Exported_Functions_Group2 IO operation functions
397 * @brief QSPI Transmit/Receive functions
400 ===============================================================================
401 ##### IO operation functions #####
402 ===============================================================================
404 This subsection provides a set of functions allowing to :
405 (+) Handle the interrupts.
406 (+) Handle the command sequence.
407 (+) Transmit data in blocking, interrupt or DMA mode.
408 (+) Receive data in blocking, interrupt or DMA mode.
409 (+) Manage the auto-polling functional mode.
410 (+) Manage the memory-mapped functional mode.
417 * @brief This function handles QSPI interrupt request.
418 * @param hqspi: QSPI handle
421 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef
*hqspi
)
423 __IO
uint32_t *data_reg
;
424 uint32_t flag
= READ_REG(hqspi
->Instance
->SR
);
425 uint32_t itsource
= READ_REG(hqspi
->Instance
->CR
);
427 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
428 if(((flag
& QSPI_FLAG_FT
)!= RESET
) && ((itsource
& QSPI_IT_FT
)!= RESET
))
430 data_reg
= &hqspi
->Instance
->DR
;
432 if(hqspi
->State
== HAL_QSPI_STATE_BUSY_INDIRECT_TX
)
434 /* Transmission process */
435 while(__HAL_QSPI_GET_FLAG(hqspi
, QSPI_FLAG_FT
) != 0U)
437 if (hqspi
->TxXferCount
> 0U)
439 /* Fill the FIFO until it is full */
440 *(__IO
uint8_t *)data_reg
= *hqspi
->pTxBuffPtr
++;
441 hqspi
->TxXferCount
--;
445 /* No more data available for the transfer */
446 /* Disable the QSPI FIFO Threshold Interrupt */
447 __HAL_QSPI_DISABLE_IT(hqspi
, QSPI_IT_FT
);
452 else if(hqspi
->State
== HAL_QSPI_STATE_BUSY_INDIRECT_RX
)
454 /* Receiving Process */
455 while(__HAL_QSPI_GET_FLAG(hqspi
, QSPI_FLAG_FT
) != 0U)
457 if (hqspi
->RxXferCount
> 0U)
459 /* Read the FIFO until it is empty */
460 *hqspi
->pRxBuffPtr
++ = *(__IO
uint8_t *)data_reg
;
461 hqspi
->RxXferCount
--;
465 /* All data have been received for the transfer */
466 /* Disable the QSPI FIFO Threshold Interrupt */
467 __HAL_QSPI_DISABLE_IT(hqspi
, QSPI_IT_FT
);
473 /* FIFO Threshold callback */
474 HAL_QSPI_FifoThresholdCallback(hqspi
);
477 /* QSPI Transfer Complete interrupt occurred -------------------------------*/
478 else if(((flag
& QSPI_FLAG_TC
)!= RESET
) && ((itsource
& QSPI_IT_TC
)!= RESET
))
480 /* Clear interrupt */
481 WRITE_REG(hqspi
->Instance
->FCR
, QSPI_FLAG_TC
);
483 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
484 __HAL_QSPI_DISABLE_IT(hqspi
, QSPI_IT_TC
| QSPI_IT_TE
| QSPI_IT_FT
);
486 /* Transfer complete callback */
487 if(hqspi
->State
== HAL_QSPI_STATE_BUSY_INDIRECT_TX
)
489 if ((hqspi
->Instance
->CR
& QUADSPI_CR_DMAEN
)!= RESET
)
491 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
492 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
494 /* Disable the DMA channel */
495 __HAL_DMA_DISABLE(hqspi
->hdma
);
499 HAL_QSPI_Abort_IT(hqspi
);
501 /* Change state of QSPI */
502 hqspi
->State
= HAL_QSPI_STATE_READY
;
504 /* TX Complete callback */
505 HAL_QSPI_TxCpltCallback(hqspi
);
507 else if(hqspi
->State
== HAL_QSPI_STATE_BUSY_INDIRECT_RX
)
509 if ((hqspi
->Instance
->CR
& QUADSPI_CR_DMAEN
)!= RESET
)
511 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
512 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
514 /* Disable the DMA channel */
515 __HAL_DMA_DISABLE(hqspi
->hdma
);
519 data_reg
= &hqspi
->Instance
->DR
;
520 while(READ_BIT(hqspi
->Instance
->SR
, QUADSPI_SR_FLEVEL
) != 0U)
522 if (hqspi
->RxXferCount
> 0U)
524 /* Read the last data received in the FIFO until it is empty */
525 *hqspi
->pRxBuffPtr
++ = *(__IO
uint8_t *)data_reg
;
526 hqspi
->RxXferCount
--;
530 /* All data have been received for the transfer */
535 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
536 HAL_QSPI_Abort_IT(hqspi
);
538 /* Change state of QSPI */
539 hqspi
->State
= HAL_QSPI_STATE_READY
;
541 /* RX Complete callback */
542 HAL_QSPI_RxCpltCallback(hqspi
);
544 else if(hqspi
->State
== HAL_QSPI_STATE_BUSY
)
546 /* Change state of QSPI */
547 hqspi
->State
= HAL_QSPI_STATE_READY
;
549 /* Command Complete callback */
550 HAL_QSPI_CmdCpltCallback(hqspi
);
552 else if(hqspi
->State
== HAL_QSPI_STATE_ABORT
)
554 /* Change state of QSPI */
555 hqspi
->State
= HAL_QSPI_STATE_READY
;
557 if (hqspi
->ErrorCode
== HAL_QSPI_ERROR_NONE
)
559 /* Abort called by the user */
561 /* Abort Complete callback */
562 HAL_QSPI_AbortCpltCallback(hqspi
);
566 /* Abort due to an error (eg : DMA error) */
569 HAL_QSPI_ErrorCallback(hqspi
);
574 /* QSPI Status Match interrupt occurred ------------------------------------*/
575 else if(((flag
& QSPI_FLAG_SM
)!= RESET
) && ((itsource
& QSPI_IT_SM
)!= RESET
))
577 /* Clear interrupt */
578 WRITE_REG(hqspi
->Instance
->FCR
, QSPI_FLAG_SM
);
580 /* Check if the automatic poll mode stop is activated */
581 if(READ_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_APMS
) != 0U)
583 /* Disable the QSPI Transfer Error and Status Match Interrupts */
584 __HAL_QSPI_DISABLE_IT(hqspi
, (QSPI_IT_SM
| QSPI_IT_TE
));
586 /* Change state of QSPI */
587 hqspi
->State
= HAL_QSPI_STATE_READY
;
590 /* Status match callback */
591 HAL_QSPI_StatusMatchCallback(hqspi
);
594 /* QSPI Transfer Error interrupt occurred ----------------------------------*/
595 else if(((flag
& QSPI_FLAG_TE
)!= RESET
) && ((itsource
& QSPI_IT_TE
)!= RESET
))
597 /* Clear interrupt */
598 WRITE_REG(hqspi
->Instance
->FCR
, QSPI_FLAG_TE
);
600 /* Disable all the QSPI Interrupts */
601 __HAL_QSPI_DISABLE_IT(hqspi
, QSPI_IT_SM
| QSPI_IT_TC
| QSPI_IT_TE
| QSPI_IT_FT
);
604 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_TRANSFER
;
606 if ((hqspi
->Instance
->CR
& QUADSPI_CR_DMAEN
)!= RESET
)
608 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
609 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
611 /* Disable the DMA channel */
612 hqspi
->hdma
->XferAbortCallback
= QSPI_DMAAbortCplt
;
613 HAL_DMA_Abort_IT(hqspi
->hdma
);
617 /* Change state of QSPI */
618 hqspi
->State
= HAL_QSPI_STATE_READY
;
621 HAL_QSPI_ErrorCallback(hqspi
);
625 /* QSPI Timeout interrupt occurred -----------------------------------------*/
626 else if(((flag
& QSPI_FLAG_TO
)!= RESET
) && ((itsource
& QSPI_IT_TO
)!= RESET
))
628 /* Clear interrupt */
629 WRITE_REG(hqspi
->Instance
->FCR
, QSPI_FLAG_TO
);
631 /* Time out callback */
632 HAL_QSPI_TimeOutCallback(hqspi
);
637 * @brief Sets the command configuration.
638 * @param hqspi: QSPI handle
639 * @param cmd : structure that contains the command configuration information
640 * @param Timeout : Time out duration
641 * @note This function is used only in Indirect Read or Write Modes
644 HAL_StatusTypeDef
HAL_QSPI_Command(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, uint32_t Timeout
)
646 HAL_StatusTypeDef status
= HAL_ERROR
;
647 uint32_t tickstart
= HAL_GetTick();
649 /* Check the parameters */
650 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
651 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
653 assert_param(IS_QSPI_INSTRUCTION(cmd
->Instruction
));
656 assert_param(IS_QSPI_ADDRESS_MODE(cmd
->AddressMode
));
657 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
659 assert_param(IS_QSPI_ADDRESS_SIZE(cmd
->AddressSize
));
662 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd
->AlternateByteMode
));
663 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
665 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd
->AlternateBytesSize
));
668 assert_param(IS_QSPI_DUMMY_CYCLES(cmd
->DummyCycles
));
669 assert_param(IS_QSPI_DATA_MODE(cmd
->DataMode
));
671 assert_param(IS_QSPI_DDR_MODE(cmd
->DdrMode
));
672 assert_param(IS_QSPI_DDR_HHC(cmd
->DdrHoldHalfCycle
));
673 assert_param(IS_QSPI_SIOO_MODE(cmd
->SIOOMode
));
678 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
680 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
682 /* Update QSPI state */
683 hqspi
->State
= HAL_QSPI_STATE_BUSY
;
685 /* Wait till BUSY flag reset */
686 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
688 if (status
== HAL_OK
)
690 /* Call the configuration function */
691 QSPI_Config(hqspi
, cmd
, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
693 if (cmd
->DataMode
== QSPI_DATA_NONE
)
695 /* When there is no data phase, the transfer start as soon as the configuration is done
696 so wait until TC flag is set to go back in idle state */
697 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
699 if (status
== HAL_OK
)
701 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
703 /* Update QSPI state */
704 hqspi
->State
= HAL_QSPI_STATE_READY
;
710 /* Update QSPI state */
711 hqspi
->State
= HAL_QSPI_STATE_READY
;
720 /* Process unlocked */
723 /* Return function status */
728 * @brief Sets the command configuration in interrupt mode.
729 * @param hqspi: QSPI handle
730 * @param cmd : structure that contains the command configuration information
731 * @note This function is used only in Indirect Read or Write Modes
734 HAL_StatusTypeDef
HAL_QSPI_Command_IT(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
)
736 __IO
uint32_t count
= 0U;
737 HAL_StatusTypeDef status
= HAL_OK
;
739 /* Check the parameters */
740 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
741 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
743 assert_param(IS_QSPI_INSTRUCTION(cmd
->Instruction
));
746 assert_param(IS_QSPI_ADDRESS_MODE(cmd
->AddressMode
));
747 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
749 assert_param(IS_QSPI_ADDRESS_SIZE(cmd
->AddressSize
));
752 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd
->AlternateByteMode
));
753 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
755 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd
->AlternateBytesSize
));
758 assert_param(IS_QSPI_DUMMY_CYCLES(cmd
->DummyCycles
));
759 assert_param(IS_QSPI_DATA_MODE(cmd
->DataMode
));
761 assert_param(IS_QSPI_DDR_MODE(cmd
->DdrMode
));
762 assert_param(IS_QSPI_DDR_HHC(cmd
->DdrHoldHalfCycle
));
763 assert_param(IS_QSPI_SIOO_MODE(cmd
->SIOOMode
));
768 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
770 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
772 /* Update QSPI state */
773 hqspi
->State
= HAL_QSPI_STATE_BUSY
;
775 /* Wait till BUSY flag reset */
776 count
= (hqspi
->Timeout
) * (SystemCoreClock
/ 16U / 1000U);
781 hqspi
->State
= HAL_QSPI_STATE_ERROR
;
782 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_TIMEOUT
;
783 status
= HAL_TIMEOUT
;
786 while ((__HAL_QSPI_GET_FLAG(hqspi
, QSPI_FLAG_BUSY
)) != RESET
);
788 if (status
== HAL_OK
)
790 if (cmd
->DataMode
== QSPI_DATA_NONE
)
792 /* Clear interrupt */
793 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TE
| QSPI_FLAG_TC
);
796 /* Call the configuration function */
797 QSPI_Config(hqspi
, cmd
, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
799 if (cmd
->DataMode
== QSPI_DATA_NONE
)
801 /* When there is no data phase, the transfer start as soon as the configuration is done
802 so activate TC and TE interrupts */
803 /* Process unlocked */
806 /* Enable the QSPI Transfer Error Interrupt */
807 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
| QSPI_IT_TC
);
811 /* Update QSPI state */
812 hqspi
->State
= HAL_QSPI_STATE_READY
;
814 /* Process unlocked */
820 /* Process unlocked */
828 /* Process unlocked */
832 /* Return function status */
837 * @brief Transmit an amount of data in blocking mode.
838 * @param hqspi: QSPI handle
839 * @param pData: pointer to data buffer
840 * @param Timeout : Time out duration
841 * @note This function is used only in Indirect Write Mode
844 HAL_StatusTypeDef
HAL_QSPI_Transmit(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
, uint32_t Timeout
)
846 HAL_StatusTypeDef status
= HAL_OK
;
847 uint32_t tickstart
= HAL_GetTick();
848 __IO
uint32_t *data_reg
= &hqspi
->Instance
->DR
;
853 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
855 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
860 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_TX
;
862 /* Configure counters and size of the handle */
863 hqspi
->TxXferCount
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
864 hqspi
->TxXferSize
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
865 hqspi
->pTxBuffPtr
= pData
;
867 /* Configure QSPI: CCR register with functional as indirect write */
868 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
870 while(hqspi
->TxXferCount
> 0U)
872 /* Wait until FT flag is set to send data */
873 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_FT
, SET
, tickstart
, Timeout
);
875 if (status
!= HAL_OK
)
880 *(__IO
uint8_t *)data_reg
= *hqspi
->pTxBuffPtr
++;
881 hqspi
->TxXferCount
--;
884 if (status
== HAL_OK
)
886 /* Wait until TC flag is set to go back in idle state */
887 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
889 if (status
== HAL_OK
)
891 /* Clear Transfer Complete bit */
892 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
895 status
= HAL_QSPI_Abort(hqspi
);
899 /* Update QSPI state */
900 hqspi
->State
= HAL_QSPI_STATE_READY
;
904 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
913 /* Process unlocked */
921 * @brief Receive an amount of data in blocking mode
922 * @param hqspi: QSPI handle
923 * @param pData: pointer to data buffer
924 * @param Timeout : Time out duration
925 * @note This function is used only in Indirect Read Mode
928 HAL_StatusTypeDef
HAL_QSPI_Receive(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
, uint32_t Timeout
)
930 HAL_StatusTypeDef status
= HAL_OK
;
931 uint32_t tickstart
= HAL_GetTick();
932 uint32_t addr_reg
= READ_REG(hqspi
->Instance
->AR
);
933 __IO
uint32_t *data_reg
= &hqspi
->Instance
->DR
;
938 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
940 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
944 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_RX
;
946 /* Configure counters and size of the handle */
947 hqspi
->RxXferCount
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
948 hqspi
->RxXferSize
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
949 hqspi
->pRxBuffPtr
= pData
;
951 /* Configure QSPI: CCR register with functional as indirect read */
952 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
954 /* Start the transfer by re-writing the address in AR register */
955 WRITE_REG(hqspi
->Instance
->AR
, addr_reg
);
957 while(hqspi
->RxXferCount
> 0U)
959 /* Wait until FT or TC flag is set to read received data */
960 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, (QSPI_FLAG_FT
| QSPI_FLAG_TC
), SET
, tickstart
, Timeout
);
962 if (status
!= HAL_OK
)
967 *hqspi
->pRxBuffPtr
++ = *(__IO
uint8_t *)data_reg
;
968 hqspi
->RxXferCount
--;
971 if (status
== HAL_OK
)
973 /* Wait until TC flag is set to go back in idle state */
974 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
976 if (status
== HAL_OK
)
978 /* Clear Transfer Complete bit */
979 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
981 /* Workaround - Extra data written in the FIFO at the end of a read transfer */
982 status
= HAL_QSPI_Abort(hqspi
);
986 /* Update QSPI state */
987 hqspi
->State
= HAL_QSPI_STATE_READY
;
991 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1000 /* Process unlocked */
1001 __HAL_UNLOCK(hqspi
);
1007 * @brief Send an amount of data in interrupt mode
1008 * @param hqspi: QSPI handle
1009 * @param pData: pointer to data buffer
1010 * @note This function is used only in Indirect Write Mode
1011 * @retval HAL status
1013 HAL_StatusTypeDef
HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
)
1015 HAL_StatusTypeDef status
= HAL_OK
;
1017 /* Process locked */
1020 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1022 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1026 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_TX
;
1028 /* Configure counters and size of the handle */
1029 hqspi
->TxXferCount
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
1030 hqspi
->TxXferSize
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
1031 hqspi
->pTxBuffPtr
= pData
;
1033 /* Configure QSPI: CCR register with functional as indirect write */
1034 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
1036 /* Clear interrupt */
1037 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TE
| QSPI_FLAG_TC
);
1039 /* Process unlocked */
1040 __HAL_UNLOCK(hqspi
);
1042 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1043 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
| QSPI_IT_FT
| QSPI_IT_TC
);
1048 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1051 /* Process unlocked */
1052 __HAL_UNLOCK(hqspi
);
1059 /* Process unlocked */
1060 __HAL_UNLOCK(hqspi
);
1067 * @brief Receive an amount of data in no-blocking mode with Interrupt
1068 * @param hqspi: QSPI handle
1069 * @param pData: pointer to data buffer
1070 * @note This function is used only in Indirect Read Mode
1071 * @retval HAL status
1073 HAL_StatusTypeDef
HAL_QSPI_Receive_IT(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
)
1075 HAL_StatusTypeDef status
= HAL_OK
;
1076 uint32_t addr_reg
= READ_REG(hqspi
->Instance
->AR
);
1078 /* Process locked */
1081 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1083 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1088 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_RX
;
1090 /* Configure counters and size of the handle */
1091 hqspi
->RxXferCount
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
1092 hqspi
->RxXferSize
= READ_REG(hqspi
->Instance
->DLR
) + 1U;
1093 hqspi
->pRxBuffPtr
= pData
;
1095 /* Configure QSPI: CCR register with functional as indirect read */
1096 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1098 /* Start the transfer by re-writing the address in AR register */
1099 WRITE_REG(hqspi
->Instance
->AR
, addr_reg
);
1101 /* Clear interrupt */
1102 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TE
| QSPI_FLAG_TC
);
1104 /* Process unlocked */
1105 __HAL_UNLOCK(hqspi
);
1107 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
1108 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
| QSPI_IT_FT
| QSPI_IT_TC
);
1112 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1115 /* Process unlocked */
1116 __HAL_UNLOCK(hqspi
);
1123 /* Process unlocked */
1124 __HAL_UNLOCK(hqspi
);
1131 * @brief Sends an amount of data in non blocking mode with DMA.
1132 * @param hqspi: QSPI handle
1133 * @param pData: pointer to data buffer
1134 * @note This function is used only in Indirect Write Mode
1135 * @note If DMA peripheral access is configured as halfword, the number
1136 * of data and the fifo threshold should be aligned on halfword
1137 * @note If DMA peripheral access is configured as word, the number
1138 * of data and the fifo threshold should be aligned on word
1139 * @retval HAL status
1141 HAL_StatusTypeDef
HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
)
1143 HAL_StatusTypeDef status
= HAL_OK
;
1145 uint32_t data_size
= (READ_REG(hqspi
->Instance
->DLR
) + 1U);
1147 /* Process locked */
1150 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1152 /* Clear the error code */
1153 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1157 /* Configure counters of the handle */
1158 if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_BYTE
)
1160 hqspi
->TxXferCount
= data_size
;
1162 else if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_HALFWORD
)
1164 if (((data_size
% 2U) != 0U) || ((hqspi
->Init
.FifoThreshold
% 2U) != 0U))
1166 /* The number of data or the fifo threshold is not aligned on halfword
1167 => no transfer possible with DMA peripheral access configured as halfword */
1168 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1171 /* Process unlocked */
1172 __HAL_UNLOCK(hqspi
);
1176 hqspi
->TxXferCount
= (data_size
>> 1);
1179 else if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_WORD
)
1181 if (((data_size
% 4U) != 0U) || ((hqspi
->Init
.FifoThreshold
% 4U) != 0U))
1183 /* The number of data or the fifo threshold is not aligned on word
1184 => no transfer possible with DMA peripheral access configured as word */
1185 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1188 /* Process unlocked */
1189 __HAL_UNLOCK(hqspi
);
1193 hqspi
->TxXferCount
= (data_size
>> 2U);
1197 if (status
== HAL_OK
)
1200 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_TX
;
1202 /* Clear interrupt */
1203 __HAL_QSPI_CLEAR_FLAG(hqspi
, (QSPI_FLAG_TE
| QSPI_FLAG_TC
));
1205 /* Configure size and pointer of the handle */
1206 hqspi
->TxXferSize
= hqspi
->TxXferCount
;
1207 hqspi
->pTxBuffPtr
= pData
;
1209 /* Configure QSPI: CCR register with functional mode as indirect write */
1210 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
1212 /* Set the QSPI DMA transfer complete callback */
1213 hqspi
->hdma
->XferCpltCallback
= QSPI_DMATxCplt
;
1215 /* Set the QSPI DMA Half transfer complete callback */
1216 hqspi
->hdma
->XferHalfCpltCallback
= QSPI_DMATxHalfCplt
;
1218 /* Set the DMA error callback */
1219 hqspi
->hdma
->XferErrorCallback
= QSPI_DMAError
;
1221 /* Clear the DMA abort callback */
1222 hqspi
->hdma
->XferAbortCallback
= NULL
;
1224 #if defined (QSPI1_V2_1L)
1225 /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
1226 AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
1227 Change the following configuration of DMA peripheral
1228 - Enable peripheral increment
1229 - Disable memory increment
1230 - Set DMA direction as peripheral to memory mode */
1232 /* Enable peripheral increment mode of the DMA */
1233 hqspi
->hdma
->Init
.PeriphInc
= DMA_PINC_ENABLE
;
1235 /* Disable memory increment mode of the DMA */
1236 hqspi
->hdma
->Init
.MemInc
= DMA_MINC_DISABLE
;
1238 /* Update peripheral/memory increment mode bits */
1239 MODIFY_REG(hqspi
->hdma
->Instance
->CR
, (DMA_SxCR_MINC
| DMA_SxCR_PINC
), (hqspi
->hdma
->Init
.MemInc
| hqspi
->hdma
->Init
.PeriphInc
));
1241 /* Configure the direction of the DMA */
1242 hqspi
->hdma
->Init
.Direction
= DMA_PERIPH_TO_MEMORY
;
1244 /* Configure the direction of the DMA */
1245 hqspi
->hdma
->Init
.Direction
= DMA_MEMORY_TO_PERIPH
;
1246 #endif /* QSPI1_V2_1L */
1248 /* Update direction mode bit */
1249 MODIFY_REG(hqspi
->hdma
->Instance
->CR
, DMA_SxCR_DIR
, hqspi
->hdma
->Init
.Direction
);
1251 /* Enable the QSPI transmit DMA Channel */
1252 tmp
= (uint32_t*)&pData
;
1253 HAL_DMA_Start_IT(hqspi
->hdma
, *(uint32_t*)tmp
, (uint32_t)&hqspi
->Instance
->DR
, hqspi
->TxXferSize
);
1255 /* Process unlocked */
1256 __HAL_UNLOCK(hqspi
);
1258 /* Enable the QSPI transfer error Interrupt */
1259 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
);
1261 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1262 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
1267 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1271 /* Process unlocked */
1272 __HAL_UNLOCK(hqspi
);
1279 /* Process unlocked */
1280 __HAL_UNLOCK(hqspi
);
1287 * @brief Receives an amount of data in non blocking mode with DMA.
1288 * @param hqspi: QSPI handle
1289 * @param pData: pointer to data buffer.
1290 * @note This function is used only in Indirect Read Mode
1291 * @note If DMA peripheral access is configured as halfword, the number
1292 * of data and the fifo threshold should be aligned on halfword
1293 * @note If DMA peripheral access is configured as word, the number
1294 * of data and the fifo threshold should be aligned on word
1295 * @retval HAL status
1297 HAL_StatusTypeDef
HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef
*hqspi
, uint8_t *pData
)
1299 HAL_StatusTypeDef status
= HAL_OK
;
1301 uint32_t addr_reg
= READ_REG(hqspi
->Instance
->AR
);
1302 uint32_t data_size
= (READ_REG(hqspi
->Instance
->DLR
) + 1U);
1304 /* Process locked */
1307 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1309 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1313 /* Configure counters of the handle */
1314 if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_BYTE
)
1316 hqspi
->RxXferCount
= data_size
;
1318 else if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_HALFWORD
)
1320 if (((data_size
% 2U) != 0U) || ((hqspi
->Init
.FifoThreshold
% 2U) != 0U))
1322 /* The number of data or the fifo threshold is not aligned on halfword
1323 => no transfer possible with DMA peripheral access configured as halfword */
1324 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1327 /* Process unlocked */
1328 __HAL_UNLOCK(hqspi
);
1332 hqspi
->RxXferCount
= (data_size
>> 1U);
1335 else if (hqspi
->hdma
->Init
.PeriphDataAlignment
== DMA_PDATAALIGN_WORD
)
1337 if (((data_size
% 4U) != 0U) || ((hqspi
->Init
.FifoThreshold
% 4U) != 0U))
1339 /* The number of data or the fifo threshold is not aligned on word
1340 => no transfer possible with DMA peripheral access configured as word */
1341 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1344 /* Process unlocked */
1345 __HAL_UNLOCK(hqspi
);
1349 hqspi
->RxXferCount
= (data_size
>> 2U);
1353 if (status
== HAL_OK
)
1356 hqspi
->State
= HAL_QSPI_STATE_BUSY_INDIRECT_RX
;
1358 /* Clear interrupt */
1359 __HAL_QSPI_CLEAR_FLAG(hqspi
, (QSPI_FLAG_TE
| QSPI_FLAG_TC
));
1361 /* Configure size and pointer of the handle */
1362 hqspi
->RxXferSize
= hqspi
->RxXferCount
;
1363 hqspi
->pRxBuffPtr
= pData
;
1365 /* Set the QSPI DMA transfer complete callback */
1366 hqspi
->hdma
->XferCpltCallback
= QSPI_DMARxCplt
;
1368 /* Set the QSPI DMA Half transfer complete callback */
1369 hqspi
->hdma
->XferHalfCpltCallback
= QSPI_DMARxHalfCplt
;
1371 /* Set the DMA error callback */
1372 hqspi
->hdma
->XferErrorCallback
= QSPI_DMAError
;
1374 /* Clear the DMA abort callback */
1375 hqspi
->hdma
->XferAbortCallback
= NULL
;
1377 #if defined (QSPI1_V2_1L)
1378 /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
1379 AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
1380 Change the following configuration of DMA peripheral
1381 - Enable peripheral increment
1382 - Disable memory increment
1383 - Set DMA direction as memory to peripheral mode
1384 - 4 Extra words (32-bits) are added for read operation to guarantee
1385 the last data is transferred from DMA FIFO to RAM memory */
1387 /* Enable peripheral increment of the DMA */
1388 hqspi
->hdma
->Init
.PeriphInc
= DMA_PINC_ENABLE
;
1390 /* Disable memory increment of the DMA */
1391 hqspi
->hdma
->Init
.MemInc
= DMA_MINC_DISABLE
;
1393 /* Update peripheral/memory increment mode bits */
1394 MODIFY_REG(hqspi
->hdma
->Instance
->CR
, (DMA_SxCR_MINC
| DMA_SxCR_PINC
), (hqspi
->hdma
->Init
.MemInc
| hqspi
->hdma
->Init
.PeriphInc
));
1396 /* Configure the direction of the DMA */
1397 hqspi
->hdma
->Init
.Direction
= DMA_MEMORY_TO_PERIPH
;
1399 /* 4 Extra words (32-bits) are needed for read operation to guarantee
1400 the last data is transferred from DMA FIFO to RAM memory */
1401 WRITE_REG(hqspi
->Instance
->DLR
, (data_size
- 1U + 16U));
1403 /* Update direction mode bit */
1404 MODIFY_REG(hqspi
->hdma
->Instance
->CR
, DMA_SxCR_DIR
, hqspi
->hdma
->Init
.Direction
);
1406 /* Configure QSPI: CCR register with functional as indirect read */
1407 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1409 /* Start the transfer by re-writing the address in AR register */
1410 WRITE_REG(hqspi
->Instance
->AR
, addr_reg
);
1412 /* Enable the DMA Channel */
1413 tmp
= (uint32_t*)&pData
;
1414 HAL_DMA_Start_IT(hqspi
->hdma
, (uint32_t)&hqspi
->Instance
->DR
, *(uint32_t*)tmp
, hqspi
->RxXferSize
);
1416 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1417 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
1419 /* Process unlocked */
1420 __HAL_UNLOCK(hqspi
);
1422 /* Enable the QSPI transfer error Interrupt */
1423 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
);
1425 /* Configure the direction of the DMA */
1426 hqspi
->hdma
->Init
.Direction
= DMA_PERIPH_TO_MEMORY
;
1428 MODIFY_REG(hqspi
->hdma
->Instance
->CR
, DMA_SxCR_DIR
, hqspi
->hdma
->Init
.Direction
);
1430 /* Enable the DMA Channel */
1431 tmp
= (uint32_t*)&pData
;
1432 HAL_DMA_Start_IT(hqspi
->hdma
, (uint32_t)&hqspi
->Instance
->DR
, *(uint32_t*)tmp
, hqspi
->RxXferSize
);
1434 /* Configure QSPI: CCR register with functional as indirect read */
1435 MODIFY_REG(hqspi
->Instance
->CCR
, QUADSPI_CCR_FMODE
, QSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1437 /* Start the transfer by re-writing the address in AR register */
1438 WRITE_REG(hqspi
->Instance
->AR
, addr_reg
);
1440 /* Process unlocked */
1441 __HAL_UNLOCK(hqspi
);
1443 /* Enable the QSPI transfer error Interrupt */
1444 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TE
);
1446 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
1447 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
1448 #endif /* QSPI1_V2_1L */
1453 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_INVALID_PARAM
;
1456 /* Process unlocked */
1457 __HAL_UNLOCK(hqspi
);
1464 /* Process unlocked */
1465 __HAL_UNLOCK(hqspi
);
1472 * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
1473 * @param hqspi: QSPI handle
1474 * @param cmd: structure that contains the command configuration information.
1475 * @param cfg: structure that contains the polling configuration information.
1476 * @param Timeout : Time out duration
1477 * @note This function is used only in Automatic Polling Mode
1478 * @retval HAL status
1480 HAL_StatusTypeDef
HAL_QSPI_AutoPolling(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, QSPI_AutoPollingTypeDef
*cfg
, uint32_t Timeout
)
1482 HAL_StatusTypeDef status
= HAL_ERROR
;
1483 uint32_t tickstart
= HAL_GetTick();
1485 /* Check the parameters */
1486 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
1487 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
1489 assert_param(IS_QSPI_INSTRUCTION(cmd
->Instruction
));
1492 assert_param(IS_QSPI_ADDRESS_MODE(cmd
->AddressMode
));
1493 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
1495 assert_param(IS_QSPI_ADDRESS_SIZE(cmd
->AddressSize
));
1498 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd
->AlternateByteMode
));
1499 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
1501 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd
->AlternateBytesSize
));
1504 assert_param(IS_QSPI_DUMMY_CYCLES(cmd
->DummyCycles
));
1505 assert_param(IS_QSPI_DATA_MODE(cmd
->DataMode
));
1507 assert_param(IS_QSPI_DDR_MODE(cmd
->DdrMode
));
1508 assert_param(IS_QSPI_DDR_HHC(cmd
->DdrHoldHalfCycle
));
1509 assert_param(IS_QSPI_SIOO_MODE(cmd
->SIOOMode
));
1511 assert_param(IS_QSPI_INTERVAL(cfg
->Interval
));
1512 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg
->StatusBytesSize
));
1513 assert_param(IS_QSPI_MATCH_MODE(cfg
->MatchMode
));
1515 /* Process locked */
1518 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1521 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1524 hqspi
->State
= HAL_QSPI_STATE_BUSY_AUTO_POLLING
;
1526 /* Wait till BUSY flag reset */
1527 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
1529 if (status
== HAL_OK
)
1531 /* Configure QSPI: PSMAR register with the status match value */
1532 WRITE_REG(hqspi
->Instance
->PSMAR
, cfg
->Match
);
1534 /* Configure QSPI: PSMKR register with the status mask value */
1535 WRITE_REG(hqspi
->Instance
->PSMKR
, cfg
->Mask
);
1537 /* Configure QSPI: PIR register with the interval value */
1538 WRITE_REG(hqspi
->Instance
->PIR
, cfg
->Interval
);
1540 /* Configure QSPI: CR register with Match mode and Automatic stop enabled
1541 (otherwise there will be an infinite loop in blocking mode) */
1542 MODIFY_REG(hqspi
->Instance
->CR
, (QUADSPI_CR_PMM
| QUADSPI_CR_APMS
),
1543 (cfg
->MatchMode
| QSPI_AUTOMATIC_STOP_ENABLE
));
1545 /* Call the configuration function */
1546 cmd
->NbData
= cfg
->StatusBytesSize
;
1547 QSPI_Config(hqspi
, cmd
, QSPI_FUNCTIONAL_MODE_AUTO_POLLING
);
1549 /* Wait until SM flag is set to go back in idle state */
1550 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_SM
, SET
, tickstart
, Timeout
);
1552 if (status
== HAL_OK
)
1554 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_SM
);
1557 hqspi
->State
= HAL_QSPI_STATE_READY
;
1565 /* Process unlocked */
1566 __HAL_UNLOCK(hqspi
);
1568 /* Return function status */
1573 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
1574 * @param hqspi: QSPI handle
1575 * @param cmd: structure that contains the command configuration information.
1576 * @param cfg: structure that contains the polling configuration information.
1577 * @note This function is used only in Automatic Polling Mode
1578 * @retval HAL status
1580 HAL_StatusTypeDef
HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, QSPI_AutoPollingTypeDef
*cfg
)
1582 __IO
uint32_t count
= 0U;
1583 HAL_StatusTypeDef status
= HAL_OK
;
1585 /* Check the parameters */
1586 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
1587 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
1589 assert_param(IS_QSPI_INSTRUCTION(cmd
->Instruction
));
1592 assert_param(IS_QSPI_ADDRESS_MODE(cmd
->AddressMode
));
1593 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
1595 assert_param(IS_QSPI_ADDRESS_SIZE(cmd
->AddressSize
));
1598 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd
->AlternateByteMode
));
1599 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
1601 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd
->AlternateBytesSize
));
1604 assert_param(IS_QSPI_DUMMY_CYCLES(cmd
->DummyCycles
));
1605 assert_param(IS_QSPI_DATA_MODE(cmd
->DataMode
));
1607 assert_param(IS_QSPI_DDR_MODE(cmd
->DdrMode
));
1608 assert_param(IS_QSPI_DDR_HHC(cmd
->DdrHoldHalfCycle
));
1609 assert_param(IS_QSPI_SIOO_MODE(cmd
->SIOOMode
));
1611 assert_param(IS_QSPI_INTERVAL(cfg
->Interval
));
1612 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg
->StatusBytesSize
));
1613 assert_param(IS_QSPI_MATCH_MODE(cfg
->MatchMode
));
1614 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg
->AutomaticStop
));
1616 /* Process locked */
1619 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1621 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1624 hqspi
->State
= HAL_QSPI_STATE_BUSY_AUTO_POLLING
;
1626 /* Wait till BUSY flag reset */
1627 count
= (hqspi
->Timeout
) * (SystemCoreClock
/ 16U / 1000U);
1632 hqspi
->State
= HAL_QSPI_STATE_ERROR
;
1633 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_TIMEOUT
;
1634 status
= HAL_TIMEOUT
;
1637 while ((__HAL_QSPI_GET_FLAG(hqspi
, QSPI_FLAG_BUSY
)) != RESET
);
1639 if (status
== HAL_OK
)
1641 /* Configure QSPI: PSMAR register with the status match value */
1642 WRITE_REG(hqspi
->Instance
->PSMAR
, cfg
->Match
);
1644 /* Configure QSPI: PSMKR register with the status mask value */
1645 WRITE_REG(hqspi
->Instance
->PSMKR
, cfg
->Mask
);
1647 /* Configure QSPI: PIR register with the interval value */
1648 WRITE_REG(hqspi
->Instance
->PIR
, cfg
->Interval
);
1650 /* Configure QSPI: CR register with Match mode and Automatic stop mode */
1651 MODIFY_REG(hqspi
->Instance
->CR
, (QUADSPI_CR_PMM
| QUADSPI_CR_APMS
),
1652 (cfg
->MatchMode
| cfg
->AutomaticStop
));
1654 /* Clear interrupt */
1655 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TE
| QSPI_FLAG_SM
);
1657 /* Call the configuration function */
1658 cmd
->NbData
= cfg
->StatusBytesSize
;
1659 QSPI_Config(hqspi
, cmd
, QSPI_FUNCTIONAL_MODE_AUTO_POLLING
);
1661 /* Process unlocked */
1662 __HAL_UNLOCK(hqspi
);
1664 /* Enable the QSPI Transfer Error and status match Interrupt */
1665 __HAL_QSPI_ENABLE_IT(hqspi
, (QSPI_IT_SM
| QSPI_IT_TE
));
1670 /* Process unlocked */
1671 __HAL_UNLOCK(hqspi
);
1678 /* Process unlocked */
1679 __HAL_UNLOCK(hqspi
);
1682 /* Return function status */
1687 * @brief Configure the Memory Mapped mode.
1688 * @param hqspi: QSPI handle
1689 * @param cmd: structure that contains the command configuration information.
1690 * @param cfg: structure that contains the memory mapped configuration information.
1691 * @note This function is used only in Memory mapped Mode
1692 * @retval HAL status
1694 HAL_StatusTypeDef
HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, QSPI_MemoryMappedTypeDef
*cfg
)
1696 HAL_StatusTypeDef status
= HAL_ERROR
;
1697 uint32_t tickstart
= HAL_GetTick();
1699 /* Check the parameters */
1700 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
1701 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
1703 assert_param(IS_QSPI_INSTRUCTION(cmd
->Instruction
));
1706 assert_param(IS_QSPI_ADDRESS_MODE(cmd
->AddressMode
));
1707 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
1709 assert_param(IS_QSPI_ADDRESS_SIZE(cmd
->AddressSize
));
1712 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd
->AlternateByteMode
));
1713 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
1715 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd
->AlternateBytesSize
));
1718 assert_param(IS_QSPI_DUMMY_CYCLES(cmd
->DummyCycles
));
1719 assert_param(IS_QSPI_DATA_MODE(cmd
->DataMode
));
1721 assert_param(IS_QSPI_DDR_MODE(cmd
->DdrMode
));
1722 assert_param(IS_QSPI_DDR_HHC(cmd
->DdrHoldHalfCycle
));
1723 assert_param(IS_QSPI_SIOO_MODE(cmd
->SIOOMode
));
1725 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg
->TimeOutActivation
));
1727 /* Process locked */
1730 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
1732 hqspi
->ErrorCode
= HAL_QSPI_ERROR_NONE
;
1735 hqspi
->State
= HAL_QSPI_STATE_BUSY_MEM_MAPPED
;
1737 /* Wait till BUSY flag reset */
1738 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_BUSY
, RESET
, tickstart
, hqspi
->Timeout
);
1740 if (status
== HAL_OK
)
1742 /* Configure QSPI: CR register with timeout counter enable */
1743 MODIFY_REG(hqspi
->Instance
->CR
, QUADSPI_CR_TCEN
, cfg
->TimeOutActivation
);
1745 if (cfg
->TimeOutActivation
== QSPI_TIMEOUT_COUNTER_ENABLE
)
1747 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg
->TimeOutPeriod
));
1749 /* Configure QSPI: LPTR register with the low-power timeout value */
1750 WRITE_REG(hqspi
->Instance
->LPTR
, cfg
->TimeOutPeriod
);
1752 /* Clear interrupt */
1753 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TO
);
1755 /* Enable the QSPI TimeOut Interrupt */
1756 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TO
);
1759 /* Call the configuration function */
1760 QSPI_Config(hqspi
, cmd
, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
);
1768 /* Process unlocked */
1769 __HAL_UNLOCK(hqspi
);
1771 /* Return function status */
1776 * @brief Transfer Error callbacks
1777 * @param hqspi: QSPI handle
1780 __weak
void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef
*hqspi
)
1782 /* Prevent unused argument(s) compilation warning */
1785 /* NOTE : This function Should not be modified, when the callback is needed,
1786 the HAL_QSPI_ErrorCallback could be implemented in the user file
1791 * @brief Abort completed callback.
1792 * @param hqspi: QSPI handle
1795 __weak
void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1797 /* Prevent unused argument(s) compilation warning */
1800 /* NOTE: This function should not be modified, when the callback is needed,
1801 the HAL_QSPI_AbortCpltCallback could be implemented in the user file
1806 * @brief Command completed callback.
1807 * @param hqspi: QSPI handle
1810 __weak
void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1812 /* Prevent unused argument(s) compilation warning */
1815 /* NOTE: This function Should not be modified, when the callback is needed,
1816 the HAL_QSPI_CmdCpltCallback could be implemented in the user file
1821 * @brief Rx Transfer completed callbacks.
1822 * @param hqspi: QSPI handle
1825 __weak
void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1827 /* Prevent unused argument(s) compilation warning */
1830 /* NOTE: This function Should not be modified, when the callback is needed,
1831 the HAL_QSPI_RxCpltCallback could be implemented in the user file
1836 * @brief Tx Transfer completed callbacks.
1837 * @param hqspi: QSPI handle
1840 __weak
void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1842 /* Prevent unused argument(s) compilation warning */
1845 /* NOTE: This function Should not be modified, when the callback is needed,
1846 the HAL_QSPI_TxCpltCallback could be implemented in the user file
1851 * @brief Rx Half Transfer completed callbacks.
1852 * @param hqspi: QSPI handle
1855 __weak
void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1857 /* Prevent unused argument(s) compilation warning */
1860 /* NOTE: This function Should not be modified, when the callback is needed,
1861 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
1866 * @brief Tx Half Transfer completed callbacks.
1867 * @param hqspi: QSPI handle
1870 __weak
void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef
*hqspi
)
1872 /* Prevent unused argument(s) compilation warning */
1875 /* NOTE: This function Should not be modified, when the callback is needed,
1876 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
1881 * @brief FIFO Threshold callbacks
1882 * @param hqspi: QSPI handle
1885 __weak
void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef
*hqspi
)
1887 /* Prevent unused argument(s) compilation warning */
1890 /* NOTE : This function Should not be modified, when the callback is needed,
1891 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
1896 * @brief Status Match callbacks
1897 * @param hqspi: QSPI handle
1900 __weak
void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef
*hqspi
)
1902 /* Prevent unused argument(s) compilation warning */
1905 /* NOTE : This function Should not be modified, when the callback is needed,
1906 the HAL_QSPI_StatusMatchCallback could be implemented in the user file
1911 * @brief Timeout callbacks
1912 * @param hqspi: QSPI handle
1915 __weak
void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef
*hqspi
)
1917 /* Prevent unused argument(s) compilation warning */
1920 /* NOTE : This function Should not be modified, when the callback is needed,
1921 the HAL_QSPI_TimeOutCallback could be implemented in the user file
1929 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
1930 * @brief QSPI control and State functions
1933 ===============================================================================
1934 ##### Peripheral Control and State functions #####
1935 ===============================================================================
1937 This subsection provides a set of functions allowing to :
1938 (+) Check in run-time the state of the driver.
1939 (+) Check the error code set during last operation.
1940 (+) Abort any operation.
1947 * @brief Return the QSPI handle state.
1948 * @param hqspi: QSPI handle
1951 HAL_QSPI_StateTypeDef
HAL_QSPI_GetState(QSPI_HandleTypeDef
*hqspi
)
1953 /* Return QSPI handle state */
1954 return hqspi
->State
;
1958 * @brief Return the QSPI error code
1959 * @param hqspi: QSPI handle
1960 * @retval QSPI Error Code
1962 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef
*hqspi
)
1964 return hqspi
->ErrorCode
;
1968 * @brief Abort the current transmission
1969 * @param hqspi: QSPI handle
1970 * @retval HAL status
1972 HAL_StatusTypeDef
HAL_QSPI_Abort(QSPI_HandleTypeDef
*hqspi
)
1974 HAL_StatusTypeDef status
= HAL_OK
;
1975 uint32_t tickstart
= HAL_GetTick();
1977 /* Check if the state is in one of the busy states */
1978 if ((hqspi
->State
& 0x2U
) != 0U)
1980 /* Process unlocked */
1981 __HAL_UNLOCK(hqspi
);
1983 if ((hqspi
->Instance
->CR
& QUADSPI_CR_DMAEN
)!= RESET
)
1985 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
1986 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
1988 /* Abort DMA channel */
1989 status
= HAL_DMA_Abort(hqspi
->hdma
);
1990 if(status
!= HAL_OK
)
1992 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_DMA
;
1996 /* Configure QSPI: CR register with Abort request */
1997 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_ABORT
);
1999 /* Wait until TC flag is set to go back in idle state */
2000 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_TC
, SET
, tickstart
, hqspi
->Timeout
);
2002 if(status
== HAL_OK
)
2004 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
2006 /* Wait until BUSY flag is reset */
2007 status
= QSPI_WaitFlagStateUntilTimeout(hqspi
, QSPI_FLAG_BUSY
, RESET
, tickstart
, hqspi
->Timeout
);
2010 if (status
== HAL_OK
)
2013 hqspi
->State
= HAL_QSPI_STATE_READY
;
2021 * @brief Abort the current transmission (non-blocking function)
2022 * @param hqspi: QSPI handle
2023 * @retval HAL status
2025 HAL_StatusTypeDef
HAL_QSPI_Abort_IT(QSPI_HandleTypeDef
*hqspi
)
2027 HAL_StatusTypeDef status
= HAL_OK
;
2029 /* Check if the state is in one of the busy states */
2030 if ((hqspi
->State
& 0x2U
) != 0U)
2032 /* Process unlocked */
2033 __HAL_UNLOCK(hqspi
);
2035 /* Update QSPI state */
2036 hqspi
->State
= HAL_QSPI_STATE_ABORT
;
2038 /* Disable all interrupts */
2039 __HAL_QSPI_DISABLE_IT(hqspi
, (QSPI_IT_TO
| QSPI_IT_SM
| QSPI_IT_FT
| QSPI_IT_TC
| QSPI_IT_TE
));
2041 if ((hqspi
->Instance
->CR
& QUADSPI_CR_DMAEN
)!= RESET
)
2043 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2044 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
2046 /* Abort DMA channel */
2047 hqspi
->hdma
->XferAbortCallback
= QSPI_DMAAbortCplt
;
2048 HAL_DMA_Abort_IT(hqspi
->hdma
);
2052 /* Clear interrupt */
2053 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
2055 /* Enable the QSPI Transfer Complete Interrupt */
2056 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TC
);
2058 /* Configure QSPI: CR register with Abort request */
2059 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_ABORT
);
2066 /** @brief Set QSPI timeout
2067 * @param hqspi: QSPI handle.
2068 * @param Timeout: Timeout for the QSPI memory access.
2071 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef
*hqspi
, uint32_t Timeout
)
2073 hqspi
->Timeout
= Timeout
;
2076 /** @brief Set QSPI Fifo threshold.
2077 * @param hqspi: QSPI handle.
2078 * @param Threshold: Threshold of the Fifo (value between 1 and 16).
2079 * @retval HAL status
2081 HAL_StatusTypeDef
HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef
*hqspi
, uint32_t Threshold
)
2083 HAL_StatusTypeDef status
= HAL_OK
;
2085 /* Process locked */
2088 if(hqspi
->State
== HAL_QSPI_STATE_READY
)
2090 /* Synchronize init structure with new FIFO threshold value */
2091 hqspi
->Init
.FifoThreshold
= Threshold
;
2093 /* Configure QSPI FIFO Threshold */
2094 MODIFY_REG(hqspi
->Instance
->CR
, QUADSPI_CR_FTHRES
,
2095 ((hqspi
->Init
.FifoThreshold
- 1U) << POSITION_VAL(QUADSPI_CR_FTHRES
)));
2102 /* Process unlocked */
2103 __HAL_UNLOCK(hqspi
);
2105 /* Return function status */
2109 /** @brief Get QSPI Fifo threshold.
2110 * @param hqspi: QSPI handle.
2111 * @retval Fifo threshold (value between 1 and 16)
2113 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef
*hqspi
)
2115 return ((READ_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_FTHRES
) >> POSITION_VAL(QUADSPI_CR_FTHRES
)) + 1U);
2122 /* Private functions ---------------------------------------------------------*/
2125 * @brief DMA QSPI receive process complete callback.
2126 * @param hdma: DMA handle
2129 static void QSPI_DMARxCplt(DMA_HandleTypeDef
*hdma
)
2131 QSPI_HandleTypeDef
* hqspi
= ( QSPI_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
2132 hqspi
->RxXferCount
= 0U;
2134 /* Enable the QSPI transfer complete Interrupt */
2135 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TC
);
2139 * @brief DMA QSPI transmit process complete callback.
2140 * @param hdma: DMA handle
2143 static void QSPI_DMATxCplt(DMA_HandleTypeDef
*hdma
)
2145 QSPI_HandleTypeDef
* hqspi
= ( QSPI_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
2146 hqspi
->TxXferCount
= 0U;
2148 /* Enable the QSPI transfer complete Interrupt */
2149 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TC
);
2153 * @brief DMA QSPI receive process half complete callback
2154 * @param hdma : DMA handle
2157 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
2159 QSPI_HandleTypeDef
* hqspi
= (QSPI_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
2161 HAL_QSPI_RxHalfCpltCallback(hqspi
);
2165 * @brief DMA QSPI transmit process half complete callback
2166 * @param hdma : DMA handle
2169 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
2171 QSPI_HandleTypeDef
* hqspi
= (QSPI_HandleTypeDef
*)((DMA_HandleTypeDef
*)hdma
)->Parent
;
2173 HAL_QSPI_TxHalfCpltCallback(hqspi
);
2177 * @brief DMA QSPI communication error callback.
2178 * @param hdma: DMA handle
2181 static void QSPI_DMAError(DMA_HandleTypeDef
*hdma
)
2183 QSPI_HandleTypeDef
* hqspi
= ( QSPI_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
2185 /* if DMA error is FIFO error ignore it */
2186 if(HAL_DMA_GetError(hdma
) != HAL_DMA_ERROR_FE
)
2188 hqspi
->RxXferCount
= 0U;
2189 hqspi
->TxXferCount
= 0U;
2190 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_DMA
;
2192 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
2193 CLEAR_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_DMAEN
);
2195 /* Abort the QSPI */
2196 HAL_QSPI_Abort_IT(hqspi
);
2201 * @brief DMA QSPI abort complete callback.
2202 * @param hdma: DMA handle
2205 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef
*hdma
)
2207 QSPI_HandleTypeDef
* hqspi
= ( QSPI_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
2209 hqspi
->RxXferCount
= 0U;
2210 hqspi
->TxXferCount
= 0U;
2212 if(hqspi
->State
== HAL_QSPI_STATE_ABORT
)
2214 /* DMA Abort called by QSPI abort */
2215 /* Clear interrupt */
2216 __HAL_QSPI_CLEAR_FLAG(hqspi
, QSPI_FLAG_TC
);
2218 /* Enable the QSPI Transfer Complete Interrupt */
2219 __HAL_QSPI_ENABLE_IT(hqspi
, QSPI_IT_TC
);
2221 /* Configure QSPI: CR register with Abort request */
2222 SET_BIT(hqspi
->Instance
->CR
, QUADSPI_CR_ABORT
);
2226 /* DMA Abort called due to a transfer error interrupt */
2227 /* Change state of QSPI */
2228 hqspi
->State
= HAL_QSPI_STATE_READY
;
2230 /* Error callback */
2231 HAL_QSPI_ErrorCallback(hqspi
);
2235 * @brief Wait for a flag state until timeout.
2236 * @param hqspi: QSPI handle
2237 * @param Flag: Flag checked
2238 * @param State: Value of the flag expected
2239 * @param Timeout: Duration of the time out
2240 * @param tickstart: tick start value
2241 * @retval HAL status
2243 static HAL_StatusTypeDef
QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef
*hqspi
, uint32_t Flag
,
2244 FlagStatus State
, uint32_t tickstart
, uint32_t Timeout
)
2246 /* Wait until flag is in expected state */
2247 while((FlagStatus
)(__HAL_QSPI_GET_FLAG(hqspi
, Flag
)) != State
)
2249 /* Check for the Timeout */
2250 if (Timeout
!= HAL_MAX_DELAY
)
2252 if((Timeout
== 0U) || ((HAL_GetTick() - tickstart
) > Timeout
))
2254 hqspi
->State
= HAL_QSPI_STATE_ERROR
;
2255 hqspi
->ErrorCode
|= HAL_QSPI_ERROR_TIMEOUT
;
2265 * @brief Configure the communication registers.
2266 * @param hqspi: QSPI handle
2267 * @param cmd: structure that contains the command configuration information
2268 * @param FunctionalMode: functional mode to configured
2269 * This parameter can be one of the following values:
2270 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
2271 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
2272 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
2273 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
2276 static void QSPI_Config(QSPI_HandleTypeDef
*hqspi
, QSPI_CommandTypeDef
*cmd
, uint32_t FunctionalMode
)
2278 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode
));
2280 if ((cmd
->DataMode
!= QSPI_DATA_NONE
) && (FunctionalMode
!= QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
))
2282 /* Configure QSPI: DLR register with the number of data to read or write */
2283 WRITE_REG(hqspi
->Instance
->DLR
, (cmd
->NbData
- 1U));
2286 if (cmd
->InstructionMode
!= QSPI_INSTRUCTION_NONE
)
2288 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
2290 /* Configure QSPI: ABR register with alternate bytes value */
2291 WRITE_REG(hqspi
->Instance
->ABR
, cmd
->AlternateBytes
);
2293 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
2295 /*---- Command with instruction, address and alternate bytes ----*/
2296 /* Configure QSPI: CCR register with all communications parameters */
2297 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2298 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateBytesSize
|
2299 cmd
->AlternateByteMode
| cmd
->AddressSize
| cmd
->AddressMode
|
2300 cmd
->InstructionMode
| cmd
->Instruction
| FunctionalMode
));
2302 if (FunctionalMode
!= QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
)
2304 /* Configure QSPI: AR register with address value */
2305 WRITE_REG(hqspi
->Instance
->AR
, cmd
->Address
);
2310 /*---- Command with instruction and alternate bytes ----*/
2311 /* Configure QSPI: CCR register with all communications parameters */
2312 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2313 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateBytesSize
|
2314 cmd
->AlternateByteMode
| cmd
->AddressMode
| cmd
->InstructionMode
|
2315 cmd
->Instruction
| FunctionalMode
));
2320 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
2322 /*---- Command with instruction and address ----*/
2323 /* Configure QSPI: CCR register with all communications parameters */
2324 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2325 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateByteMode
|
2326 cmd
->AddressSize
| cmd
->AddressMode
| cmd
->InstructionMode
|
2327 cmd
->Instruction
| FunctionalMode
));
2329 if (FunctionalMode
!= QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
)
2331 /* Configure QSPI: AR register with address value */
2332 WRITE_REG(hqspi
->Instance
->AR
, cmd
->Address
);
2337 /*---- Command with only instruction ----*/
2338 /* Configure QSPI: CCR register with all communications parameters */
2339 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2340 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateByteMode
|
2341 cmd
->AddressMode
| cmd
->InstructionMode
| cmd
->Instruction
|
2348 if (cmd
->AlternateByteMode
!= QSPI_ALTERNATE_BYTES_NONE
)
2350 /* Configure QSPI: ABR register with alternate bytes value */
2351 WRITE_REG(hqspi
->Instance
->ABR
, cmd
->AlternateBytes
);
2353 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
2355 /*---- Command with address and alternate bytes ----*/
2356 /* Configure QSPI: CCR register with all communications parameters */
2357 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2358 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateBytesSize
|
2359 cmd
->AlternateByteMode
| cmd
->AddressSize
| cmd
->AddressMode
|
2360 cmd
->InstructionMode
| FunctionalMode
));
2362 if (FunctionalMode
!= QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
)
2364 /* Configure QSPI: AR register with address value */
2365 WRITE_REG(hqspi
->Instance
->AR
, cmd
->Address
);
2370 /*---- Command with only alternate bytes ----*/
2371 /* Configure QSPI: CCR register with all communications parameters */
2372 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2373 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateBytesSize
|
2374 cmd
->AlternateByteMode
| cmd
->AddressMode
| cmd
->InstructionMode
|
2380 if (cmd
->AddressMode
!= QSPI_ADDRESS_NONE
)
2382 /*---- Command with only address ----*/
2383 /* Configure QSPI: CCR register with all communications parameters */
2384 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2385 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateByteMode
|
2386 cmd
->AddressSize
| cmd
->AddressMode
| cmd
->InstructionMode
|
2389 if (FunctionalMode
!= QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
)
2391 /* Configure QSPI: AR register with address value */
2392 WRITE_REG(hqspi
->Instance
->AR
, cmd
->Address
);
2397 /*---- Command with only data phase ----*/
2398 if (cmd
->DataMode
!= QSPI_DATA_NONE
)
2400 /* Configure QSPI: CCR register with all communications parameters */
2401 WRITE_REG(hqspi
->Instance
->CCR
, (cmd
->DdrMode
| cmd
->DdrHoldHalfCycle
| cmd
->SIOOMode
|
2402 cmd
->DataMode
| (cmd
->DummyCycles
<< 18U) | cmd
->AlternateByteMode
|
2403 cmd
->AddressMode
| cmd
->InstructionMode
| FunctionalMode
));
2412 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx
2413 STM32F413xx || STM32F423xx */
2415 #endif /* HAL_QSPI_MODULE_ENABLED */
2424 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/