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