]> git.sur5r.net Git - freertos/blob
536d1632e23e74ea462a9e72f551d62cc0e31199
[freertos] /
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l4xx_hal_qspi.c\r
4   * @author  MCD Application Team\r
5   * @brief   QSPI HAL module driver.\r
6   *          This file provides firmware functions to manage the following\r
7   *          functionalities of the QuadSPI interface (QSPI).\r
8   *           + Initialization and de-initialization functions\r
9   *           + Indirect functional mode management\r
10   *           + Memory-mapped functional mode management\r
11   *           + Auto-polling functional mode management\r
12   *           + Interrupts and flags management\r
13   *           + DMA channel configuration for indirect functional mode\r
14   *           + Errors management and abort functionality\r
15   *\r
16   *\r
17   @verbatim\r
18  ===============================================================================\r
19                         ##### How to use this driver #####\r
20  ===============================================================================\r
21   [..]\r
22     *** Initialization ***\r
23     ======================\r
24     [..]\r
25       (#) As prerequisite, fill in the HAL_QSPI_MspInit() :\r
26         (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().\r
27         (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().\r
28         (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().\r
29         (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().\r
30         (++) If interrupt mode is used, enable and configure QuadSPI global\r
31             interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().\r
32         (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel\r
33             with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),\r
34             link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure\r
35             DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().\r
36       (#) Configure the flash size, the clock prescaler, the fifo threshold, the\r
37           clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.\r
38 \r
39     *** Indirect functional mode ***\r
40     ================================\r
41     [..]\r
42       (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()\r
43           functions :\r
44          (++) Instruction phase : the mode used and if present the instruction opcode.\r
45          (++) Address phase : the mode used and if present the size and the address value.\r
46          (++) Alternate-bytes phase : the mode used and if present the size and the alternate\r
47              bytes values.\r
48          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).\r
49          (++) Data phase : the mode used and if present the number of bytes.\r
50          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay\r
51              if activated.\r
52          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.\r
53       (#) If no data is required for the command, it is sent directly to the memory :\r
54          (++) In polling mode, the output of the function is done when the transfer is complete.\r
55          (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.\r
56       (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or\r
57           HAL_QSPI_Transmit_IT() after the command configuration :\r
58          (++) In polling mode, the output of the function is done when the transfer is complete.\r
59          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold\r
60              is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.\r
61          (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and\r
62              HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.\r
63       (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or\r
64           HAL_QSPI_Receive_IT() after the command configuration :\r
65          (++) In polling mode, the output of the function is done when the transfer is complete.\r
66          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold\r
67              is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.\r
68          (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and\r
69              HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.\r
70 \r
71     *** Auto-polling functional mode ***\r
72     ====================================\r
73     [..]\r
74       (#) Configure the command sequence and the auto-polling functional mode using the\r
75           HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :\r
76          (++) Instruction phase : the mode used and if present the instruction opcode.\r
77          (++) Address phase : the mode used and if present the size and the address value.\r
78          (++) Alternate-bytes phase : the mode used and if present the size and the alternate\r
79              bytes values.\r
80          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).\r
81          (++) Data phase : the mode used.\r
82          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay\r
83              if activated.\r
84          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.\r
85          (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),\r
86              the polling interval and the automatic stop activation.\r
87       (#) After the configuration :\r
88          (++) In polling mode, the output of the function is done when the status match is reached. The\r
89              automatic stop is activated to avoid an infinite loop.\r
90          (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.\r
91 \r
92     *** Memory-mapped functional mode ***\r
93     =====================================\r
94     [..]\r
95       (#) Configure the command sequence and the memory-mapped functional mode using the\r
96           HAL_QSPI_MemoryMapped() functions :\r
97          (++) Instruction phase : the mode used and if present the instruction opcode.\r
98          (++) Address phase : the mode used and the size.\r
99          (++) Alternate-bytes phase : the mode used and if present the size and the alternate\r
100              bytes values.\r
101          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).\r
102          (++) Data phase : the mode used.\r
103          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay\r
104              if activated.\r
105          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.\r
106          (++) The timeout activation and the timeout period.\r
107       (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on\r
108           the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.\r
109 \r
110     *** Errors management and abort functionality ***\r
111     =================================================\r
112     [..]\r
113       (#) HAL_QSPI_GetError() function gives the error raised during the last operation.\r
114       (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and\r
115           flushes the fifo :\r
116          (++) In polling mode, the output of the function is done when the transfer\r
117               complete bit is set and the busy bit cleared.\r
118          (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when\r
119               the transfer complete bit is set.\r
120 \r
121     *** Control functions ***\r
122     =========================\r
123     [..]\r
124       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.\r
125       (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.\r
126       (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.\r
127       (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold\r
128       (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.\r
129 \r
130     *** Callback registration ***\r
131     =============================================\r
132     [..]\r
133       The compilation define  USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1\r
134       allows the user to configure dynamically the driver callbacks.\r
135 \r
136       Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,\r
137       it allows to register following callbacks:\r
138         (+) ErrorCallback : callback when error occurs.\r
139         (+) AbortCpltCallback : callback when abort is completed.\r
140         (+) FifoThresholdCallback : callback when the fifo threshold is reached.\r
141         (+) CmdCpltCallback : callback when a command without data is completed.\r
142         (+) RxCpltCallback : callback when a reception transfer is completed.\r
143         (+) TxCpltCallback : callback when a transmission transfer is completed.\r
144         (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.\r
145         (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.\r
146         (+) StatusMatchCallback : callback when a status match occurs.\r
147         (+) TimeOutCallback : callback when the timeout perioed expires.\r
148         (+) MspInitCallback    : QSPI MspInit.\r
149         (+) MspDeInitCallback  : QSPI MspDeInit.\r
150       This function takes as parameters the HAL peripheral handle, the Callback ID\r
151       and a pointer to the user callback function.\r
152 \r
153       Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default\r
154       weak (surcharged) function. It allows to reset following callbacks:\r
155         (+) ErrorCallback : callback when error occurs.\r
156         (+) AbortCpltCallback : callback when abort is completed.\r
157         (+) FifoThresholdCallback : callback when the fifo threshold is reached.\r
158         (+) CmdCpltCallback : callback when a command without data is completed.\r
159         (+) RxCpltCallback : callback when a reception transfer is completed.\r
160         (+) TxCpltCallback : callback when a transmission transfer is completed.\r
161         (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.\r
162         (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.\r
163         (+) StatusMatchCallback : callback when a status match occurs.\r
164         (+) TimeOutCallback : callback when the timeout perioed expires.\r
165         (+) MspInitCallback    : QSPI MspInit.\r
166         (+) MspDeInitCallback  : QSPI MspDeInit.\r
167       This function) takes as parameters the HAL peripheral handle and the Callback ID.\r
168 \r
169       By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET\r
170       all callbacks are reset to the corresponding legacy weak (surcharged) functions.\r
171       Exception done for MspInit and MspDeInit callbacks that are respectively\r
172       reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init\r
173       and @ref  HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).\r
174       If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit\r
175       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)\r
176 \r
177       Callbacks can be registered/unregistered in READY state only.\r
178       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered\r
179       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used\r
180       during the Init/DeInit.\r
181       In that case first register the MspInit/MspDeInit user callbacks\r
182       using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit\r
183       or @ref HAL_QSPI_Init function.\r
184 \r
185       When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or\r
186       not defined, the callback registering feature is not available\r
187       and weak (surcharged) callbacks are used.\r
188 \r
189     *** Workarounds linked to Silicon Limitation ***\r
190     ====================================================\r
191     [..]\r
192       (#) Workarounds Implemented inside HAL Driver\r
193          (++) Extra data written in the FIFO at the end of a read transfer\r
194 \r
195   @endverbatim\r
196   ******************************************************************************\r
197   * @attention\r
198   *\r
199   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.\r
200   * All rights reserved.</center></h2>\r
201   *\r
202   * This software component is licensed by ST under BSD 3-Clause license,\r
203   * the "License"; You may not use this file except in compliance with the\r
204   * License. You may obtain a copy of the License at:\r
205   *                       opensource.org/licenses/BSD-3-Clause\r
206   *\r
207   ******************************************************************************\r
208   */\r
209 \r
210 /* Includes ------------------------------------------------------------------*/\r
211 #include "stm32l4xx_hal.h"\r
212 \r
213 #if defined(QUADSPI)\r
214 \r
215 /** @addtogroup STM32L4xx_HAL_Driver\r
216   * @{\r
217   */\r
218 \r
219 /** @defgroup QSPI QSPI\r
220   * @brief QSPI HAL module driver\r
221   * @{\r
222   */\r
223 #ifdef HAL_QSPI_MODULE_ENABLED\r
224 \r
225 /* Private typedef -----------------------------------------------------------*/\r
226 \r
227 /* Private define ------------------------------------------------------------*/\r
228 /** @defgroup QSPI_Private_Constants QSPI Private Constants\r
229   * @{\r
230   */\r
231 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U                     /*!<Indirect write mode*/\r
232 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/\r
233 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/\r
234 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/\r
235 /**\r
236   * @}\r
237   */\r
238 \r
239 /* Private macro -------------------------------------------------------------*/\r
240 /** @defgroup QSPI_Private_Macros QSPI Private Macros\r
241   * @{\r
242   */\r
243 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \\r
244                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \\r
245                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \\r
246                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))\r
247 /**\r
248   * @}\r
249   */\r
250 \r
251 /* Private variables ---------------------------------------------------------*/\r
252 \r
253 /* Private function prototypes -----------------------------------------------*/\r
254 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);\r
255 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);\r
256 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);\r
257 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);\r
258 static void QSPI_DMAError(DMA_HandleTypeDef *hdma);\r
259 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);\r
260 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);\r
261 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);\r
262 \r
263 /* Exported functions --------------------------------------------------------*/\r
264 \r
265 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions\r
266   * @{\r
267   */\r
268 \r
269 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions\r
270   *  @brief    Initialization and Configuration functions\r
271   *\r
272 @verbatim\r
273 ===============================================================================\r
274             ##### Initialization and Configuration functions #####\r
275  ===============================================================================\r
276     [..]\r
277     This subsection provides a set of functions allowing to :\r
278       (+) Initialize the QuadSPI.\r
279       (+) De-initialize the QuadSPI.\r
280 \r
281 @endverbatim\r
282   * @{\r
283   */\r
284 \r
285 /**\r
286   * @brief Initialize the QSPI mode according to the specified parameters\r
287   *        in the QSPI_InitTypeDef and initialize the associated handle.\r
288   * @param hqspi : QSPI handle\r
289   * @retval HAL status\r
290   */\r
291 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)\r
292 {\r
293   HAL_StatusTypeDef status;\r
294   uint32_t tickstart = HAL_GetTick();\r
295 \r
296   /* Check the QSPI handle allocation */\r
297   if(hqspi == NULL)\r
298   {\r
299     return HAL_ERROR;\r
300   }\r
301 \r
302   /* Check the parameters */\r
303   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));\r
304   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));\r
305   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));\r
306   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));\r
307   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));\r
308   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));\r
309   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));\r
310 #if defined(QUADSPI_CR_DFM)\r
311   assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));\r
312 \r
313   if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )\r
314   {\r
315     assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));\r
316   }\r
317 #endif\r
318 \r
319   /* Process locked */\r
320   __HAL_LOCK(hqspi);\r
321 \r
322   if(hqspi->State == HAL_QSPI_STATE_RESET)\r
323   {\r
324     /* Allocate lock resource and initialize it */\r
325     hqspi->Lock = HAL_UNLOCKED;\r
326 \r
327 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
328     /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */\r
329     hqspi->ErrorCallback         = HAL_QSPI_ErrorCallback;\r
330     hqspi->AbortCpltCallback     = HAL_QSPI_AbortCpltCallback;\r
331     hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;\r
332     hqspi->CmdCpltCallback       = HAL_QSPI_CmdCpltCallback;\r
333     hqspi->RxCpltCallback        = HAL_QSPI_RxCpltCallback;\r
334     hqspi->TxCpltCallback        = HAL_QSPI_TxCpltCallback;\r
335     hqspi->RxHalfCpltCallback    = HAL_QSPI_RxHalfCpltCallback;\r
336     hqspi->TxHalfCpltCallback    = HAL_QSPI_TxHalfCpltCallback;\r
337     hqspi->StatusMatchCallback   = HAL_QSPI_StatusMatchCallback;\r
338     hqspi->TimeOutCallback       = HAL_QSPI_TimeOutCallback;\r
339 \r
340     if(hqspi->MspInitCallback == NULL)\r
341     {\r
342       hqspi->MspInitCallback = HAL_QSPI_MspInit;\r
343     }\r
344 \r
345     /* Init the low level hardware */\r
346     hqspi->MspInitCallback(hqspi);\r
347 #else\r
348     /* Init the low level hardware : GPIO, CLOCK */\r
349     HAL_QSPI_MspInit(hqspi);\r
350 #endif\r
351 \r
352     /* Configure the default timeout for the QSPI memory access */\r
353     HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);\r
354   }\r
355 \r
356   /* Configure QSPI FIFO Threshold */\r
357   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,\r
358              ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));\r
359 \r
360   /* Wait till BUSY flag reset */\r
361   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);\r
362 \r
363   if(status == HAL_OK)\r
364   {\r
365     /* Configure QSPI Clock Prescaler and Sample Shift */\r
366 #if defined(QUADSPI_CR_DFM)\r
367     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),\r
368                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |\r
369                 hqspi->Init.SampleShifting  | hqspi->Init.FlashID | hqspi->Init.DualFlash));\r
370 #else\r
371     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT),\r
372                ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |\r
373                 hqspi->Init.SampleShifting));\r
374 #endif\r
375 \r
376     /* Configure QSPI Flash Size, CS High Time and Clock Mode */\r
377     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),\r
378                ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |\r
379                 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));\r
380 \r
381     /* Enable the QSPI peripheral */\r
382     __HAL_QSPI_ENABLE(hqspi);\r
383 \r
384     /* Set QSPI error code to none */\r
385     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
386 \r
387     /* Initialize the QSPI state */\r
388     hqspi->State = HAL_QSPI_STATE_READY;\r
389   }\r
390 \r
391   /* Release Lock */\r
392   __HAL_UNLOCK(hqspi);\r
393 \r
394   /* Return function status */\r
395   return status;\r
396 }\r
397 \r
398 /**\r
399   * @brief De-Initialize the QSPI peripheral.\r
400   * @param hqspi : QSPI handle\r
401   * @retval HAL status\r
402   */\r
403 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)\r
404 {\r
405   /* Check the QSPI handle allocation */\r
406   if(hqspi == NULL)\r
407   {\r
408     return HAL_ERROR;\r
409   }\r
410 \r
411   /* Process locked */\r
412   __HAL_LOCK(hqspi);\r
413 \r
414   /* Disable the QSPI Peripheral Clock */\r
415   __HAL_QSPI_DISABLE(hqspi);\r
416 \r
417 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
418   if(hqspi->MspDeInitCallback == NULL)\r
419   {\r
420     hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;\r
421   }\r
422 \r
423   /* DeInit the low level hardware */\r
424   hqspi->MspDeInitCallback(hqspi);\r
425 #else\r
426   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */\r
427   HAL_QSPI_MspDeInit(hqspi);\r
428 #endif\r
429 \r
430   /* Set QSPI error code to none */\r
431   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
432 \r
433   /* Initialize the QSPI state */\r
434   hqspi->State = HAL_QSPI_STATE_RESET;\r
435 \r
436   /* Release Lock */\r
437   __HAL_UNLOCK(hqspi);\r
438 \r
439   return HAL_OK;\r
440 }\r
441 \r
442 /**\r
443   * @brief Initialize the QSPI MSP.\r
444   * @param hqspi : QSPI handle\r
445   * @retval None\r
446   */\r
447 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)\r
448 {\r
449   /* Prevent unused argument(s) compilation warning */\r
450   UNUSED(hqspi);\r
451 \r
452   /* NOTE : This function should not be modified, when the callback is needed,\r
453             the HAL_QSPI_MspInit can be implemented in the user file\r
454    */\r
455 }\r
456 \r
457 /**\r
458   * @brief DeInitialize the QSPI MSP.\r
459   * @param hqspi : QSPI handle\r
460   * @retval None\r
461   */\r
462 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)\r
463 {\r
464   /* Prevent unused argument(s) compilation warning */\r
465   UNUSED(hqspi);\r
466 \r
467   /* NOTE : This function should not be modified, when the callback is needed,\r
468             the HAL_QSPI_MspDeInit can be implemented in the user file\r
469    */\r
470 }\r
471 \r
472 /**\r
473   * @}\r
474   */\r
475 \r
476 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions\r
477   *  @brief QSPI Transmit/Receive functions\r
478   *\r
479 @verbatim\r
480  ===============================================================================\r
481                       ##### IO operation functions #####\r
482  ===============================================================================\r
483     [..]\r
484     This subsection provides a set of functions allowing to :\r
485       (+) Handle the interrupts.\r
486       (+) Handle the command sequence.\r
487       (+) Transmit data in blocking, interrupt or DMA mode.\r
488       (+) Receive data in blocking, interrupt or DMA mode.\r
489       (+) Manage the auto-polling functional mode.\r
490       (+) Manage the memory-mapped functional mode.\r
491 \r
492 @endverbatim\r
493   * @{\r
494   */\r
495 \r
496 /**\r
497   * @brief Handle QSPI interrupt request.\r
498   * @param hqspi : QSPI handle\r
499   * @retval None\r
500   */\r
501 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)\r
502 {\r
503   __IO uint32_t *data_reg;\r
504   uint32_t flag = READ_REG(hqspi->Instance->SR);\r
505   uint32_t itsource = READ_REG(hqspi->Instance->CR);\r
506 \r
507   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/\r
508   if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))\r
509   {\r
510     data_reg = &hqspi->Instance->DR;\r
511 \r
512     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)\r
513     {\r
514       /* Transmission process */\r
515       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)\r
516       {\r
517         if (hqspi->TxXferCount > 0U)\r
518         {\r
519           /* Fill the FIFO until the threshold is reached */\r
520           *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;\r
521           hqspi->pTxBuffPtr++;\r
522           hqspi->TxXferCount--;\r
523         }\r
524         else\r
525         {\r
526           /* No more data available for the transfer */\r
527           /* Disable the QSPI FIFO Threshold Interrupt */\r
528           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);\r
529           break;\r
530         }\r
531       }\r
532     }\r
533     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)\r
534     {\r
535       /* Receiving Process */\r
536       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)\r
537       {\r
538         if (hqspi->RxXferCount > 0U)\r
539         {\r
540           /* Read the FIFO until the threshold is reached */\r
541           *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);\r
542           hqspi->pRxBuffPtr++;\r
543           hqspi->RxXferCount--;\r
544         }\r
545         else\r
546         {\r
547           /* All data have been received for the transfer */\r
548           /* Disable the QSPI FIFO Threshold Interrupt */\r
549           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);\r
550           break;\r
551         }\r
552       }\r
553     }\r
554     else\r
555     {\r
556       /* Nothing to do */\r
557     }\r
558 \r
559     /* FIFO Threshold callback */\r
560 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
561     hqspi->FifoThresholdCallback(hqspi);\r
562 #else\r
563     HAL_QSPI_FifoThresholdCallback(hqspi);\r
564 #endif\r
565   }\r
566 \r
567   /* QSPI Transfer Complete interrupt occurred -------------------------------*/\r
568   else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))\r
569   {\r
570     /* Clear interrupt */\r
571     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);\r
572 \r
573     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */\r
574     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);\r
575 \r
576     /* Transfer complete callback */\r
577     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)\r
578     {\r
579       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)\r
580       {\r
581         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
582         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
583 \r
584         /* Disable the DMA channel */\r
585         __HAL_DMA_DISABLE(hqspi->hdma);\r
586       }\r
587 \r
588 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))\r
589       /* Clear Busy bit */\r
590       HAL_QSPI_Abort_IT(hqspi);\r
591 #endif\r
592 \r
593       /* Change state of QSPI */\r
594       hqspi->State = HAL_QSPI_STATE_READY;\r
595 \r
596       /* TX Complete callback */\r
597 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
598       hqspi->TxCpltCallback(hqspi);\r
599 #else\r
600       HAL_QSPI_TxCpltCallback(hqspi);\r
601 #endif\r
602     }\r
603     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)\r
604     {\r
605       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)\r
606       {\r
607         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
608         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
609 \r
610         /* Disable the DMA channel */\r
611         __HAL_DMA_DISABLE(hqspi->hdma);\r
612       }\r
613       else\r
614       {\r
615         data_reg = &hqspi->Instance->DR;\r
616         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)\r
617         {\r
618           if (hqspi->RxXferCount > 0U)\r
619           {\r
620             /* Read the last data received in the FIFO until it is empty */\r
621             *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);\r
622             hqspi->pRxBuffPtr++;\r
623             hqspi->RxXferCount--;\r
624           }\r
625           else\r
626           {\r
627             /* All data have been received for the transfer */\r
628             break;\r
629           }\r
630         }\r
631       }\r
632 \r
633 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))\r
634       /* Workaround - Extra data written in the FIFO at the end of a read transfer */\r
635       HAL_QSPI_Abort_IT(hqspi);\r
636 #endif\r
637 \r
638       /* Change state of QSPI */\r
639       hqspi->State = HAL_QSPI_STATE_READY;\r
640 \r
641       /* RX Complete callback */\r
642 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
643       hqspi->RxCpltCallback(hqspi);\r
644 #else\r
645       HAL_QSPI_RxCpltCallback(hqspi);\r
646 #endif\r
647     }\r
648     else if(hqspi->State == HAL_QSPI_STATE_BUSY)\r
649     {\r
650       /* Change state of QSPI */\r
651       hqspi->State = HAL_QSPI_STATE_READY;\r
652 \r
653       /* Command Complete callback */\r
654 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
655       hqspi->CmdCpltCallback(hqspi);\r
656 #else\r
657       HAL_QSPI_CmdCpltCallback(hqspi);\r
658 #endif\r
659     }\r
660     else if(hqspi->State == HAL_QSPI_STATE_ABORT)\r
661     {\r
662       /* Reset functional mode configuration to indirect write mode by default */\r
663       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);\r
664 \r
665       /* Change state of QSPI */\r
666       hqspi->State = HAL_QSPI_STATE_READY;\r
667 \r
668       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)\r
669       {\r
670         /* Abort called by the user */\r
671 \r
672         /* Abort Complete callback */\r
673 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
674         hqspi->AbortCpltCallback(hqspi);\r
675 #else\r
676         HAL_QSPI_AbortCpltCallback(hqspi);\r
677 #endif\r
678       }\r
679       else\r
680       {\r
681         /* Abort due to an error (eg :  DMA error) */\r
682 \r
683         /* Error callback */\r
684 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
685         hqspi->ErrorCallback(hqspi);\r
686 #else\r
687         HAL_QSPI_ErrorCallback(hqspi);\r
688 #endif\r
689       }\r
690     }\r
691     else\r
692     {\r
693      /* Nothing to do */\r
694     }\r
695   }\r
696 \r
697   /* QSPI Status Match interrupt occurred ------------------------------------*/\r
698   else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))\r
699   {\r
700     /* Clear interrupt */\r
701     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);\r
702 \r
703     /* Check if the automatic poll mode stop is activated */\r
704     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)\r
705     {\r
706       /* Disable the QSPI Transfer Error and Status Match Interrupts */\r
707       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));\r
708 \r
709       /* Change state of QSPI */\r
710       hqspi->State = HAL_QSPI_STATE_READY;\r
711     }\r
712 \r
713     /* Status match callback */\r
714 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
715     hqspi->StatusMatchCallback(hqspi);\r
716 #else\r
717     HAL_QSPI_StatusMatchCallback(hqspi);\r
718 #endif\r
719   }\r
720 \r
721   /* QSPI Transfer Error interrupt occurred ----------------------------------*/\r
722   else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))\r
723   {\r
724     /* Clear interrupt */\r
725     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);\r
726 \r
727     /* Disable all the QSPI Interrupts */\r
728     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);\r
729 \r
730     /* Set error code */\r
731     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;\r
732 \r
733     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)\r
734     {\r
735       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
736       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
737 \r
738       /* Disable the DMA channel */\r
739       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;\r
740       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)\r
741       {\r
742         /* Set error code to DMA */\r
743         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;\r
744 \r
745         /* Change state of QSPI */\r
746         hqspi->State = HAL_QSPI_STATE_READY;\r
747         \r
748         /* Error callback */\r
749 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
750         hqspi->ErrorCallback(hqspi);\r
751 #else\r
752         HAL_QSPI_ErrorCallback(hqspi);\r
753 #endif\r
754       }\r
755     }\r
756     else\r
757     {\r
758       /* Change state of QSPI */\r
759       hqspi->State = HAL_QSPI_STATE_READY;\r
760 \r
761       /* Error callback */\r
762 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
763       hqspi->ErrorCallback(hqspi);\r
764 #else\r
765       HAL_QSPI_ErrorCallback(hqspi);\r
766 #endif\r
767     }\r
768   }\r
769 \r
770   /* QSPI Timeout interrupt occurred -----------------------------------------*/\r
771   else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))\r
772   {\r
773     /* Clear interrupt */\r
774     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);\r
775 \r
776     /* Timeout callback */\r
777 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
778     hqspi->TimeOutCallback(hqspi);\r
779 #else\r
780     HAL_QSPI_TimeOutCallback(hqspi);\r
781 #endif\r
782   }\r
783 \r
784    else\r
785   {\r
786    /* Nothing to do */\r
787   }\r
788 }\r
789 \r
790 /**\r
791   * @brief Set the command configuration.\r
792   * @param hqspi : QSPI handle\r
793   * @param cmd : structure that contains the command configuration information\r
794   * @param Timeout : Timeout duration\r
795   * @note   This function is used only in Indirect Read or Write Modes\r
796   * @retval HAL status\r
797   */\r
798 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)\r
799 {\r
800   HAL_StatusTypeDef status;\r
801   uint32_t tickstart = HAL_GetTick();\r
802 \r
803   /* Check the parameters */\r
804   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));\r
805   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
806   {\r
807     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));\r
808   }\r
809 \r
810   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));\r
811   if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
812   {\r
813     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));\r
814   }\r
815 \r
816   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));\r
817   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
818   {\r
819     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));\r
820   }\r
821 \r
822   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));\r
823   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));\r
824 \r
825   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));\r
826   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));\r
827   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));\r
828 \r
829   /* Process locked */\r
830   __HAL_LOCK(hqspi);\r
831 \r
832   if(hqspi->State == HAL_QSPI_STATE_READY)\r
833   {\r
834     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
835 \r
836     /* Update QSPI state */\r
837     hqspi->State = HAL_QSPI_STATE_BUSY;\r
838 \r
839     /* Wait till BUSY flag reset */\r
840     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);\r
841 \r
842     if (status == HAL_OK)\r
843     {\r
844       /* Call the configuration function */\r
845       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);\r
846 \r
847       if (cmd->DataMode == QSPI_DATA_NONE)\r
848       {\r
849         /* When there is no data phase, the transfer start as soon as the configuration is done\r
850         so wait until TC flag is set to go back in idle state */\r
851         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);\r
852 \r
853         if (status == HAL_OK)\r
854         {\r
855           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
856 \r
857           /* Update QSPI state */\r
858           hqspi->State = HAL_QSPI_STATE_READY;\r
859         }\r
860       }\r
861       else\r
862       {\r
863         /* Update QSPI state */\r
864         hqspi->State = HAL_QSPI_STATE_READY;\r
865       }\r
866     }\r
867   }\r
868   else\r
869   {\r
870     status = HAL_BUSY;\r
871   }\r
872 \r
873   /* Process unlocked */\r
874   __HAL_UNLOCK(hqspi);\r
875 \r
876   /* Return function status */\r
877   return status;\r
878 }\r
879 \r
880 /**\r
881   * @brief Set the command configuration in interrupt mode.\r
882   * @param hqspi : QSPI handle\r
883   * @param cmd : structure that contains the command configuration information\r
884   * @note   This function is used only in Indirect Read or Write Modes\r
885   * @retval HAL status\r
886   */\r
887 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)\r
888 {\r
889   HAL_StatusTypeDef status;\r
890   uint32_t tickstart = HAL_GetTick();\r
891 \r
892   /* Check the parameters */\r
893   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));\r
894   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
895   {\r
896     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));\r
897   }\r
898 \r
899   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));\r
900   if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
901   {\r
902     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));\r
903   }\r
904 \r
905   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));\r
906   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
907   {\r
908     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));\r
909   }\r
910 \r
911   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));\r
912   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));\r
913 \r
914   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));\r
915   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));\r
916   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));\r
917 \r
918   /* Process locked */\r
919   __HAL_LOCK(hqspi);\r
920 \r
921   if(hqspi->State == HAL_QSPI_STATE_READY)\r
922   {\r
923     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
924 \r
925     /* Update QSPI state */\r
926     hqspi->State = HAL_QSPI_STATE_BUSY;\r
927 \r
928     /* Wait till BUSY flag reset */\r
929     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);\r
930 \r
931     if (status == HAL_OK)\r
932     {\r
933       if (cmd->DataMode == QSPI_DATA_NONE)\r
934       {\r
935         /* Clear interrupt */\r
936         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);\r
937       }\r
938 \r
939       /* Call the configuration function */\r
940       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);\r
941 \r
942       if (cmd->DataMode == QSPI_DATA_NONE)\r
943       {\r
944         /* When there is no data phase, the transfer start as soon as the configuration is done\r
945         so activate TC and TE interrupts */\r
946         /* Process unlocked */\r
947         __HAL_UNLOCK(hqspi);\r
948 \r
949         /* Enable the QSPI Transfer Error Interrupt */\r
950         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);\r
951       }\r
952       else\r
953       {\r
954         /* Update QSPI state */\r
955         hqspi->State = HAL_QSPI_STATE_READY;\r
956 \r
957         /* Process unlocked */\r
958         __HAL_UNLOCK(hqspi);\r
959       }\r
960     }\r
961     else\r
962     {\r
963       /* Process unlocked */\r
964       __HAL_UNLOCK(hqspi);\r
965     }\r
966   }\r
967   else\r
968   {\r
969     status = HAL_BUSY;\r
970 \r
971     /* Process unlocked */\r
972     __HAL_UNLOCK(hqspi);\r
973   }\r
974 \r
975   /* Return function status */\r
976   return status;\r
977 }\r
978 \r
979 /**\r
980   * @brief Transmit an amount of data in blocking mode.\r
981   * @param hqspi : QSPI handle\r
982   * @param pData : pointer to data buffer\r
983   * @param Timeout : Timeout duration\r
984   * @note   This function is used only in Indirect Write Mode\r
985   * @retval HAL status\r
986   */\r
987 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)\r
988 {\r
989   HAL_StatusTypeDef status = HAL_OK;\r
990   uint32_t tickstart = HAL_GetTick();\r
991   __IO uint32_t *data_reg = &hqspi->Instance->DR;\r
992 \r
993   /* Process locked */\r
994   __HAL_LOCK(hqspi);\r
995 \r
996   if(hqspi->State == HAL_QSPI_STATE_READY)\r
997   {\r
998     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
999 \r
1000     if(pData != NULL )\r
1001     {\r
1002       /* Update state */\r
1003       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;\r
1004 \r
1005       /* Configure counters and size of the handle */\r
1006       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;\r
1007       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;\r
1008       hqspi->pTxBuffPtr = pData;\r
1009 \r
1010       /* Configure QSPI: CCR register with functional as indirect write */\r
1011       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);\r
1012 \r
1013       while(hqspi->TxXferCount > 0U)\r
1014       {\r
1015         /* Wait until FT flag is set to send data */\r
1016         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);\r
1017 \r
1018         if (status != HAL_OK)\r
1019         {\r
1020           break;\r
1021         }\r
1022 \r
1023         *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;\r
1024         hqspi->pTxBuffPtr++;\r
1025         hqspi->TxXferCount--;\r
1026       }\r
1027 \r
1028       if (status == HAL_OK)\r
1029       {\r
1030         /* Wait until TC flag is set to go back in idle state */\r
1031         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);\r
1032 \r
1033         if (status == HAL_OK)\r
1034         {\r
1035           /* Clear Transfer Complete bit */\r
1036           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
1037 \r
1038 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))\r
1039           /* Clear Busy bit */\r
1040           status = HAL_QSPI_Abort(hqspi);\r
1041 #endif\r
1042         }\r
1043       }\r
1044 \r
1045       /* Update QSPI state */\r
1046       hqspi->State = HAL_QSPI_STATE_READY;\r
1047     }\r
1048     else\r
1049     {\r
1050       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1051       status = HAL_ERROR;\r
1052     }\r
1053   }\r
1054   else\r
1055   {\r
1056     status = HAL_BUSY;\r
1057   }\r
1058 \r
1059   /* Process unlocked */\r
1060   __HAL_UNLOCK(hqspi);\r
1061 \r
1062   return status;\r
1063 }\r
1064 \r
1065 \r
1066 /**\r
1067   * @brief Receive an amount of data in blocking mode.\r
1068   * @param hqspi : QSPI handle\r
1069   * @param pData : pointer to data buffer\r
1070   * @param Timeout : Timeout duration\r
1071   * @note   This function is used only in Indirect Read Mode\r
1072   * @retval HAL status\r
1073   */\r
1074 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)\r
1075 {\r
1076   HAL_StatusTypeDef status = HAL_OK;\r
1077   uint32_t tickstart = HAL_GetTick();\r
1078   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);\r
1079   __IO uint32_t *data_reg = &hqspi->Instance->DR;\r
1080 \r
1081   /* Process locked */\r
1082   __HAL_LOCK(hqspi);\r
1083 \r
1084   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1085   {\r
1086     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1087 \r
1088     if(pData != NULL )\r
1089     {\r
1090       /* Update state */\r
1091       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;\r
1092 \r
1093       /* Configure counters and size of the handle */\r
1094       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;\r
1095       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;\r
1096       hqspi->pRxBuffPtr = pData;\r
1097 \r
1098       /* Configure QSPI: CCR register with functional as indirect read */\r
1099       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);\r
1100 \r
1101       /* Start the transfer by re-writing the address in AR register */\r
1102       WRITE_REG(hqspi->Instance->AR, addr_reg);\r
1103 \r
1104       while(hqspi->RxXferCount > 0U)\r
1105       {\r
1106         /* Wait until FT or TC flag is set to read received data */\r
1107         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);\r
1108 \r
1109         if  (status != HAL_OK)\r
1110         {\r
1111           break;\r
1112         }\r
1113 \r
1114         *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);\r
1115         hqspi->pRxBuffPtr++;\r
1116         hqspi->RxXferCount--;\r
1117       }\r
1118 \r
1119       if (status == HAL_OK)\r
1120       {\r
1121         /* Wait until TC flag is set to go back in idle state */\r
1122         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);\r
1123 \r
1124         if  (status == HAL_OK)\r
1125         {\r
1126           /* Clear Transfer Complete bit */\r
1127           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
1128 \r
1129 #if  (defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx))\r
1130           /* Workaround - Extra data written in the FIFO at the end of a read transfer */\r
1131           status = HAL_QSPI_Abort(hqspi);\r
1132 #endif\r
1133         }\r
1134       }\r
1135 \r
1136       /* Update QSPI state */\r
1137       hqspi->State = HAL_QSPI_STATE_READY;\r
1138     }\r
1139     else\r
1140     {\r
1141       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1142       status = HAL_ERROR;\r
1143     }\r
1144   }\r
1145   else\r
1146   {\r
1147     status = HAL_BUSY;\r
1148   }\r
1149 \r
1150   /* Process unlocked */\r
1151   __HAL_UNLOCK(hqspi);\r
1152 \r
1153   return status;\r
1154 }\r
1155 \r
1156 /**\r
1157   * @brief  Send an amount of data in non-blocking mode with interrupt.\r
1158   * @param  hqspi : QSPI handle\r
1159   * @param  pData : pointer to data buffer\r
1160   * @note   This function is used only in Indirect Write Mode\r
1161   * @retval HAL status\r
1162   */\r
1163 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)\r
1164 {\r
1165   HAL_StatusTypeDef status = HAL_OK;\r
1166 \r
1167   /* Process locked */\r
1168   __HAL_LOCK(hqspi);\r
1169 \r
1170   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1171   {\r
1172     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1173 \r
1174     if(pData != NULL )\r
1175     {\r
1176       /* Update state */\r
1177       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;\r
1178 \r
1179       /* Configure counters and size of the handle */\r
1180       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;\r
1181       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;\r
1182       hqspi->pTxBuffPtr = pData;\r
1183 \r
1184       /* Clear interrupt */\r
1185       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);\r
1186 \r
1187       /* Configure QSPI: CCR register with functional as indirect write */\r
1188       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);\r
1189 \r
1190       /* Process unlocked */\r
1191       __HAL_UNLOCK(hqspi);\r
1192 \r
1193       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */\r
1194       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);\r
1195     }\r
1196     else\r
1197     {\r
1198       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1199       status = HAL_ERROR;\r
1200 \r
1201       /* Process unlocked */\r
1202       __HAL_UNLOCK(hqspi);\r
1203     }\r
1204   }\r
1205   else\r
1206   {\r
1207     status = HAL_BUSY;\r
1208 \r
1209     /* Process unlocked */\r
1210     __HAL_UNLOCK(hqspi);\r
1211   }\r
1212 \r
1213   return status;\r
1214 }\r
1215 \r
1216 /**\r
1217   * @brief  Receive an amount of data in non-blocking mode with interrupt.\r
1218   * @param  hqspi : QSPI handle\r
1219   * @param  pData : pointer to data buffer\r
1220   * @note   This function is used only in Indirect Read Mode\r
1221   * @retval HAL status\r
1222   */\r
1223 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)\r
1224 {\r
1225   HAL_StatusTypeDef status = HAL_OK;\r
1226   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);\r
1227 \r
1228   /* Process locked */\r
1229   __HAL_LOCK(hqspi);\r
1230 \r
1231   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1232   {\r
1233     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1234 \r
1235     if(pData != NULL )\r
1236     {\r
1237       /* Update state */\r
1238       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;\r
1239 \r
1240       /* Configure counters and size of the handle */\r
1241       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;\r
1242       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;\r
1243       hqspi->pRxBuffPtr = pData;\r
1244 \r
1245       /* Clear interrupt */\r
1246       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);\r
1247 \r
1248       /* Configure QSPI: CCR register with functional as indirect read */\r
1249       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);\r
1250 \r
1251       /* Start the transfer by re-writing the address in AR register */\r
1252       WRITE_REG(hqspi->Instance->AR, addr_reg);\r
1253 \r
1254       /* Process unlocked */\r
1255       __HAL_UNLOCK(hqspi);\r
1256 \r
1257       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */\r
1258       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);\r
1259     }\r
1260     else\r
1261     {\r
1262       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1263       status = HAL_ERROR;\r
1264 \r
1265       /* Process unlocked */\r
1266       __HAL_UNLOCK(hqspi);\r
1267     }\r
1268   }\r
1269   else\r
1270   {\r
1271     status = HAL_BUSY;\r
1272 \r
1273     /* Process unlocked */\r
1274     __HAL_UNLOCK(hqspi);\r
1275   }\r
1276 \r
1277   return status;\r
1278 }\r
1279 \r
1280 /**\r
1281   * @brief  Send an amount of data in non-blocking mode with DMA.\r
1282   * @param  hqspi : QSPI handle\r
1283   * @param  pData : pointer to data buffer\r
1284   * @note   This function is used only in Indirect Write Mode\r
1285   * @note   If DMA peripheral access is configured as halfword, the number\r
1286   *         of data and the fifo threshold should be aligned on halfword\r
1287   * @note   If DMA peripheral access is configured as word, the number\r
1288   *         of data and the fifo threshold should be aligned on word\r
1289   * @retval HAL status\r
1290   */\r
1291 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)\r
1292 {\r
1293   HAL_StatusTypeDef status = HAL_OK;\r
1294   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);\r
1295 \r
1296   /* Process locked */\r
1297   __HAL_LOCK(hqspi);\r
1298 \r
1299   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1300   {\r
1301     /* Clear the error code */\r
1302     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1303 \r
1304     if(pData != NULL )\r
1305     {\r
1306       /* Configure counters of the handle */\r
1307       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)\r
1308       {\r
1309         hqspi->TxXferCount = data_size;\r
1310       }\r
1311       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)\r
1312       {\r
1313         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))\r
1314         {\r
1315           /* The number of data or the fifo threshold is not aligned on halfword\r
1316           => no transfer possible with DMA peripheral access configured as halfword */\r
1317           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1318           status = HAL_ERROR;\r
1319 \r
1320           /* Process unlocked */\r
1321           __HAL_UNLOCK(hqspi);\r
1322         }\r
1323         else\r
1324         {\r
1325           hqspi->TxXferCount = (data_size >> 1U);\r
1326         }\r
1327       }\r
1328       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)\r
1329       {\r
1330         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))\r
1331         {\r
1332           /* The number of data or the fifo threshold is not aligned on word\r
1333           => no transfer possible with DMA peripheral access configured as word */\r
1334           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1335           status = HAL_ERROR;\r
1336 \r
1337           /* Process unlocked */\r
1338           __HAL_UNLOCK(hqspi);\r
1339         }\r
1340         else\r
1341         {\r
1342           hqspi->TxXferCount = (data_size >> 2U);\r
1343         }\r
1344       }\r
1345       else\r
1346       {\r
1347         /* Nothing to do */\r
1348       }\r
1349 \r
1350       if (status == HAL_OK)\r
1351       {\r
1352         /* Update state */\r
1353         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;\r
1354 \r
1355         /* Clear interrupt */\r
1356         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));\r
1357 \r
1358         /* Configure size and pointer of the handle */\r
1359         hqspi->TxXferSize = hqspi->TxXferCount;\r
1360         hqspi->pTxBuffPtr = pData;\r
1361 \r
1362         /* Configure QSPI: CCR register with functional mode as indirect write */\r
1363         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);\r
1364 \r
1365         /* Set the QSPI DMA transfer complete callback */\r
1366         hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;\r
1367 \r
1368         /* Set the QSPI DMA Half transfer complete callback */\r
1369         hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;\r
1370 \r
1371         /* Set the DMA error callback */\r
1372         hqspi->hdma->XferErrorCallback = QSPI_DMAError;\r
1373 \r
1374         /* Clear the DMA abort callback */\r
1375         hqspi->hdma->XferAbortCallback = NULL;\r
1376 \r
1377         /* Configure the direction of the DMA */\r
1378         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;\r
1379         MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);\r
1380 \r
1381         /* Enable the QSPI transmit DMA Channel */\r
1382         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)\r
1383         {\r
1384           /* Process unlocked */\r
1385           __HAL_UNLOCK(hqspi);\r
1386           \r
1387           /* Enable the QSPI transfer error Interrupt */\r
1388           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);\r
1389           \r
1390           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */\r
1391           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
1392         }\r
1393         else\r
1394         {\r
1395           status = HAL_ERROR;\r
1396           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;\r
1397           hqspi->State = HAL_QSPI_STATE_READY;\r
1398 \r
1399           /* Process unlocked */\r
1400           __HAL_UNLOCK(hqspi);\r
1401         }\r
1402      }\r
1403     }\r
1404     else\r
1405     {\r
1406       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1407       status = HAL_ERROR;\r
1408 \r
1409       /* Process unlocked */\r
1410       __HAL_UNLOCK(hqspi);\r
1411     }\r
1412   }\r
1413   else\r
1414   {\r
1415     status = HAL_BUSY;\r
1416 \r
1417     /* Process unlocked */\r
1418     __HAL_UNLOCK(hqspi);\r
1419   }\r
1420 \r
1421   return status;\r
1422 }\r
1423 \r
1424 /**\r
1425   * @brief  Receive an amount of data in non-blocking mode with DMA.\r
1426   * @param  hqspi : QSPI handle\r
1427   * @param  pData : pointer to data buffer.\r
1428   * @note   This function is used only in Indirect Read Mode\r
1429   * @note   If DMA peripheral access is configured as halfword, the number\r
1430   *         of data and the fifo threshold should be aligned on halfword\r
1431   * @note   If DMA peripheral access is configured as word, the number\r
1432   *         of data and the fifo threshold should be aligned on word\r
1433   * @retval HAL status\r
1434   */\r
1435 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)\r
1436 {\r
1437   HAL_StatusTypeDef status = HAL_OK;\r
1438   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);\r
1439   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);\r
1440 \r
1441   /* Process locked */\r
1442   __HAL_LOCK(hqspi);\r
1443 \r
1444   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1445   {\r
1446     /* Clear the error code */\r
1447     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1448 \r
1449     if(pData != NULL )\r
1450     {\r
1451       /* Configure counters of the handle */\r
1452       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)\r
1453       {\r
1454         hqspi->RxXferCount = data_size;\r
1455       }\r
1456       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)\r
1457       {\r
1458         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))\r
1459         {\r
1460           /* The number of data or the fifo threshold is not aligned on halfword\r
1461              => no transfer possible with DMA peripheral access configured as halfword */\r
1462           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1463           status = HAL_ERROR;\r
1464 \r
1465           /* Process unlocked */\r
1466           __HAL_UNLOCK(hqspi);\r
1467         }\r
1468         else\r
1469         {\r
1470           hqspi->RxXferCount = (data_size >> 1U);\r
1471         }\r
1472       }\r
1473       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)\r
1474       {\r
1475         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))\r
1476         {\r
1477           /* The number of data or the fifo threshold is not aligned on word\r
1478              => no transfer possible with DMA peripheral access configured as word */\r
1479           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1480           status = HAL_ERROR;\r
1481 \r
1482           /* Process unlocked */\r
1483           __HAL_UNLOCK(hqspi);\r
1484         }\r
1485         else\r
1486         {\r
1487           hqspi->RxXferCount = (data_size >> 2U);\r
1488         }\r
1489       }\r
1490       else\r
1491       {\r
1492         /* Nothing to do */\r
1493       }\r
1494 \r
1495       if (status == HAL_OK)\r
1496       {\r
1497         /* Update state */\r
1498         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;\r
1499 \r
1500         /* Clear interrupt */\r
1501         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));\r
1502 \r
1503         /* Configure size and pointer of the handle */\r
1504         hqspi->RxXferSize = hqspi->RxXferCount;\r
1505         hqspi->pRxBuffPtr = pData;\r
1506 \r
1507         /* Set the QSPI DMA transfer complete callback */\r
1508         hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;\r
1509 \r
1510         /* Set the QSPI DMA Half transfer complete callback */\r
1511         hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;\r
1512 \r
1513         /* Set the DMA error callback */\r
1514         hqspi->hdma->XferErrorCallback = QSPI_DMAError;\r
1515 \r
1516         /* Clear the DMA abort callback */\r
1517         hqspi->hdma->XferAbortCallback = NULL;\r
1518 \r
1519         /* Configure the direction of the DMA */\r
1520         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;\r
1521         MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);\r
1522 \r
1523         /* Enable the DMA Channel */\r
1524         if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)\r
1525         {\r
1526           /* Configure QSPI: CCR register with functional as indirect read */\r
1527           MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);\r
1528 \r
1529           /* Start the transfer by re-writing the address in AR register */\r
1530           WRITE_REG(hqspi->Instance->AR, addr_reg);\r
1531 \r
1532           /* Process unlocked */\r
1533           __HAL_UNLOCK(hqspi);\r
1534           \r
1535           /* Enable the QSPI transfer error Interrupt */\r
1536           __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);\r
1537           \r
1538           /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */\r
1539           SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
1540         }\r
1541         else\r
1542         {\r
1543           status = HAL_ERROR;\r
1544           hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;\r
1545           hqspi->State = HAL_QSPI_STATE_READY;\r
1546 \r
1547           /* Process unlocked */\r
1548           __HAL_UNLOCK(hqspi);\r
1549         }\r
1550       }\r
1551     }\r
1552     else\r
1553     {\r
1554       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;\r
1555       status = HAL_ERROR;\r
1556 \r
1557       /* Process unlocked */\r
1558       __HAL_UNLOCK(hqspi);\r
1559     }\r
1560   }\r
1561   else\r
1562   {\r
1563     status = HAL_BUSY;\r
1564 \r
1565     /* Process unlocked */\r
1566     __HAL_UNLOCK(hqspi);\r
1567   }\r
1568 \r
1569   return status;\r
1570 }\r
1571 \r
1572 /**\r
1573   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode.\r
1574   * @param  hqspi : QSPI handle\r
1575   * @param  cmd : structure that contains the command configuration information.\r
1576   * @param  cfg : structure that contains the polling configuration information.\r
1577   * @param  Timeout : Timeout duration\r
1578   * @note   This function is used only in Automatic Polling Mode\r
1579   * @retval HAL status\r
1580   */\r
1581 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)\r
1582 {\r
1583   HAL_StatusTypeDef status;\r
1584   uint32_t tickstart = HAL_GetTick();\r
1585 \r
1586   /* Check the parameters */\r
1587   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));\r
1588   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
1589   {\r
1590     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));\r
1591   }\r
1592 \r
1593   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));\r
1594   if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
1595   {\r
1596     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));\r
1597   }\r
1598 \r
1599   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));\r
1600   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
1601   {\r
1602     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));\r
1603   }\r
1604 \r
1605   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));\r
1606   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));\r
1607 \r
1608   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));\r
1609   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));\r
1610   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));\r
1611 \r
1612   assert_param(IS_QSPI_INTERVAL(cfg->Interval));\r
1613   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));\r
1614   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));\r
1615 \r
1616   /* Process locked */\r
1617   __HAL_LOCK(hqspi);\r
1618 \r
1619   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1620   {\r
1621     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1622 \r
1623     /* Update state */\r
1624     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;\r
1625 \r
1626     /* Wait till BUSY flag reset */\r
1627     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);\r
1628 \r
1629     if (status == HAL_OK)\r
1630     {\r
1631       /* Configure QSPI: PSMAR register with the status match value */\r
1632       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);\r
1633 \r
1634       /* Configure QSPI: PSMKR register with the status mask value */\r
1635       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);\r
1636 \r
1637       /* Configure QSPI: PIR register with the interval value */\r
1638       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);\r
1639 \r
1640       /* Configure QSPI: CR register with Match mode and Automatic stop enabled\r
1641       (otherwise there will be an infinite loop in blocking mode) */\r
1642       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),\r
1643                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));\r
1644 \r
1645       /* Call the configuration function */\r
1646       cmd->NbData = cfg->StatusBytesSize;\r
1647       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);\r
1648 \r
1649       /* Wait until SM flag is set to go back in idle state */\r
1650       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);\r
1651 \r
1652       if (status == HAL_OK)\r
1653       {\r
1654         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);\r
1655 \r
1656         /* Update state */\r
1657         hqspi->State = HAL_QSPI_STATE_READY;\r
1658       }\r
1659     }\r
1660   }\r
1661   else\r
1662   {\r
1663     status = HAL_BUSY;\r
1664   }\r
1665 \r
1666   /* Process unlocked */\r
1667   __HAL_UNLOCK(hqspi);\r
1668 \r
1669   /* Return function status */\r
1670   return status;\r
1671 }\r
1672 \r
1673 /**\r
1674   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode.\r
1675   * @param  hqspi : QSPI handle\r
1676   * @param  cmd : structure that contains the command configuration information.\r
1677   * @param  cfg : structure that contains the polling configuration information.\r
1678   * @note   This function is used only in Automatic Polling Mode\r
1679   * @retval HAL status\r
1680   */\r
1681 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)\r
1682 {\r
1683   HAL_StatusTypeDef status;\r
1684   uint32_t tickstart = HAL_GetTick();\r
1685 \r
1686   /* Check the parameters */\r
1687   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));\r
1688   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
1689   {\r
1690     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));\r
1691   }\r
1692 \r
1693   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));\r
1694   if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
1695   {\r
1696     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));\r
1697   }\r
1698 \r
1699   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));\r
1700   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
1701   {\r
1702     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));\r
1703   }\r
1704 \r
1705   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));\r
1706   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));\r
1707 \r
1708   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));\r
1709   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));\r
1710   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));\r
1711 \r
1712   assert_param(IS_QSPI_INTERVAL(cfg->Interval));\r
1713   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));\r
1714   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));\r
1715   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));\r
1716 \r
1717   /* Process locked */\r
1718   __HAL_LOCK(hqspi);\r
1719 \r
1720   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1721   {\r
1722     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1723 \r
1724     /* Update state */\r
1725     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;\r
1726 \r
1727     /* Wait till BUSY flag reset */\r
1728     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);\r
1729 \r
1730     if (status == HAL_OK)\r
1731     {\r
1732       /* Configure QSPI: PSMAR register with the status match value */\r
1733       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);\r
1734 \r
1735       /* Configure QSPI: PSMKR register with the status mask value */\r
1736       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);\r
1737 \r
1738       /* Configure QSPI: PIR register with the interval value */\r
1739       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);\r
1740 \r
1741       /* Configure QSPI: CR register with Match mode and Automatic stop mode */\r
1742       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),\r
1743                (cfg->MatchMode | cfg->AutomaticStop));\r
1744 \r
1745       /* Clear interrupt */\r
1746       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);\r
1747 \r
1748       /* Call the configuration function */\r
1749       cmd->NbData = cfg->StatusBytesSize;\r
1750       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);\r
1751 \r
1752       /* Process unlocked */\r
1753       __HAL_UNLOCK(hqspi);\r
1754 \r
1755       /* Enable the QSPI Transfer Error and status match Interrupt */\r
1756       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));\r
1757 \r
1758     }\r
1759     else\r
1760     {\r
1761       /* Process unlocked */\r
1762       __HAL_UNLOCK(hqspi);\r
1763     }\r
1764   }\r
1765   else\r
1766   {\r
1767     status = HAL_BUSY;\r
1768 \r
1769     /* Process unlocked */\r
1770     __HAL_UNLOCK(hqspi);\r
1771   }\r
1772 \r
1773   /* Return function status */\r
1774   return status;\r
1775 }\r
1776 \r
1777 /**\r
1778   * @brief  Configure the Memory Mapped mode.\r
1779   * @param  hqspi : QSPI handle\r
1780   * @param  cmd : structure that contains the command configuration information.\r
1781   * @param  cfg : structure that contains the memory mapped configuration information.\r
1782   * @note   This function is used only in Memory mapped Mode\r
1783   * @retval HAL status\r
1784   */\r
1785 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)\r
1786 {\r
1787   HAL_StatusTypeDef status;\r
1788   uint32_t tickstart = HAL_GetTick();\r
1789 \r
1790   /* Check the parameters */\r
1791   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));\r
1792   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
1793   {\r
1794   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));\r
1795   }\r
1796 \r
1797   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));\r
1798   if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
1799   {\r
1800     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));\r
1801   }\r
1802 \r
1803   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));\r
1804   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
1805   {\r
1806     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));\r
1807   }\r
1808 \r
1809   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));\r
1810   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));\r
1811 \r
1812   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));\r
1813   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));\r
1814   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));\r
1815 \r
1816   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));\r
1817 \r
1818   /* Process locked */\r
1819   __HAL_LOCK(hqspi);\r
1820 \r
1821   if(hqspi->State == HAL_QSPI_STATE_READY)\r
1822   {\r
1823     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;\r
1824 \r
1825     /* Update state */\r
1826     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;\r
1827 \r
1828     /* Wait till BUSY flag reset */\r
1829     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);\r
1830 \r
1831     if (status == HAL_OK)\r
1832     {\r
1833       /* Configure QSPI: CR register with timeout counter enable */\r
1834     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);\r
1835 \r
1836     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)\r
1837       {\r
1838         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));\r
1839 \r
1840         /* Configure QSPI: LPTR register with the low-power timeout value */\r
1841         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);\r
1842 \r
1843         /* Clear interrupt */\r
1844         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);\r
1845 \r
1846         /* Enable the QSPI TimeOut Interrupt */\r
1847         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);\r
1848       }\r
1849 \r
1850       /* Call the configuration function */\r
1851       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);\r
1852     }\r
1853   }\r
1854   else\r
1855   {\r
1856     status = HAL_BUSY;\r
1857   }\r
1858 \r
1859   /* Process unlocked */\r
1860   __HAL_UNLOCK(hqspi);\r
1861 \r
1862   /* Return function status */\r
1863   return status;\r
1864 }\r
1865 \r
1866 /**\r
1867   * @brief  Transfer Error callback.\r
1868   * @param  hqspi : QSPI handle\r
1869   * @retval None\r
1870   */\r
1871 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)\r
1872 {\r
1873   /* Prevent unused argument(s) compilation warning */\r
1874   UNUSED(hqspi);\r
1875 \r
1876   /* NOTE : This function should not be modified, when the callback is needed,\r
1877             the HAL_QSPI_ErrorCallback could be implemented in the user file\r
1878    */\r
1879 }\r
1880 \r
1881 /**\r
1882   * @brief  Abort completed callback.\r
1883   * @param  hqspi : QSPI handle\r
1884   * @retval None\r
1885   */\r
1886 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1887 {\r
1888   /* Prevent unused argument(s) compilation warning */\r
1889   UNUSED(hqspi);\r
1890 \r
1891   /* NOTE: This function should not be modified, when the callback is needed,\r
1892            the HAL_QSPI_AbortCpltCallback could be implemented in the user file\r
1893    */\r
1894 }\r
1895 \r
1896 /**\r
1897   * @brief  Command completed callback.\r
1898   * @param  hqspi : QSPI handle\r
1899   * @retval None\r
1900   */\r
1901 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1902 {\r
1903   /* Prevent unused argument(s) compilation warning */\r
1904   UNUSED(hqspi);\r
1905 \r
1906   /* NOTE: This function should not be modified, when the callback is needed,\r
1907            the HAL_QSPI_CmdCpltCallback could be implemented in the user file\r
1908    */\r
1909 }\r
1910 \r
1911 /**\r
1912   * @brief  Rx Transfer completed callback.\r
1913   * @param  hqspi : QSPI handle\r
1914   * @retval None\r
1915   */\r
1916 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1917 {\r
1918   /* Prevent unused argument(s) compilation warning */\r
1919   UNUSED(hqspi);\r
1920 \r
1921   /* NOTE: This function should not be modified, when the callback is needed,\r
1922            the HAL_QSPI_RxCpltCallback could be implemented in the user file\r
1923    */\r
1924 }\r
1925 \r
1926 /**\r
1927   * @brief  Tx Transfer completed callback.\r
1928   * @param  hqspi : QSPI handle\r
1929   * @retval None\r
1930   */\r
1931 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1932 {\r
1933   /* Prevent unused argument(s) compilation warning */\r
1934   UNUSED(hqspi);\r
1935 \r
1936   /* NOTE: This function should not be modified, when the callback is needed,\r
1937            the HAL_QSPI_TxCpltCallback could be implemented in the user file\r
1938    */\r
1939 }\r
1940 \r
1941 /**\r
1942   * @brief  Rx Half Transfer completed callback.\r
1943   * @param  hqspi : QSPI handle\r
1944   * @retval None\r
1945   */\r
1946 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1947 {\r
1948   /* Prevent unused argument(s) compilation warning */\r
1949   UNUSED(hqspi);\r
1950 \r
1951   /* NOTE: This function should not be modified, when the callback is needed,\r
1952            the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file\r
1953    */\r
1954 }\r
1955 \r
1956 /**\r
1957   * @brief  Tx Half Transfer completed callback.\r
1958   * @param  hqspi : QSPI handle\r
1959   * @retval None\r
1960   */\r
1961 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)\r
1962 {\r
1963   /* Prevent unused argument(s) compilation warning */\r
1964   UNUSED(hqspi);\r
1965 \r
1966   /* NOTE: This function should not be modified, when the callback is needed,\r
1967            the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file\r
1968    */\r
1969 }\r
1970 \r
1971 /**\r
1972   * @brief  FIFO Threshold callback.\r
1973   * @param  hqspi : QSPI handle\r
1974   * @retval None\r
1975   */\r
1976 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)\r
1977 {\r
1978   /* Prevent unused argument(s) compilation warning */\r
1979   UNUSED(hqspi);\r
1980 \r
1981   /* NOTE : This function should not be modified, when the callback is needed,\r
1982             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file\r
1983    */\r
1984 }\r
1985 \r
1986 /**\r
1987   * @brief  Status Match callback.\r
1988   * @param  hqspi : QSPI handle\r
1989   * @retval None\r
1990   */\r
1991 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)\r
1992 {\r
1993   /* Prevent unused argument(s) compilation warning */\r
1994   UNUSED(hqspi);\r
1995 \r
1996   /* NOTE : This function should not be modified, when the callback is needed,\r
1997             the HAL_QSPI_StatusMatchCallback could be implemented in the user file\r
1998    */\r
1999 }\r
2000 \r
2001 /**\r
2002   * @brief  Timeout callback.\r
2003   * @param  hqspi : QSPI handle\r
2004   * @retval None\r
2005   */\r
2006 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)\r
2007 {\r
2008   /* Prevent unused argument(s) compilation warning */\r
2009   UNUSED(hqspi);\r
2010 \r
2011   /* NOTE : This function should not be modified, when the callback is needed,\r
2012             the HAL_QSPI_TimeOutCallback could be implemented in the user file\r
2013    */\r
2014 }\r
2015 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
2016 /**\r
2017   * @brief  Register a User QSPI Callback\r
2018   *         To be used instead of the weak (surcharged) predefined callback\r
2019   * @param hqspi : QSPI handle\r
2020   * @param CallbackId : ID of the callback to be registered\r
2021   *        This parameter can be one of the following values:\r
2022   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID\r
2023   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID\r
2024   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID\r
2025   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID\r
2026   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID\r
2027   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID\r
2028   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID\r
2029   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID\r
2030   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID\r
2031   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID\r
2032   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID\r
2033   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID\r
2034   * @param pCallback : pointer to the Callback function\r
2035   * @retval status\r
2036   */\r
2037 HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)\r
2038 {\r
2039   HAL_StatusTypeDef status = HAL_OK;\r
2040 \r
2041   if(pCallback == NULL)\r
2042   {\r
2043     /* Update the error code */\r
2044     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2045     return HAL_ERROR;\r
2046   }\r
2047 \r
2048   /* Process locked */\r
2049   __HAL_LOCK(hqspi);\r
2050 \r
2051   if(hqspi->State == HAL_QSPI_STATE_READY)\r
2052   {\r
2053     switch (CallbackId)\r
2054     {\r
2055     case  HAL_QSPI_ERROR_CB_ID :\r
2056       hqspi->ErrorCallback = pCallback;\r
2057       break;\r
2058     case HAL_QSPI_ABORT_CB_ID :\r
2059       hqspi->AbortCpltCallback = pCallback;\r
2060       break;\r
2061     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :\r
2062       hqspi->FifoThresholdCallback = pCallback;\r
2063       break;\r
2064     case HAL_QSPI_CMD_CPLT_CB_ID :\r
2065       hqspi->CmdCpltCallback = pCallback;\r
2066       break;\r
2067     case HAL_QSPI_RX_CPLT_CB_ID :\r
2068       hqspi->RxCpltCallback = pCallback;\r
2069       break;\r
2070     case HAL_QSPI_TX_CPLT_CB_ID :\r
2071       hqspi->TxCpltCallback = pCallback;\r
2072       break;\r
2073     case HAL_QSPI_RX_HALF_CPLT_CB_ID :\r
2074       hqspi->RxHalfCpltCallback = pCallback;\r
2075       break;\r
2076     case HAL_QSPI_TX_HALF_CPLT_CB_ID :\r
2077       hqspi->TxHalfCpltCallback = pCallback;\r
2078       break;\r
2079     case HAL_QSPI_STATUS_MATCH_CB_ID :\r
2080       hqspi->StatusMatchCallback = pCallback;\r
2081       break;\r
2082     case HAL_QSPI_TIMEOUT_CB_ID :\r
2083       hqspi->TimeOutCallback = pCallback;\r
2084       break;\r
2085     case HAL_QSPI_MSP_INIT_CB_ID :\r
2086       hqspi->MspInitCallback = pCallback;\r
2087       break;\r
2088     case HAL_QSPI_MSP_DEINIT_CB_ID :\r
2089       hqspi->MspDeInitCallback = pCallback;\r
2090       break;\r
2091     default :\r
2092       /* Update the error code */\r
2093       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2094       /* update return status */\r
2095       status =  HAL_ERROR;\r
2096       break;\r
2097     }\r
2098   }\r
2099   else if (hqspi->State == HAL_QSPI_STATE_RESET)\r
2100   {\r
2101     switch (CallbackId)\r
2102     {\r
2103     case HAL_QSPI_MSP_INIT_CB_ID :\r
2104       hqspi->MspInitCallback = pCallback;\r
2105       break;\r
2106     case HAL_QSPI_MSP_DEINIT_CB_ID :\r
2107       hqspi->MspDeInitCallback = pCallback;\r
2108       break;\r
2109     default :\r
2110       /* Update the error code */\r
2111       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2112       /* update return status */\r
2113       status =  HAL_ERROR;\r
2114       break;\r
2115     }\r
2116   }\r
2117   else\r
2118   {\r
2119     /* Update the error code */\r
2120     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2121     /* update return status */\r
2122     status =  HAL_ERROR;\r
2123   }\r
2124 \r
2125   /* Release Lock */\r
2126   __HAL_UNLOCK(hqspi);\r
2127   return status;\r
2128 }\r
2129 \r
2130 /**\r
2131   * @brief  Unregister a User QSPI Callback\r
2132   *         QSPI Callback is redirected to the weak (surcharged) predefined callback\r
2133   * @param hqspi : QSPI handle\r
2134   * @param CallbackId : ID of the callback to be unregistered\r
2135   *        This parameter can be one of the following values:\r
2136   *          @arg @ref HAL_QSPI_ERROR_CB_ID          QSPI Error Callback ID\r
2137   *          @arg @ref HAL_QSPI_ABORT_CB_ID          QSPI Abort Callback ID\r
2138   *          @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID\r
2139   *          @arg @ref HAL_QSPI_CMD_CPLT_CB_ID       QSPI Command Complete Callback ID\r
2140   *          @arg @ref HAL_QSPI_RX_CPLT_CB_ID        QSPI Rx Complete Callback ID\r
2141   *          @arg @ref HAL_QSPI_TX_CPLT_CB_ID        QSPI Tx Complete Callback ID\r
2142   *          @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID   QSPI Rx Half Complete Callback ID\r
2143   *          @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID   QSPI Tx Half Complete Callback ID\r
2144   *          @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID   QSPI Status Match Callback ID\r
2145   *          @arg @ref HAL_QSPI_TIMEOUT_CB_ID        QSPI Timeout Callback ID\r
2146   *          @arg @ref HAL_QSPI_MSP_INIT_CB_ID       QSPI MspInit callback ID\r
2147   *          @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID     QSPI MspDeInit callback ID\r
2148   * @retval status\r
2149   */\r
2150 HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)\r
2151 {\r
2152   HAL_StatusTypeDef status = HAL_OK;\r
2153 \r
2154   /* Process locked */\r
2155   __HAL_LOCK(hqspi);\r
2156 \r
2157   if(hqspi->State == HAL_QSPI_STATE_READY)\r
2158   {\r
2159     switch (CallbackId)\r
2160     {\r
2161     case  HAL_QSPI_ERROR_CB_ID :\r
2162       hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;\r
2163       break;\r
2164     case HAL_QSPI_ABORT_CB_ID :\r
2165       hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;\r
2166       break;\r
2167     case HAL_QSPI_FIFO_THRESHOLD_CB_ID :\r
2168       hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;\r
2169       break;\r
2170     case HAL_QSPI_CMD_CPLT_CB_ID :\r
2171       hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;\r
2172       break;\r
2173     case HAL_QSPI_RX_CPLT_CB_ID :\r
2174       hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;\r
2175       break;\r
2176     case HAL_QSPI_TX_CPLT_CB_ID :\r
2177       hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;\r
2178       break;\r
2179     case HAL_QSPI_RX_HALF_CPLT_CB_ID :\r
2180       hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;\r
2181       break;\r
2182     case HAL_QSPI_TX_HALF_CPLT_CB_ID :\r
2183       hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;\r
2184       break;\r
2185     case HAL_QSPI_STATUS_MATCH_CB_ID :\r
2186       hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;\r
2187       break;\r
2188     case HAL_QSPI_TIMEOUT_CB_ID :\r
2189       hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;\r
2190       break;\r
2191     case HAL_QSPI_MSP_INIT_CB_ID :\r
2192       hqspi->MspInitCallback = HAL_QSPI_MspInit;\r
2193       break;\r
2194     case HAL_QSPI_MSP_DEINIT_CB_ID :\r
2195       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;\r
2196       break;\r
2197     default :\r
2198       /* Update the error code */\r
2199       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2200       /* update return status */\r
2201       status =  HAL_ERROR;\r
2202       break;\r
2203     }\r
2204   }\r
2205   else if (hqspi->State == HAL_QSPI_STATE_RESET)\r
2206   {\r
2207     switch (CallbackId)\r
2208     {\r
2209     case HAL_QSPI_MSP_INIT_CB_ID :\r
2210       hqspi->MspInitCallback = HAL_QSPI_MspInit;\r
2211       break;\r
2212     case HAL_QSPI_MSP_DEINIT_CB_ID :\r
2213       hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;\r
2214       break;\r
2215     default :\r
2216       /* Update the error code */\r
2217       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2218       /* update return status */\r
2219       status =  HAL_ERROR;\r
2220       break;\r
2221     }\r
2222   }\r
2223   else\r
2224   {\r
2225     /* Update the error code */\r
2226     hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;\r
2227     /* update return status */\r
2228     status =  HAL_ERROR;\r
2229   }\r
2230 \r
2231   /* Release Lock */\r
2232   __HAL_UNLOCK(hqspi);\r
2233   return status;\r
2234 }\r
2235 #endif\r
2236 \r
2237 /**\r
2238   * @}\r
2239   */\r
2240 \r
2241 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions\r
2242   *  @brief   QSPI control and State functions\r
2243   *\r
2244 @verbatim\r
2245  ===============================================================================\r
2246                   ##### Peripheral Control and State functions #####\r
2247  ===============================================================================\r
2248     [..]\r
2249     This subsection provides a set of functions allowing to :\r
2250       (+) Check in run-time the state of the driver.\r
2251       (+) Check the error code set during last operation.\r
2252       (+) Abort any operation.\r
2253 \r
2254 \r
2255 @endverbatim\r
2256   * @{\r
2257   */\r
2258 \r
2259 /**\r
2260   * @brief  Return the QSPI handle state.\r
2261   * @param  hqspi : QSPI handle\r
2262   * @retval HAL state\r
2263   */\r
2264 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)\r
2265 {\r
2266   /* Return QSPI handle state */\r
2267   return hqspi->State;\r
2268 }\r
2269 \r
2270 /**\r
2271 * @brief  Return the QSPI error code.\r
2272 * @param  hqspi : QSPI handle\r
2273 * @retval QSPI Error Code\r
2274 */\r
2275 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)\r
2276 {\r
2277   return hqspi->ErrorCode;\r
2278 }\r
2279 \r
2280 /**\r
2281 * @brief  Abort the current transmission.\r
2282 * @param  hqspi : QSPI handle\r
2283 * @retval HAL status\r
2284 */\r
2285 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)\r
2286 {\r
2287   HAL_StatusTypeDef status = HAL_OK;\r
2288   uint32_t tickstart = HAL_GetTick();\r
2289 \r
2290   /* Check if the state is in one of the busy states */\r
2291   if (((uint32_t)hqspi->State & 0x2U) != 0U)\r
2292   {\r
2293     /* Process unlocked */\r
2294     __HAL_UNLOCK(hqspi);\r
2295 \r
2296     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)\r
2297     {\r
2298       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
2299       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
2300 \r
2301       /* Abort DMA channel */\r
2302       status = HAL_DMA_Abort(hqspi->hdma);\r
2303       if(status != HAL_OK)\r
2304       {\r
2305         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;\r
2306       }\r
2307     }\r
2308 \r
2309     /* Configure QSPI: CR register with Abort request */\r
2310     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);\r
2311 \r
2312     /* Wait until TC flag is set to go back in idle state */\r
2313     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);\r
2314 \r
2315     if (status == HAL_OK)\r
2316     {\r
2317       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
2318 \r
2319       /* Wait until BUSY flag is reset */\r
2320       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);\r
2321     }\r
2322 \r
2323     if (status == HAL_OK)\r
2324     {\r
2325       /* Reset functional mode configuration to indirect write mode by default */\r
2326       CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);\r
2327 \r
2328       /* Update state */\r
2329       hqspi->State = HAL_QSPI_STATE_READY;\r
2330     }\r
2331   }\r
2332 \r
2333   return status;\r
2334 }\r
2335 \r
2336 /**\r
2337 * @brief  Abort the current transmission (non-blocking function)\r
2338 * @param  hqspi : QSPI handle\r
2339 * @retval HAL status\r
2340 */\r
2341 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)\r
2342 {\r
2343   HAL_StatusTypeDef status = HAL_OK;\r
2344 \r
2345   /* Check if the state is in one of the busy states */\r
2346   if (((uint32_t)hqspi->State & 0x2U) != 0U)\r
2347   {\r
2348     /* Process unlocked */\r
2349     __HAL_UNLOCK(hqspi);\r
2350 \r
2351     /* Update QSPI state */\r
2352     hqspi->State = HAL_QSPI_STATE_ABORT;\r
2353 \r
2354     /* Disable all interrupts */\r
2355     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));\r
2356 \r
2357     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)\r
2358     {\r
2359       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
2360       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
2361 \r
2362       /* Abort DMA channel */\r
2363       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;\r
2364       if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)\r
2365       {\r
2366         /* Change state of QSPI */\r
2367         hqspi->State = HAL_QSPI_STATE_READY;\r
2368         \r
2369         /* Abort Complete callback */\r
2370 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
2371         hqspi->AbortCpltCallback(hqspi);\r
2372 #else\r
2373         HAL_QSPI_AbortCpltCallback(hqspi);\r
2374 #endif\r
2375       }\r
2376     }\r
2377     else\r
2378     {\r
2379       /* Clear interrupt */\r
2380       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
2381 \r
2382       /* Enable the QSPI Transfer Complete Interrupt */\r
2383       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);\r
2384 \r
2385       /* Configure QSPI: CR register with Abort request */\r
2386       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);\r
2387     }\r
2388   }\r
2389   return status;\r
2390 }\r
2391 \r
2392 /** @brief Set QSPI timeout.\r
2393   * @param  hqspi : QSPI handle.\r
2394   * @param  Timeout : Timeout for the QSPI memory access.\r
2395   * @retval None\r
2396   */\r
2397 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)\r
2398 {\r
2399   hqspi->Timeout = Timeout;\r
2400 }\r
2401 \r
2402 /** @brief Set QSPI Fifo threshold.\r
2403   * @param  hqspi : QSPI handle.\r
2404   * @param  Threshold : Threshold of the Fifo (value between 1 and 16).\r
2405   * @retval HAL status\r
2406   */\r
2407 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)\r
2408 {\r
2409   HAL_StatusTypeDef status = HAL_OK;\r
2410 \r
2411   /* Process locked */\r
2412   __HAL_LOCK(hqspi);\r
2413 \r
2414   if(hqspi->State == HAL_QSPI_STATE_READY)\r
2415   {\r
2416     /* Synchronize init structure with new FIFO threshold value */\r
2417     hqspi->Init.FifoThreshold = Threshold;\r
2418 \r
2419     /* Configure QSPI FIFO Threshold */\r
2420     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,\r
2421                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));\r
2422   }\r
2423   else\r
2424   {\r
2425     status = HAL_BUSY;\r
2426   }\r
2427 \r
2428   /* Process unlocked */\r
2429   __HAL_UNLOCK(hqspi);\r
2430 \r
2431   /* Return function status */\r
2432   return status;\r
2433 }\r
2434 \r
2435 /** @brief Get QSPI Fifo threshold.\r
2436   * @param  hqspi : QSPI handle.\r
2437   * @retval Fifo threshold (value between 1 and 16)\r
2438   */\r
2439 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)\r
2440 {\r
2441   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);\r
2442 }\r
2443 \r
2444 #if defined(QUADSPI_CR_DFM)\r
2445 /** @brief  Set FlashID.\r
2446   * @param  hqspi : QSPI handle.\r
2447   * @param  FlashID : Index of the flash memory to be accessed.\r
2448   *                   This parameter can be a value of @ref QSPI_Flash_Select.\r
2449   * @note   The FlashID is ignored when dual flash mode is enabled.\r
2450   * @retval HAL status\r
2451   */\r
2452 HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)\r
2453 {\r
2454   HAL_StatusTypeDef status = HAL_OK;\r
2455 \r
2456   /* Check the parameter */\r
2457   assert_param(IS_QSPI_FLASH_ID(FlashID));\r
2458 \r
2459   /* Process locked */\r
2460   __HAL_LOCK(hqspi);\r
2461 \r
2462   if(hqspi->State == HAL_QSPI_STATE_READY)\r
2463   {\r
2464     /* Synchronize init structure with new FlashID value */\r
2465     hqspi->Init.FlashID = FlashID;\r
2466 \r
2467     /* Configure QSPI FlashID */\r
2468     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);\r
2469   }\r
2470   else\r
2471   {\r
2472     status = HAL_BUSY;\r
2473   }\r
2474 \r
2475   /* Process unlocked */\r
2476   __HAL_UNLOCK(hqspi);\r
2477 \r
2478   /* Return function status */\r
2479   return status;\r
2480 }\r
2481 \r
2482 #endif\r
2483 /**\r
2484   * @}\r
2485   */\r
2486 \r
2487 /**\r
2488   * @}\r
2489   */\r
2490 \r
2491 /** @defgroup QSPI_Private_Functions QSPI Private Functions\r
2492   * @{\r
2493   */\r
2494 \r
2495 /**\r
2496   * @brief  DMA QSPI receive process complete callback.\r
2497   * @param  hdma : DMA handle\r
2498   * @retval None\r
2499   */\r
2500 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)\r
2501 {\r
2502   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);\r
2503   hqspi->RxXferCount = 0U;\r
2504 \r
2505   /* Enable the QSPI transfer complete Interrupt */\r
2506   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);\r
2507 }\r
2508 \r
2509 /**\r
2510   * @brief  DMA QSPI transmit process complete callback.\r
2511   * @param  hdma : DMA handle\r
2512   * @retval None\r
2513   */\r
2514 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)\r
2515 {\r
2516   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);\r
2517   hqspi->TxXferCount = 0U;\r
2518 \r
2519   /* Enable the QSPI transfer complete Interrupt */\r
2520   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);\r
2521 }\r
2522 \r
2523 /**\r
2524   * @brief  DMA QSPI receive process half complete callback.\r
2525   * @param  hdma : DMA handle\r
2526   * @retval None\r
2527   */\r
2528 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)\r
2529 {\r
2530   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);\r
2531 \r
2532 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
2533   hqspi->RxHalfCpltCallback(hqspi);\r
2534 #else\r
2535   HAL_QSPI_RxHalfCpltCallback(hqspi);\r
2536 #endif\r
2537 }\r
2538 \r
2539 /**\r
2540   * @brief  DMA QSPI transmit process half complete callback.\r
2541   * @param  hdma : DMA handle\r
2542   * @retval None\r
2543   */\r
2544 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)\r
2545 {\r
2546   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);\r
2547 \r
2548 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
2549   hqspi->TxHalfCpltCallback(hqspi);\r
2550 #else\r
2551   HAL_QSPI_TxHalfCpltCallback(hqspi);\r
2552 #endif\r
2553 }\r
2554 \r
2555 /**\r
2556   * @brief  DMA QSPI communication error callback.\r
2557   * @param  hdma : DMA handle\r
2558   * @retval None\r
2559   */\r
2560 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)\r
2561 {\r
2562   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);\r
2563 \r
2564   hqspi->RxXferCount = 0U;\r
2565   hqspi->TxXferCount = 0U;\r
2566   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;\r
2567 \r
2568   /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */\r
2569   CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);\r
2570 \r
2571   /* Abort the QSPI */\r
2572   (void)HAL_QSPI_Abort_IT(hqspi);\r
2573 \r
2574 }\r
2575 \r
2576 /**\r
2577   * @brief  DMA QSPI abort complete callback.\r
2578   * @param  hdma : DMA handle\r
2579   * @retval None\r
2580   */\r
2581 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)\r
2582 {\r
2583   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);\r
2584 \r
2585   hqspi->RxXferCount = 0U;\r
2586   hqspi->TxXferCount = 0U;\r
2587 \r
2588   if(hqspi->State == HAL_QSPI_STATE_ABORT)\r
2589   {\r
2590     /* DMA Abort called by QSPI abort */\r
2591     /* Clear interrupt */\r
2592     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);\r
2593 \r
2594     /* Enable the QSPI Transfer Complete Interrupt */\r
2595     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);\r
2596 \r
2597     /* Configure QSPI: CR register with Abort request */\r
2598     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);\r
2599   }\r
2600   else\r
2601   {\r
2602     /* DMA Abort called due to a transfer error interrupt */\r
2603     /* Change state of QSPI */\r
2604     hqspi->State = HAL_QSPI_STATE_READY;\r
2605 \r
2606     /* Error callback */\r
2607 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)\r
2608     hqspi->ErrorCallback(hqspi);\r
2609 #else\r
2610     HAL_QSPI_ErrorCallback(hqspi);\r
2611 #endif\r
2612   }\r
2613 }\r
2614 \r
2615 /**\r
2616   * @brief  Wait for a flag state until timeout.\r
2617   * @param  hqspi : QSPI handle\r
2618   * @param  Flag : Flag checked\r
2619   * @param  State : Value of the flag expected\r
2620   * @param  Tickstart : Tick start value\r
2621   * @param  Timeout : Duration of the timeout\r
2622   * @retval HAL status\r
2623   */\r
2624 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,\r
2625                                                         FlagStatus State, uint32_t Tickstart, uint32_t Timeout)\r
2626 {\r
2627   /* Wait until flag is in expected state */\r
2628   while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)\r
2629   {\r
2630     /* Check for the Timeout */\r
2631     if (Timeout != HAL_MAX_DELAY)\r
2632     {\r
2633       if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))\r
2634       {\r
2635         hqspi->State     = HAL_QSPI_STATE_ERROR;\r
2636         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;\r
2637 \r
2638         return HAL_ERROR;\r
2639       }\r
2640     }\r
2641   }\r
2642   return HAL_OK;\r
2643 }\r
2644 \r
2645 /**\r
2646   * @brief  Configure the communication registers.\r
2647   * @param  hqspi : QSPI handle\r
2648   * @param  cmd : structure that contains the command configuration information\r
2649   * @param  FunctionalMode : functional mode to configured\r
2650   *           This parameter can be one of the following values:\r
2651   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode\r
2652   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode\r
2653   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode\r
2654   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode\r
2655   * @retval None\r
2656   */\r
2657 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)\r
2658 {\r
2659   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));\r
2660 \r
2661   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))\r
2662   {\r
2663     /* Configure QSPI: DLR register with the number of data to read or write */\r
2664     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));\r
2665   }\r
2666 \r
2667   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)\r
2668   {\r
2669     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
2670     {\r
2671       /* Configure QSPI: ABR register with alternate bytes value */\r
2672       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);\r
2673 \r
2674       if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
2675       {\r
2676         /*---- Command with instruction, address and alternate bytes ----*/\r
2677         /* Configure QSPI: CCR register with all communications parameters */\r
2678         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2679                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2680                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |\r
2681                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |\r
2682                                          cmd->Instruction | FunctionalMode));\r
2683 \r
2684         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)\r
2685         {\r
2686           /* Configure QSPI: AR register with address value */\r
2687           WRITE_REG(hqspi->Instance->AR, cmd->Address);\r
2688         }\r
2689       }\r
2690       else\r
2691       {\r
2692         /*---- Command with instruction and alternate bytes ----*/\r
2693         /* Configure QSPI: CCR register with all communications parameters */\r
2694         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2695                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2696                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |\r
2697                                          cmd->AddressMode | cmd->InstructionMode |\r
2698                                          cmd->Instruction | FunctionalMode));\r
2699       }\r
2700     }\r
2701     else\r
2702     {\r
2703       if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
2704       {\r
2705         /*---- Command with instruction and address ----*/\r
2706         /* Configure QSPI: CCR register with all communications parameters */\r
2707         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2708                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2709                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |\r
2710                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));\r
2711 \r
2712         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)\r
2713         {\r
2714           /* Configure QSPI: AR register with address value */\r
2715           WRITE_REG(hqspi->Instance->AR, cmd->Address);\r
2716         }\r
2717       }\r
2718       else\r
2719       {\r
2720         /*---- Command with only instruction ----*/\r
2721         /* Configure QSPI: CCR register with all communications parameters */\r
2722         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2723                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2724                                          cmd->AlternateByteMode | cmd->AddressMode |\r
2725                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));\r
2726       }\r
2727     }\r
2728   }\r
2729   else\r
2730   {\r
2731     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)\r
2732     {\r
2733       /* Configure QSPI: ABR register with alternate bytes value */\r
2734       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);\r
2735 \r
2736       if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
2737       {\r
2738         /*---- Command with address and alternate bytes ----*/\r
2739         /* Configure QSPI: CCR register with all communications parameters */\r
2740         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2741                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2742                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |\r
2743                                          cmd->AddressSize | cmd->AddressMode |\r
2744                                          cmd->InstructionMode | FunctionalMode));\r
2745 \r
2746         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)\r
2747         {\r
2748           /* Configure QSPI: AR register with address value */\r
2749           WRITE_REG(hqspi->Instance->AR, cmd->Address);\r
2750         }\r
2751       }\r
2752       else\r
2753       {\r
2754         /*---- Command with only alternate bytes ----*/\r
2755         /* Configure QSPI: CCR register with all communications parameters */\r
2756         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2757                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2758                                          cmd->AlternateBytesSize | cmd->AlternateByteMode |\r
2759                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));\r
2760       }\r
2761     }\r
2762     else\r
2763     {\r
2764       if (cmd->AddressMode != QSPI_ADDRESS_NONE)\r
2765       {\r
2766         /*---- Command with only address ----*/\r
2767         /* Configure QSPI: CCR register with all communications parameters */\r
2768         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2769                                          cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2770                                          cmd->AlternateByteMode | cmd->AddressSize |\r
2771                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));\r
2772 \r
2773         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)\r
2774         {\r
2775           /* Configure QSPI: AR register with address value */\r
2776           WRITE_REG(hqspi->Instance->AR, cmd->Address);\r
2777         }\r
2778       }\r
2779       else\r
2780       {\r
2781         /*---- Command with only data phase ----*/\r
2782         if (cmd->DataMode != QSPI_DATA_NONE)\r
2783         {\r
2784           /* Configure QSPI: CCR register with all communications parameters */\r
2785           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |\r
2786                                            cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |\r
2787                                            cmd->AlternateByteMode | cmd->AddressMode |\r
2788                                            cmd->InstructionMode | FunctionalMode));\r
2789         }\r
2790       }\r
2791     }\r
2792   }\r
2793 }\r
2794 \r
2795 /**\r
2796   * @}\r
2797   */\r
2798 \r
2799 /**\r
2800   * @}\r
2801   */\r
2802 \r
2803 #endif /* HAL_QSPI_MODULE_ENABLED */\r
2804 /**\r
2805   * @}\r
2806   */\r
2807 \r
2808 /**\r
2809   * @}\r
2810   */\r
2811 \r
2812 #endif /* defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2) */\r
2813 \r
2814 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r