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