Merge pull request #11270 from haslinghuis/rename_attr
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal_qspi.c
blob05f5f8ffd3a22932ba56d7b609ecda65fc6cff5e
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_qspi.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
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
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.
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.
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.
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.
112 *** Errors management and abort functionality ***
113 ==================================================
114 [..]
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
117 flushes the fifo :
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 =========================
125 [..]
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 ====================================================
133 [..]
134 (#) Workarounds Implemented inside HAL Driver
135 (++) Extra data written in the FIFO at the end of a read transfer
137 @endverbatim
138 ******************************************************************************
139 * @attention
141 * <h2><center>&copy; 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
172 * @{
175 /** @defgroup QSPI QSPI
176 * @brief QSPI HAL module driver
177 * @{
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
187 * @{
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*/
194 * @}
197 /* Private macro -------------------------------------------------------------*/
198 /** @addtogroup QSPI_Private_Macros QSPI Private Macros
199 * @{
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))
206 * @}
209 /* Private variables ---------------------------------------------------------*/
210 /* Private function prototypes -----------------------------------------------*/
211 /** @addtogroup QSPI_Private_Functions QSPI Private Functions
212 * @{
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);
223 * @}
226 /* Exported functions ---------------------------------------------------------*/
228 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
229 * @{
232 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
233 * @brief Initialization and Configuration functions
235 @verbatim
236 ===============================================================================
237 ##### Initialization and Configuration functions #####
238 ===============================================================================
239 [..]
240 This subsection provides a set of functions allowing to :
241 (+) Initialize the QuadSPI.
242 (+) De-initialize the QuadSPI.
244 @endverbatim
245 * @{
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
252 * @retval HAL status
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 */
260 if(hqspi == NULL)
262 return HAL_ERROR;
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));
280 /* Process locked */
281 __HAL_LOCK(hqspi);
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);
301 if(status == HAL_OK)
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;
321 /* Release Lock */
322 __HAL_UNLOCK(hqspi);
324 /* Return function status */
325 return status;
329 * @brief DeInitializes the QSPI peripheral
330 * @param hqspi: qspi handle
331 * @retval HAL status
333 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
335 /* Check the QSPI handle allocation */
336 if(hqspi == NULL)
338 return HAL_ERROR;
341 /* Process locked */
342 __HAL_LOCK(hqspi);
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;
356 /* Release Lock */
357 __HAL_UNLOCK(hqspi);
359 return HAL_OK;
363 * @brief QSPI MSP Init
364 * @param hqspi: QSPI handle
365 * @retval None
367 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
369 /* Prevent unused argument(s) compilation warning */
370 UNUSED(hqspi);
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
380 * @retval None
382 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
384 /* Prevent unused argument(s) compilation warning */
385 UNUSED(hqspi);
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
393 * @}
396 /** @defgroup QSPI_Exported_Functions_Group2 IO operation functions
397 * @brief QSPI Transmit/Receive functions
399 @verbatim
400 ===============================================================================
401 ##### IO operation functions #####
402 ===============================================================================
403 [..]
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.
412 @endverbatim
413 * @{
417 * @brief This function handles QSPI interrupt request.
418 * @param hqspi: QSPI handle
419 * @retval None.
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--;
443 else
445 /* No more data available for the transfer */
446 /* Disable the QSPI FIFO Threshold Interrupt */
447 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
448 break;
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--;
463 else
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);
468 break;
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);
498 /* Clear Busy bit */
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);
517 else
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--;
528 else
530 /* All data have been received for the transfer */
531 break;
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);
564 else
566 /* Abort due to an error (eg : DMA error) */
568 /* Error callback */
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);
603 /* Set error code */
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);
615 else
617 /* Change state of QSPI */
618 hqspi->State = HAL_QSPI_STATE_READY;
620 /* Error callback */
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
642 * @retval HAL status
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));
675 /* Process locked */
676 __HAL_LOCK(hqspi);
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;
708 else
710 /* Update QSPI state */
711 hqspi->State = HAL_QSPI_STATE_READY;
715 else
717 status = HAL_BUSY;
720 /* Process unlocked */
721 __HAL_UNLOCK(hqspi);
723 /* Return function status */
724 return 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
732 * @retval HAL status
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));
765 /* Process locked */
766 __HAL_LOCK(hqspi);
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);
779 if (count-- == 0U)
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 */
804 __HAL_UNLOCK(hqspi);
806 /* Enable the QSPI Transfer Error Interrupt */
807 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
809 else
811 /* Update QSPI state */
812 hqspi->State = HAL_QSPI_STATE_READY;
814 /* Process unlocked */
815 __HAL_UNLOCK(hqspi);
818 else
820 /* Process unlocked */
821 __HAL_UNLOCK(hqspi);
824 else
826 status = HAL_BUSY;
828 /* Process unlocked */
829 __HAL_UNLOCK(hqspi);
832 /* Return function status */
833 return 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
842 * @retval HAL status
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;
850 /* Process locked */
851 __HAL_LOCK(hqspi);
853 if(hqspi->State == HAL_QSPI_STATE_READY)
855 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
857 if(pData != NULL )
859 /* Update state */
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)
877 break;
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);
894 /* Clear Busy bit */
895 status = HAL_QSPI_Abort(hqspi);
899 /* Update QSPI state */
900 hqspi->State = HAL_QSPI_STATE_READY;
902 else
904 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
905 status = HAL_ERROR;
908 else
910 status = HAL_BUSY;
913 /* Process unlocked */
914 __HAL_UNLOCK(hqspi);
916 return status;
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
926 * @retval HAL status
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;
935 /* Process locked */
936 __HAL_LOCK(hqspi);
938 if(hqspi->State == HAL_QSPI_STATE_READY)
940 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
941 if(pData != NULL )
943 /* Update state */
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)
964 break;
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;
989 else
991 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
992 status = HAL_ERROR;
995 else
997 status = HAL_BUSY;
1000 /* Process unlocked */
1001 __HAL_UNLOCK(hqspi);
1003 return status;
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 */
1018 __HAL_LOCK(hqspi);
1020 if(hqspi->State == HAL_QSPI_STATE_READY)
1022 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1023 if(pData != NULL )
1025 /* Update state */
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);
1046 else
1048 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1049 status = HAL_ERROR;
1051 /* Process unlocked */
1052 __HAL_UNLOCK(hqspi);
1055 else
1057 status = HAL_BUSY;
1059 /* Process unlocked */
1060 __HAL_UNLOCK(hqspi);
1063 return status;
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 */
1079 __HAL_LOCK(hqspi);
1081 if(hqspi->State == HAL_QSPI_STATE_READY)
1083 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1085 if(pData != NULL )
1087 /* Update state */
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);
1110 else
1112 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1113 status = HAL_ERROR;
1115 /* Process unlocked */
1116 __HAL_UNLOCK(hqspi);
1119 else
1121 status = HAL_BUSY;
1123 /* Process unlocked */
1124 __HAL_UNLOCK(hqspi);
1127 return status;
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;
1144 uint32_t *tmp;
1145 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1147 /* Process locked */
1148 __HAL_LOCK(hqspi);
1150 if(hqspi->State == HAL_QSPI_STATE_READY)
1152 /* Clear the error code */
1153 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1155 if(pData != NULL )
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;
1169 status = HAL_ERROR;
1171 /* Process unlocked */
1172 __HAL_UNLOCK(hqspi);
1174 else
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;
1186 status = HAL_ERROR;
1188 /* Process unlocked */
1189 __HAL_UNLOCK(hqspi);
1191 else
1193 hqspi->TxXferCount = (data_size >> 2U);
1197 if (status == HAL_OK)
1199 /* Update state */
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;
1243 #else
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);
1265 else
1267 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1269 status = HAL_ERROR;
1271 /* Process unlocked */
1272 __HAL_UNLOCK(hqspi);
1275 else
1277 status = HAL_BUSY;
1279 /* Process unlocked */
1280 __HAL_UNLOCK(hqspi);
1283 return status;
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;
1300 uint32_t *tmp;
1301 uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
1302 uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
1304 /* Process locked */
1305 __HAL_LOCK(hqspi);
1307 if(hqspi->State == HAL_QSPI_STATE_READY)
1309 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1311 if(pData != NULL )
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;
1325 status = HAL_ERROR;
1327 /* Process unlocked */
1328 __HAL_UNLOCK(hqspi);
1330 else
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;
1342 status = HAL_ERROR;
1344 /* Process unlocked */
1345 __HAL_UNLOCK(hqspi);
1347 else
1349 hqspi->RxXferCount = (data_size >> 2U);
1353 if (status == HAL_OK)
1355 /* Update state */
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);
1424 #else
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 */
1451 else
1453 hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
1454 status = HAL_ERROR;
1456 /* Process unlocked */
1457 __HAL_UNLOCK(hqspi);
1460 else
1462 status = HAL_BUSY;
1464 /* Process unlocked */
1465 __HAL_UNLOCK(hqspi);
1468 return status;
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 */
1516 __HAL_LOCK(hqspi);
1518 if(hqspi->State == HAL_QSPI_STATE_READY)
1521 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1523 /* Update state */
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);
1556 /* Update state */
1557 hqspi->State = HAL_QSPI_STATE_READY;
1561 else
1563 status = HAL_BUSY;
1565 /* Process unlocked */
1566 __HAL_UNLOCK(hqspi);
1568 /* Return function status */
1569 return 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 */
1617 __HAL_LOCK(hqspi);
1619 if(hqspi->State == HAL_QSPI_STATE_READY)
1621 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1623 /* Update state */
1624 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
1626 /* Wait till BUSY flag reset */
1627 count = (hqspi->Timeout) * (SystemCoreClock / 16U / 1000U);
1630 if (count-- == 0U)
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));
1668 else
1670 /* Process unlocked */
1671 __HAL_UNLOCK(hqspi);
1674 else
1676 status = HAL_BUSY;
1678 /* Process unlocked */
1679 __HAL_UNLOCK(hqspi);
1682 /* Return function status */
1683 return 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 */
1728 __HAL_LOCK(hqspi);
1730 if(hqspi->State == HAL_QSPI_STATE_READY)
1732 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
1734 /* Update state */
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);
1763 else
1765 status = HAL_BUSY;
1768 /* Process unlocked */
1769 __HAL_UNLOCK(hqspi);
1771 /* Return function status */
1772 return status;
1776 * @brief Transfer Error callbacks
1777 * @param hqspi: QSPI handle
1778 * @retval None
1780 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
1782 /* Prevent unused argument(s) compilation warning */
1783 UNUSED(hqspi);
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
1793 * @retval None
1795 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
1797 /* Prevent unused argument(s) compilation warning */
1798 UNUSED(hqspi);
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
1808 * @retval None
1810 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
1812 /* Prevent unused argument(s) compilation warning */
1813 UNUSED(hqspi);
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
1823 * @retval None
1825 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
1827 /* Prevent unused argument(s) compilation warning */
1828 UNUSED(hqspi);
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
1838 * @retval None
1840 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
1842 /* Prevent unused argument(s) compilation warning */
1843 UNUSED(hqspi);
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
1853 * @retval None
1855 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1857 /* Prevent unused argument(s) compilation warning */
1858 UNUSED(hqspi);
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
1868 * @retval None
1870 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
1872 /* Prevent unused argument(s) compilation warning */
1873 UNUSED(hqspi);
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
1883 * @retval None
1885 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
1887 /* Prevent unused argument(s) compilation warning */
1888 UNUSED(hqspi);
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
1898 * @retval None
1900 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
1902 /* Prevent unused argument(s) compilation warning */
1903 UNUSED(hqspi);
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
1913 * @retval None
1915 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
1917 /* Prevent unused argument(s) compilation warning */
1918 UNUSED(hqspi);
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
1926 * @}
1929 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
1930 * @brief QSPI control and State functions
1932 @verbatim
1933 ===============================================================================
1934 ##### Peripheral Control and State functions #####
1935 ===============================================================================
1936 [..]
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.
1942 @endverbatim
1943 * @{
1947 * @brief Return the QSPI handle state.
1948 * @param hqspi: QSPI handle
1949 * @retval HAL state
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)
2012 /* Update state */
2013 hqspi->State = HAL_QSPI_STATE_READY;
2017 return status;
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);
2050 else
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);
2063 return status;
2066 /** @brief Set QSPI timeout
2067 * @param hqspi: QSPI handle.
2068 * @param Timeout: Timeout for the QSPI memory access.
2069 * @retval None
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 */
2086 __HAL_LOCK(hqspi);
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)));
2097 else
2099 status = HAL_BUSY;
2102 /* Process unlocked */
2103 __HAL_UNLOCK(hqspi);
2105 /* Return function status */
2106 return 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);
2119 * @}
2122 /* Private functions ---------------------------------------------------------*/
2125 * @brief DMA QSPI receive process complete callback.
2126 * @param hdma: DMA handle
2127 * @retval None
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
2141 * @retval None
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
2155 * @retval None
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
2167 * @retval None
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
2179 * @retval None
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
2203 * @retval None
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);
2224 else
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;
2257 return HAL_ERROR;
2261 return HAL_OK;
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
2274 * @retval None
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);
2308 else
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));
2318 else
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);
2335 else
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 |
2342 FunctionalMode));
2346 else
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);
2368 else
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 |
2375 FunctionalMode));
2378 else
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 |
2387 FunctionalMode));
2389 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
2391 /* Configure QSPI: AR register with address value */
2392 WRITE_REG(hqspi->Instance->AR, cmd->Address);
2395 else
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));
2410 * @}
2412 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx
2413 STM32F413xx || STM32F423xx */
2415 #endif /* HAL_QSPI_MODULE_ENABLED */
2417 * @}
2421 * @}
2424 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/