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