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