STM32F439xx HAL User Manual
stm32f4xx_hal_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_qspi.c
00004   * @author  MCD Application Team
00005   * @brief   QSPI HAL module driver.
00006   *          This file provides firmware functions to manage the following 
00007   *          functionalities of the QuadSPI interface (QSPI).
00008   *           + Initialization and de-initialization functions
00009   *           + Indirect functional mode management
00010   *           + Memory-mapped functional mode management
00011   *           + Auto-polling functional mode management
00012   *           + Interrupts and flags management
00013   *           + DMA channel configuration for indirect functional mode
00014   *           + Errors management and abort functionality
00015   *
00016   *
00017   @verbatim
00018  ===============================================================================
00019                         ##### How to use this driver #####
00020  ===============================================================================
00021   [..]
00022     *** Initialization ***
00023     ======================
00024     [..]
00025       (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
00026         (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
00027         (++) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
00028         (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
00029         (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
00030         (++) If interrupt mode is used, enable and configure QuadSPI global
00031             interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00032         (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel 
00033             with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), 
00034             link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure 
00035             DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
00036       (#) Configure the flash size, the clock prescaler, the fifo threshold, the
00037           clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
00038 
00039     *** Indirect functional mode ***
00040     ================================
00041     [..]
00042       (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT() 
00043           functions :
00044          (++) Instruction phase : the mode used and if present the instruction opcode.
00045          (++) Address phase : the mode used and if present the size and the address value.
00046          (++) Alternate-bytes phase : the mode used and if present the size and the alternate 
00047              bytes values.
00048          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00049          (++) Data phase : the mode used and if present the number of bytes.
00050          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 
00051              if activated.
00052          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00053       (#) If no data is required for the command, it is sent directly to the memory :
00054          (++) In polling mode, the output of the function is done when the transfer is complete.
00055          (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
00056       (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or 
00057           HAL_QSPI_Transmit_IT() after the command configuration :
00058          (++) In polling mode, the output of the function is done when the transfer is complete.
00059          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold 
00060              is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
00061          (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and 
00062              HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
00063       (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or 
00064           HAL_QSPI_Receive_IT() after the command configuration :
00065          (++) In polling mode, the output of the function is done when the transfer is complete.
00066          (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold 
00067              is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
00068          (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and 
00069              HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
00070 
00071     *** Auto-polling functional mode ***
00072     ====================================
00073     [..]
00074       (#) Configure the command sequence and the auto-polling functional mode using the 
00075           HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
00076          (++) Instruction phase : the mode used and if present the instruction opcode.
00077          (++) Address phase : the mode used and if present the size and the address value.
00078          (++) Alternate-bytes phase : the mode used and if present the size and the alternate 
00079              bytes values.
00080          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00081          (++) Data phase : the mode used.
00082          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 
00083              if activated.
00084          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00085          (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
00086              the polling interval and the automatic stop activation.
00087       (#) After the configuration :
00088          (++) In polling mode, the output of the function is done when the status match is reached. The
00089              automatic stop is activated to avoid an infinite loop.
00090          (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
00091 
00092     *** Memory-mapped functional mode ***
00093     =====================================
00094     [..]
00095       (#) Configure the command sequence and the memory-mapped functional mode using the 
00096           HAL_QSPI_MemoryMapped() functions :
00097          (++) Instruction phase : the mode used and if present the instruction opcode.
00098          (++) Address phase : the mode used and the size.
00099          (++) Alternate-bytes phase : the mode used and if present the size and the alternate 
00100              bytes values.
00101          (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
00102          (++) Data phase : the mode used.
00103          (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 
00104              if activated.
00105          (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
00106          (++) The timeout activation and the timeout period.
00107       (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on 
00108           the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
00109 
00110     *** Errors management and abort functionality ***
00111     ==================================================
00112     [..]
00113       (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
00114       (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and 
00115           flushes the fifo :
00116          (++) In polling mode, the output of the function is done when the transfer 
00117               complete bit is set and the busy bit cleared.
00118          (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when 
00119               the transfer complete bi is set.
00120 
00121     *** Control functions ***
00122     =========================
00123     [..]
00124       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
00125       (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
00126       (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
00127       (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold 
00128 
00129     *** Workarounds linked to Silicon Limitation ***
00130     ====================================================
00131     [..]
00132       (#) Workarounds Implemented inside HAL Driver
00133          (++) Extra data written in the FIFO at the end of a read transfer
00134 
00135   @endverbatim
00136   ******************************************************************************
00137   * @attention
00138   *
00139   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00140   *
00141   * Redistribution and use in source and binary forms, with or without modification,
00142   * are permitted provided that the following conditions are met:
00143   *   1. Redistributions of source code must retain the above copyright notice,
00144   *      this list of conditions and the following disclaimer.
00145   *   2. Redistributions in binary form must reproduce the above copyright notice,
00146   *      this list of conditions and the following disclaimer in the documentation
00147   *      and/or other materials provided with the distribution.
00148   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00149   *      may be used to endorse or promote products derived from this software
00150   *      without specific prior written permission.
00151   *
00152   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00153   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00154   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00155   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00156   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00157   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00158   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00159   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00160   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00161   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00162   *
00163   ******************************************************************************  
00164   */
00165 
00166 /* Includes ------------------------------------------------------------------*/
00167 #include "stm32f4xx_hal.h"
00168 
00169 /** @addtogroup STM32F4xx_HAL_Driver
00170   * @{
00171   */
00172 
00173 /** @defgroup QSPI QSPI
00174   * @brief QSPI HAL module driver
00175   * @{
00176   */
00177 #ifdef HAL_QSPI_MODULE_ENABLED
00178 
00179 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
00180     defined(STM32F412Rx) || defined(STM32F413xx) || defined(STM32F423xx)
00181     
00182 /* Private typedef -----------------------------------------------------------*/
00183 /* Private define ------------------------------------------------------------*/
00184 /** @addtogroup QSPI_Private_Constants 
00185   * @{
00186   */
00187 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U                     /*!<Indirect write mode*/
00188 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
00189 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
00190 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/
00191 /**
00192   * @}
00193   */
00194   
00195 /* Private macro -------------------------------------------------------------*/
00196 /** @addtogroup QSPI_Private_Macros QSPI Private Macros
00197   * @{
00198   */
00199 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
00200                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
00201                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
00202                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
00203 /**
00204   * @}
00205   */
00206                                          
00207 /* Private variables ---------------------------------------------------------*/
00208 /* Private function prototypes -----------------------------------------------*/
00209 /** @addtogroup QSPI_Private_Functions QSPI Private Functions
00210   * @{
00211   */
00212 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
00213 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
00214 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00215 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00216 static void QSPI_DMAError(DMA_HandleTypeDef *hdma); 
00217 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
00218 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t tickstart, uint32_t Timeout);
00219 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
00220 /**
00221   * @}
00222   */
00223   
00224 /* Exported functions ---------------------------------------------------------*/
00225 
00226 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
00227   * @{
00228   */
00229 
00230 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions 
00231   *  @brief    Initialization and Configuration functions 
00232   *
00233 @verbatim    
00234 ===============================================================================
00235             ##### Initialization and Configuration functions #####
00236  ===============================================================================
00237     [..]
00238     This subsection provides a set of functions allowing to :
00239       (+) Initialize the QuadSPI.
00240       (+) De-initialize the QuadSPI.
00241       
00242 @endverbatim
00243   * @{
00244   */
00245 
00246 /**
00247   * @brief Initializes the QSPI mode according to the specified parameters
00248   *        in the QSPI_InitTypeDef and creates the associated handle.
00249   * @param hqspi qspi handle
00250   * @retval HAL status
00251   */
00252 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
00253 {
00254   HAL_StatusTypeDef status = HAL_ERROR;
00255   uint32_t tickstart = HAL_GetTick();
00256   
00257   /* Check the QSPI handle allocation */
00258   if(hqspi == NULL)
00259   {
00260     return HAL_ERROR;
00261   }
00262 
00263   /* Check the parameters */
00264   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
00265   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
00266   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
00267   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
00268   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
00269   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
00270   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
00271   assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
00272 
00273   if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
00274   {
00275     assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
00276   }
00277   
00278   /* Process locked */
00279   __HAL_LOCK(hqspi);
00280     
00281   if(hqspi->State == HAL_QSPI_STATE_RESET)
00282   { 
00283     /* Allocate lock resource and initialize it */
00284     hqspi->Lock = HAL_UNLOCKED;
00285      
00286     /* Init the low level hardware : GPIO, CLOCK */
00287     HAL_QSPI_MspInit(hqspi);
00288              
00289     /* Configure the default timeout for the QSPI memory access */
00290     HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
00291   }
00292   
00293   /* Configure QSPI FIFO Threshold */
00294   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, ((hqspi->Init.FifoThreshold - 1U) << 8U));
00295 
00296   /* Wait till BUSY flag reset */
00297   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
00298 
00299   if(status == HAL_OK)
00300   {
00301                 
00302     /* Configure QSPI Clock Prescaler and Sample Shift */
00303     MODIFY_REG(hqspi->Instance->CR,(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM), ((hqspi->Init.ClockPrescaler << 24U)| hqspi->Init.SampleShifting | hqspi->Init.FlashID| hqspi->Init.DualFlash ));
00304         
00305     /* Configure QSPI Flash Size, CS High Time and Clock Mode */
00306     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE), 
00307                ((hqspi->Init.FlashSize << 16U) | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
00308     
00309     /* Enable the QSPI peripheral */
00310     __HAL_QSPI_ENABLE(hqspi);
00311   
00312     /* Set QSPI error code to none */
00313     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;  
00314 
00315     /* Initialize the QSPI state */
00316     hqspi->State = HAL_QSPI_STATE_READY;
00317   }
00318   
00319   /* Release Lock */
00320   __HAL_UNLOCK(hqspi);
00321 
00322   /* Return function status */
00323   return status;
00324 }
00325 
00326 /**
00327   * @brief DeInitializes the QSPI peripheral 
00328   * @param hqspi qspi handle
00329   * @retval HAL status
00330   */
00331 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
00332 {
00333   /* Check the QSPI handle allocation */
00334   if(hqspi == NULL)
00335   {
00336     return HAL_ERROR;
00337   }
00338 
00339   /* Process locked */
00340   __HAL_LOCK(hqspi);
00341 
00342   /* Disable the QSPI Peripheral Clock */
00343   __HAL_QSPI_DISABLE(hqspi);
00344 
00345   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00346   HAL_QSPI_MspDeInit(hqspi);
00347 
00348   /* Set QSPI error code to none */
00349   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00350 
00351   /* Initialize the QSPI state */
00352   hqspi->State = HAL_QSPI_STATE_RESET;
00353 
00354   /* Release Lock */
00355   __HAL_UNLOCK(hqspi);
00356 
00357   return HAL_OK;
00358 }
00359 
00360 /**
00361   * @brief QSPI MSP Init
00362   * @param hqspi QSPI handle
00363   * @retval None
00364   */
00365  __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
00366 {
00367   /* Prevent unused argument(s) compilation warning */
00368   UNUSED(hqspi);
00369   
00370   /* NOTE : This function should not be modified, when the callback is needed,
00371             the HAL_QSPI_MspInit can be implemented in the user file
00372    */ 
00373 }
00374 
00375 /**
00376   * @brief QSPI MSP DeInit
00377   * @param hqspi QSPI handle
00378   * @retval None
00379   */
00380  __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
00381 {
00382   /* Prevent unused argument(s) compilation warning */
00383   UNUSED(hqspi);
00384   
00385   /* NOTE : This function should not be modified, when the callback is needed,
00386             the HAL_QSPI_MspDeInit can be implemented in the user file
00387    */ 
00388 }
00389 
00390 /**
00391   * @}
00392   */
00393 
00394 /** @defgroup QSPI_Exported_Functions_Group2 IO operation functions 
00395   *  @brief QSPI Transmit/Receive functions 
00396   *
00397 @verbatim   
00398  ===============================================================================
00399                       ##### IO operation functions #####
00400  ===============================================================================
00401        [..]
00402     This subsection provides a set of functions allowing to :
00403       (+) Handle the interrupts.
00404       (+) Handle the command sequence.
00405       (+) Transmit data in blocking, interrupt or DMA mode.
00406       (+) Receive data in blocking, interrupt or DMA mode.
00407       (+) Manage the auto-polling functional mode.
00408       (+) Manage the memory-mapped functional mode.
00409 
00410 @endverbatim
00411   * @{
00412   */
00413 
00414 /**
00415   * @brief This function handles QSPI interrupt request.
00416   * @param hqspi QSPI handle
00417   * @retval None.
00418   */
00419 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
00420 {
00421   __IO uint32_t *data_reg;
00422   uint32_t flag = READ_REG(hqspi->Instance->SR);
00423   uint32_t itsource = READ_REG(hqspi->Instance->CR);
00424 
00425   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
00426   if(((flag & QSPI_FLAG_FT)!= RESET) && ((itsource & QSPI_IT_FT)!= RESET))
00427   {
00428     data_reg = &hqspi->Instance->DR;
00429 
00430     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00431     {
00432       /* Transmission process */
00433       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0U)
00434       {
00435         if (hqspi->TxXferCount > 0U)
00436         {
00437           /* Fill the FIFO until it is full */
00438           *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
00439           hqspi->TxXferCount--;
00440         }
00441         else
00442         {
00443           /* No more data available for the transfer */
00444           /* Disable the QSPI FIFO Threshold Interrupt */
00445           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
00446           break;
00447         }
00448       }
00449     }
00450     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00451     {
00452       /* Receiving Process */
00453       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0U)
00454       {
00455         if (hqspi->RxXferCount > 0U)
00456         {
00457           /* Read the FIFO until it is empty */
00458           *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00459           hqspi->RxXferCount--;
00460         }
00461         else
00462         {
00463           /* All data have been received for the transfer */
00464           /* Disable the QSPI FIFO Threshold Interrupt */
00465           __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
00466           break;
00467         }
00468       }
00469     }
00470     
00471     /* FIFO Threshold callback */
00472     HAL_QSPI_FifoThresholdCallback(hqspi);
00473   }
00474 
00475   /* QSPI Transfer Complete interrupt occurred -------------------------------*/
00476   else if(((flag & QSPI_FLAG_TC)!= RESET) && ((itsource & QSPI_IT_TC)!= RESET))
00477   {
00478     /* Clear interrupt */
00479     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
00480 
00481     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
00482     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00483     
00484     /* Transfer complete callback */
00485     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00486     {
00487       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
00488       {
00489         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00490         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00491         
00492         /* Disable the DMA channel */
00493         __HAL_DMA_DISABLE(hqspi->hdma);
00494       }
00495 
00496       /* Clear Busy bit */
00497       HAL_QSPI_Abort_IT(hqspi);
00498       
00499       /* Change state of QSPI */
00500       hqspi->State = HAL_QSPI_STATE_READY;
00501 
00502       /* TX Complete callback */
00503       HAL_QSPI_TxCpltCallback(hqspi);
00504     }
00505     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00506     {
00507       if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
00508       {
00509         /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00510         CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00511         
00512         /* Disable the DMA channel */
00513         __HAL_DMA_DISABLE(hqspi->hdma);
00514       }
00515       else
00516       {
00517         data_reg = &hqspi->Instance->DR;
00518         while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
00519         {
00520           if (hqspi->RxXferCount > 0U)
00521           {
00522             /* Read the last data received in the FIFO until it is empty */
00523             *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00524             hqspi->RxXferCount--;
00525           }
00526           else
00527           {
00528             /* All data have been received for the transfer */
00529             break;
00530           }
00531         }
00532       }
00533       /* Workaround - Extra data written in the FIFO at the end of a read transfer */
00534       HAL_QSPI_Abort_IT(hqspi);
00535       
00536       /* Change state of QSPI */
00537       hqspi->State = HAL_QSPI_STATE_READY;
00538 
00539       /* RX Complete callback */
00540       HAL_QSPI_RxCpltCallback(hqspi);
00541     }
00542     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
00543     {
00544       /* Change state of QSPI */
00545       hqspi->State = HAL_QSPI_STATE_READY;
00546 
00547       /* Command Complete callback */
00548       HAL_QSPI_CmdCpltCallback(hqspi);
00549     }
00550     else if(hqspi->State == HAL_QSPI_STATE_ABORT)
00551     {
00552       /* Change state of QSPI */
00553       hqspi->State = HAL_QSPI_STATE_READY;
00554 
00555       if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
00556       {
00557         /* Abort called by the user */
00558 
00559         /* Abort Complete callback */
00560         HAL_QSPI_AbortCpltCallback(hqspi);
00561       }
00562       else 
00563       {
00564         /* Abort due to an error (eg :  DMA error) */
00565 
00566         /* Error callback */
00567         HAL_QSPI_ErrorCallback(hqspi);
00568       }
00569     }
00570   }
00571 
00572   /* QSPI Status Match interrupt occurred ------------------------------------*/
00573   else if(((flag & QSPI_FLAG_SM)!= RESET) && ((itsource & QSPI_IT_SM)!= RESET))
00574   {
00575     /* Clear interrupt */
00576     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
00577    
00578     /* Check if the automatic poll mode stop is activated */
00579     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
00580     {
00581       /* Disable the QSPI Transfer Error and Status Match Interrupts */
00582       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
00583 
00584       /* Change state of QSPI */
00585       hqspi->State = HAL_QSPI_STATE_READY;
00586     }
00587 
00588     /* Status match callback */
00589     HAL_QSPI_StatusMatchCallback(hqspi);
00590   }
00591 
00592   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
00593   else if(((flag & QSPI_FLAG_TE)!= RESET) && ((itsource & QSPI_IT_TE)!= RESET))
00594   {
00595     /* Clear interrupt */
00596     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
00597     
00598     /* Disable all the QSPI Interrupts */
00599     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00600 
00601     /* Set error code */
00602     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
00603     
00604     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
00605     {
00606       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
00607       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
00608       
00609       /* Disable the DMA channel */
00610       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
00611       HAL_DMA_Abort_IT(hqspi->hdma);
00612     }
00613     else
00614     {
00615       /* Change state of QSPI */
00616       hqspi->State = HAL_QSPI_STATE_READY;
00617       
00618       /* Error callback */
00619       HAL_QSPI_ErrorCallback(hqspi);
00620     }
00621   }
00622 
00623   /* QSPI Timeout interrupt occurred -----------------------------------------*/
00624   else if(((flag & QSPI_FLAG_TO)!= RESET) && ((itsource & QSPI_IT_TO)!= RESET))
00625   {
00626     /* Clear interrupt */
00627     WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
00628     
00629     /* Time out callback */
00630     HAL_QSPI_TimeOutCallback(hqspi);
00631   }
00632 }
00633 
00634 /**
00635   * @brief Sets the command configuration. 
00636   * @param hqspi QSPI handle
00637   * @param cmd  structure that contains the command configuration information
00638   * @param Timeout  Time out duration
00639   * @note   This function is used only in Indirect Read or Write Modes
00640   * @retval HAL status
00641   */
00642 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
00643 {
00644   HAL_StatusTypeDef status = HAL_ERROR;
00645   uint32_t tickstart = HAL_GetTick();
00646   
00647   /* Check the parameters */
00648   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00649   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00650   {
00651     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00652   }
00653 
00654   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00655   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00656   {
00657     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00658   }
00659 
00660   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00661   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00662   {
00663     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00664   }
00665 
00666   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00667   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00668 
00669   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00670   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00671   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00672   
00673   /* Process locked */
00674   __HAL_LOCK(hqspi);
00675 
00676   if(hqspi->State == HAL_QSPI_STATE_READY)
00677   {
00678     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00679     
00680     /* Update QSPI state */
00681     hqspi->State = HAL_QSPI_STATE_BUSY;   
00682     
00683     /* Wait till BUSY flag reset */
00684     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
00685     
00686     if (status == HAL_OK)
00687     {
00688       /* Call the configuration function */
00689       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00690       
00691       if (cmd->DataMode == QSPI_DATA_NONE)
00692       {
00693         /* When there is no data phase, the transfer start as soon as the configuration is done 
00694         so wait until TC flag is set to go back in idle state */
00695         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
00696 
00697         if (status == HAL_OK)
00698         {
00699           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00700           
00701           /* Update QSPI state */
00702           hqspi->State = HAL_QSPI_STATE_READY;   
00703         }
00704         
00705       }
00706       else
00707       {
00708         /* Update QSPI state */
00709         hqspi->State = HAL_QSPI_STATE_READY;   
00710       }
00711     }
00712   }
00713   else
00714   {
00715     status = HAL_BUSY;   
00716   }
00717   
00718   /* Process unlocked */
00719   __HAL_UNLOCK(hqspi);
00720 
00721   /* Return function status */
00722   return status;
00723 }
00724 
00725 /**
00726   * @brief Sets the command configuration in interrupt mode. 
00727   * @param hqspi QSPI handle
00728   * @param cmd  structure that contains the command configuration information
00729   * @note   This function is used only in Indirect Read or Write Modes
00730   * @retval HAL status
00731   */
00732 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
00733 {
00734   __IO uint32_t count = 0U;
00735   HAL_StatusTypeDef status = HAL_OK;
00736   
00737   /* Check the parameters */
00738   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00739   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00740   {
00741     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00742   }
00743 
00744   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00745   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00746   {
00747     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00748   }
00749 
00750   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00751   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00752   {
00753     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00754   }
00755 
00756   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00757   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00758 
00759   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00760   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00761   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00762   
00763   /* Process locked */
00764   __HAL_LOCK(hqspi);
00765 
00766   if(hqspi->State == HAL_QSPI_STATE_READY)
00767   {
00768     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00769     
00770     /* Update QSPI state */
00771     hqspi->State = HAL_QSPI_STATE_BUSY;   
00772     
00773     /* Wait till BUSY flag reset */
00774    count = (hqspi->Timeout) * (SystemCoreClock / 16U / 1000U);
00775    do 
00776    {
00777      if (count-- == 0U)
00778      { 
00779         hqspi->State     = HAL_QSPI_STATE_ERROR;
00780         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
00781         status = HAL_TIMEOUT;
00782      }
00783    } 
00784    while ((__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY)) != RESET);
00785    
00786     if (status == HAL_OK)
00787     {
00788       if (cmd->DataMode == QSPI_DATA_NONE)
00789       {
00790         /* Clear interrupt */
00791         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
00792       }
00793       
00794       /* Call the configuration function */
00795       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00796       
00797       if (cmd->DataMode == QSPI_DATA_NONE)
00798       {
00799         /* When there is no data phase, the transfer start as soon as the configuration is done 
00800         so activate TC and TE interrupts */
00801         /* Process unlocked */
00802         __HAL_UNLOCK(hqspi);
00803 
00804         /* Enable the QSPI Transfer Error Interrupt */
00805         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
00806       }
00807       else
00808       {
00809         /* Update QSPI state */
00810         hqspi->State = HAL_QSPI_STATE_READY;   
00811 
00812         /* Process unlocked */
00813         __HAL_UNLOCK(hqspi);
00814       }
00815     }
00816     else
00817     {
00818       /* Process unlocked */
00819       __HAL_UNLOCK(hqspi);
00820     }
00821   }
00822   else
00823   {
00824     status = HAL_BUSY;   
00825 
00826     /* Process unlocked */
00827     __HAL_UNLOCK(hqspi);
00828   }
00829   
00830   /* Return function status */
00831   return status;
00832 }
00833 
00834 /**
00835   * @brief Transmit an amount of data in blocking mode. 
00836   * @param hqspi QSPI handle
00837   * @param pData pointer to data buffer
00838   * @param Timeout  Time out duration
00839   * @note   This function is used only in Indirect Write Mode
00840   * @retval HAL status
00841   */
00842 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
00843 {
00844    HAL_StatusTypeDef status = HAL_OK;
00845   uint32_t tickstart = HAL_GetTick();
00846   __IO uint32_t *data_reg = &hqspi->Instance->DR;
00847 
00848   /* Process locked */
00849   __HAL_LOCK(hqspi);
00850 
00851   if(hqspi->State == HAL_QSPI_STATE_READY)
00852   {
00853     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00854 
00855     if(pData != NULL )
00856     {
00857       /* Update state */
00858       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
00859       
00860       /* Configure counters and size of the handle */
00861       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
00862       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
00863       hqspi->pTxBuffPtr = pData;
00864     
00865       /* Configure QSPI: CCR register with functional as indirect write */
00866       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00867 
00868       while(hqspi->TxXferCount > 0U)
00869       {
00870         /* Wait until FT flag is set to send data */
00871         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
00872 
00873         if (status != HAL_OK)
00874         { 
00875           break;
00876         }
00877 
00878         *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
00879         hqspi->TxXferCount--;
00880       }
00881     
00882       if (status == HAL_OK)
00883       {
00884         /* Wait until TC flag is set to go back in idle state */
00885         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
00886 
00887         if (status == HAL_OK)
00888         {
00889           /* Clear Transfer Complete bit */
00890           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00891           
00892           /* Clear Busy bit */
00893           status = HAL_QSPI_Abort(hqspi);
00894         }
00895       }
00896     
00897       /* Update QSPI state */
00898       hqspi->State = HAL_QSPI_STATE_READY;    
00899     }
00900     else
00901     {
00902       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
00903       status = HAL_ERROR;
00904     }
00905   }
00906   else
00907   {
00908     status = HAL_BUSY;
00909   }
00910 
00911   /* Process unlocked */
00912   __HAL_UNLOCK(hqspi);
00913 
00914   return status;
00915 }
00916 
00917 
00918 /**
00919   * @brief Receive an amount of data in blocking mode 
00920   * @param hqspi QSPI handle
00921   * @param pData pointer to data buffer
00922   * @param Timeout  Time out duration
00923   * @note   This function is used only in Indirect Read Mode
00924   * @retval HAL status
00925   */
00926 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
00927 {
00928   HAL_StatusTypeDef status = HAL_OK;
00929   uint32_t tickstart = HAL_GetTick();
00930   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
00931   __IO uint32_t *data_reg = &hqspi->Instance->DR;
00932 
00933   /* Process locked */
00934   __HAL_LOCK(hqspi);
00935   
00936   if(hqspi->State == HAL_QSPI_STATE_READY)
00937   {
00938     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00939     if(pData != NULL )
00940     {
00941       /* Update state */
00942       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
00943     
00944       /* Configure counters and size of the handle */
00945       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
00946       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
00947       hqspi->pRxBuffPtr = pData;
00948 
00949       /* Configure QSPI: CCR register with functional as indirect read */
00950       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
00951 
00952       /* Start the transfer by re-writing the address in AR register */
00953       WRITE_REG(hqspi->Instance->AR, addr_reg);
00954       
00955       while(hqspi->RxXferCount > 0U)
00956       {
00957         /* Wait until FT or TC flag is set to read received data */
00958         status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
00959 
00960         if  (status != HAL_OK)
00961         { 
00962           break;
00963         }
00964 
00965         *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00966         hqspi->RxXferCount--;
00967       }
00968     
00969       if (status == HAL_OK)
00970       {
00971         /* Wait until TC flag is set to go back in idle state */
00972         status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
00973 
00974         if  (status == HAL_OK)
00975         {
00976           /* Clear Transfer Complete bit */
00977           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00978           
00979          /* Workaround - Extra data written in the FIFO at the end of a read transfer */
00980          status = HAL_QSPI_Abort(hqspi);
00981         }
00982       }
00983 
00984       /* Update QSPI state */
00985       hqspi->State = HAL_QSPI_STATE_READY;    
00986     }
00987     else
00988     {
00989       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
00990       status = HAL_ERROR;
00991     }
00992   }
00993   else
00994   {
00995     status = HAL_BUSY;
00996   }
00997   
00998   /* Process unlocked */
00999   __HAL_UNLOCK(hqspi);
01000 
01001   return status;
01002 }
01003 
01004 /**
01005   * @brief  Send an amount of data in interrupt mode 
01006   * @param  hqspi QSPI handle
01007   * @param  pData pointer to data buffer
01008   * @note   This function is used only in Indirect Write Mode
01009   * @retval HAL status
01010   */
01011 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01012 {  
01013   HAL_StatusTypeDef status = HAL_OK;
01014   
01015   /* Process locked */
01016   __HAL_LOCK(hqspi);
01017 
01018   if(hqspi->State == HAL_QSPI_STATE_READY)
01019   {
01020     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01021     if(pData != NULL )
01022     {
01023       /* Update state */
01024       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
01025 
01026       /* Configure counters and size of the handle */
01027       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01028       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01029       hqspi->pTxBuffPtr = pData;
01030     
01031       /* Configure QSPI: CCR register with functional as indirect write */
01032       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01033     
01034       /* Clear interrupt */
01035       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
01036 
01037       /* Process unlocked */
01038       __HAL_UNLOCK(hqspi);
01039       
01040       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
01041       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
01042       
01043     }
01044     else
01045     {
01046       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01047       status = HAL_ERROR;
01048 
01049       /* Process unlocked */
01050       __HAL_UNLOCK(hqspi);
01051     }
01052   }
01053   else
01054   {
01055     status = HAL_BUSY;
01056 
01057     /* Process unlocked */
01058     __HAL_UNLOCK(hqspi);
01059   }
01060 
01061   return status;
01062 }
01063 
01064 /**
01065   * @brief  Receive an amount of data in no-blocking mode with Interrupt
01066   * @param  hqspi QSPI handle
01067   * @param  pData pointer to data buffer
01068   * @note   This function is used only in Indirect Read Mode
01069   * @retval HAL status
01070   */
01071 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01072 {
01073   HAL_StatusTypeDef status = HAL_OK;
01074   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01075   
01076   /* Process locked */
01077   __HAL_LOCK(hqspi);
01078 
01079   if(hqspi->State == HAL_QSPI_STATE_READY)
01080   {
01081     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01082     
01083     if(pData != NULL )
01084     {
01085       /* Update state */
01086       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01087     
01088       /* Configure counters and size of the handle */
01089       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
01090       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
01091       hqspi->pRxBuffPtr = pData;
01092 
01093       /* Configure QSPI: CCR register with functional as indirect read */
01094       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01095 
01096       /* Start the transfer by re-writing the address in AR register */
01097       WRITE_REG(hqspi->Instance->AR, addr_reg);
01098 
01099       /* Clear interrupt */
01100       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
01101 
01102       /* Process unlocked */
01103       __HAL_UNLOCK(hqspi);
01104 
01105       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
01106       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
01107     }
01108     else
01109     {
01110       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01111       status = HAL_ERROR;
01112 
01113       /* Process unlocked */
01114       __HAL_UNLOCK(hqspi);
01115     }
01116   }
01117   else
01118   {
01119     status = HAL_BUSY;   
01120 
01121     /* Process unlocked */
01122     __HAL_UNLOCK(hqspi);
01123   }
01124 
01125   return status;
01126 }
01127 
01128 /**
01129   * @brief  Sends an amount of data in non blocking mode with DMA. 
01130   * @param  hqspi QSPI handle
01131   * @param  pData pointer to data buffer
01132   * @note   This function is used only in Indirect Write Mode
01133   * @note   If DMA peripheral access is configured as halfword, the number 
01134   *         of data and the fifo threshold should be aligned on halfword
01135   * @note   If DMA peripheral access is configured as word, the number 
01136   *         of data and the fifo threshold should be aligned on word
01137   * @retval HAL status
01138   */
01139 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01140 {
01141   HAL_StatusTypeDef status = HAL_OK;
01142   uint32_t *tmp;
01143   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
01144 
01145   /* Process locked */
01146   __HAL_LOCK(hqspi);
01147 
01148   if(hqspi->State == HAL_QSPI_STATE_READY)
01149   {
01150     /* Clear the error code */                
01151     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01152 
01153     if(pData != NULL ) 
01154     {
01155       /* Configure counters of the handle */
01156       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
01157       {
01158         hqspi->TxXferCount = data_size;
01159       }
01160       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
01161       {
01162         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
01163         {
01164           /* The number of data or the fifo threshold is not aligned on halfword 
01165           => no transfer possible with DMA peripheral access configured as halfword */
01166           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01167           status = HAL_ERROR;
01168 
01169           /* Process unlocked */
01170           __HAL_UNLOCK(hqspi);
01171         }
01172         else
01173         {
01174           hqspi->TxXferCount = (data_size >> 1);
01175         }
01176       }
01177       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
01178       {
01179         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
01180         {
01181           /* The number of data or the fifo threshold is not aligned on word 
01182           => no transfer possible with DMA peripheral access configured as word */
01183           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01184           status = HAL_ERROR;
01185 
01186           /* Process unlocked */
01187           __HAL_UNLOCK(hqspi);
01188         }
01189         else
01190         {
01191           hqspi->TxXferCount = (data_size >> 2U);
01192         }
01193       }
01194 
01195       if (status == HAL_OK)
01196       {
01197       /* Update state */
01198       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
01199 
01200       /* Clear interrupt */
01201       __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
01202 
01203       /* Configure size and pointer of the handle */
01204       hqspi->TxXferSize = hqspi->TxXferCount;
01205       hqspi->pTxBuffPtr = pData;
01206 
01207       /* Configure QSPI: CCR register with functional mode as indirect write */
01208       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01209 
01210       /* Set the QSPI DMA transfer complete callback */
01211       hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
01212 
01213       /* Set the QSPI DMA Half transfer complete callback */
01214       hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
01215 
01216       /* Set the DMA error callback */
01217       hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01218 
01219       /* Clear the DMA abort callback */
01220       hqspi->hdma->XferAbortCallback = NULL;
01221 
01222 #if defined (QSPI1_V2_1L)
01223       /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
01224          AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
01225          Change the following configuration of DMA peripheral
01226            - Enable peripheral increment
01227            - Disable memory increment
01228            - Set DMA direction as peripheral to memory mode */
01229 
01230         /* Enable peripheral increment mode of the DMA */
01231         hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
01232 
01233         /* Disable memory increment mode of the DMA */
01234         hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
01235         
01236         /* Update peripheral/memory increment mode bits */
01237         MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
01238 
01239         /* Configure the direction of the DMA */
01240         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
01241 #else        
01242       /* Configure the direction of the DMA */
01243       hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
01244 #endif /* QSPI1_V2_1L */
01245 
01246       /* Update direction mode bit */
01247       MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
01248 
01249       /* Enable the QSPI transmit DMA Channel */
01250       tmp = (uint32_t*)&pData;
01251       HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize);
01252 
01253       /* Process unlocked */
01254       __HAL_UNLOCK(hqspi);
01255 
01256       /* Enable the QSPI transfer error Interrupt */
01257       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
01258 
01259       /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01260       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01261       }
01262     }
01263     else
01264     {
01265       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01266 
01267       status = HAL_ERROR;
01268 
01269       /* Process unlocked */
01270       __HAL_UNLOCK(hqspi);
01271     }
01272   }
01273   else
01274   {
01275     status = HAL_BUSY;   
01276 
01277     /* Process unlocked */
01278     __HAL_UNLOCK(hqspi);
01279   }
01280 
01281   return status;
01282 }
01283 
01284 /**
01285   * @brief  Receives an amount of data in non blocking mode with DMA. 
01286   * @param  hqspi QSPI handle
01287   * @param  pData pointer to data buffer.
01288   * @note   This function is used only in Indirect Read Mode
01289   * @note   If DMA peripheral access is configured as halfword, the number 
01290   *         of data and the fifo threshold should be aligned on halfword
01291   * @note   If DMA peripheral access is configured as word, the number 
01292   *         of data and the fifo threshold should be aligned on word
01293   * @retval HAL status
01294   */
01295 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01296 {
01297   HAL_StatusTypeDef status = HAL_OK;
01298   uint32_t *tmp;
01299   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01300   uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
01301 
01302   /* Process locked */
01303   __HAL_LOCK(hqspi);
01304 
01305   if(hqspi->State == HAL_QSPI_STATE_READY)
01306   {
01307     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01308 
01309     if(pData != NULL ) 
01310     {
01311       /* Configure counters of the handle */
01312       if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
01313       {
01314         hqspi->RxXferCount = data_size;
01315       }
01316       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
01317       {
01318         if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
01319         {
01320           /* The number of data or the fifo threshold is not aligned on halfword 
01321           => no transfer possible with DMA peripheral access configured as halfword */
01322           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01323           status = HAL_ERROR;
01324 
01325           /* Process unlocked */
01326           __HAL_UNLOCK(hqspi);
01327         }
01328         else
01329         {
01330           hqspi->RxXferCount = (data_size >> 1U);
01331         }
01332       }
01333       else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
01334       {
01335         if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
01336         {
01337           /* The number of data or the fifo threshold is not aligned on word 
01338           => no transfer possible with DMA peripheral access configured as word */
01339           hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01340           status = HAL_ERROR;
01341 
01342           /* Process unlocked */
01343           __HAL_UNLOCK(hqspi);
01344         }
01345         else
01346         {
01347           hqspi->RxXferCount = (data_size >> 2U);
01348         }
01349       }
01350 
01351       if (status == HAL_OK)
01352       {
01353         /* Update state */
01354         hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01355 
01356         /* Clear interrupt */
01357         __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
01358 
01359         /* Configure size and pointer of the handle */
01360         hqspi->RxXferSize = hqspi->RxXferCount;
01361         hqspi->pRxBuffPtr = pData;
01362 
01363         /* Set the QSPI DMA transfer complete callback */
01364         hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
01365 
01366         /* Set the QSPI DMA Half transfer complete callback */
01367         hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
01368 
01369         /* Set the DMA error callback */
01370         hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01371 
01372         /* Clear the DMA abort callback */
01373         hqspi->hdma->XferAbortCallback = NULL;
01374 
01375 #if defined (QSPI1_V2_1L)
01376       /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
01377          AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
01378          Change the following configuration of DMA peripheral
01379            - Enable peripheral increment
01380            - Disable memory increment
01381            - Set DMA direction as memory to peripheral mode
01382            - 4 Extra words (32-bits) are added for read operation to guarantee
01383               the last data is transferred from DMA FIFO to RAM memory */
01384 
01385         /* Enable peripheral increment of the DMA */
01386         hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
01387 
01388         /* Disable memory increment of the DMA */
01389         hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
01390 
01391         /* Update peripheral/memory increment mode bits */
01392         MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
01393 
01394         /* Configure the direction of the DMA */
01395         hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
01396 
01397         /* 4 Extra words (32-bits) are needed for read operation to guarantee 
01398         the last data is transferred from DMA FIFO to RAM memory */
01399         WRITE_REG(hqspi->Instance->DLR, (data_size - 1U + 16U));
01400 
01401                 /* Update direction mode bit */
01402         MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
01403 
01404         /* Configure QSPI: CCR register with functional as indirect read */
01405         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01406 
01407         /* Start the transfer by re-writing the address in AR register */
01408         WRITE_REG(hqspi->Instance->AR, addr_reg);
01409 
01410         /* Enable the DMA Channel */
01411         tmp = (uint32_t*)&pData;
01412         HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
01413 
01414         /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01415         SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01416 
01417         /* Process unlocked */
01418         __HAL_UNLOCK(hqspi);
01419 
01420         /* Enable the QSPI transfer error Interrupt */
01421         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
01422 #else
01423         /* Configure the direction of the DMA */
01424         hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
01425 
01426                 MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
01427 
01428         /* Enable the DMA Channel */
01429         tmp = (uint32_t*)&pData;
01430         HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
01431 
01432         /* Configure QSPI: CCR register with functional as indirect read */
01433         MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01434 
01435         /* Start the transfer by re-writing the address in AR register */
01436         WRITE_REG(hqspi->Instance->AR, addr_reg);
01437 
01438         /* Process unlocked */
01439         __HAL_UNLOCK(hqspi);
01440 
01441         /* Enable the QSPI transfer error Interrupt */
01442         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
01443 
01444         /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01445         SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01446 #endif /* QSPI1_V2_1L */
01447       }
01448     }
01449     else
01450     {
01451       hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
01452       status = HAL_ERROR;
01453 
01454       /* Process unlocked */
01455       __HAL_UNLOCK(hqspi);
01456     }
01457   }
01458   else
01459   {
01460     status = HAL_BUSY; 
01461 
01462     /* Process unlocked */
01463     __HAL_UNLOCK(hqspi);
01464   }
01465 
01466   return status;
01467 }
01468 
01469 /**
01470   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode. 
01471   * @param  hqspi QSPI handle
01472   * @param  cmd structure that contains the command configuration information.
01473   * @param  cfg structure that contains the polling configuration information.
01474   * @param  Timeout  Time out duration
01475   * @note   This function is used only in Automatic Polling Mode
01476   * @retval HAL status
01477   */
01478 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
01479 {
01480   HAL_StatusTypeDef status = HAL_ERROR;
01481   uint32_t tickstart = HAL_GetTick();
01482   
01483   /* Check the parameters */
01484   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01485   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01486   {
01487     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01488   }
01489   
01490   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01491   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01492   {
01493     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01494   }
01495   
01496   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01497   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01498   {
01499     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01500   }
01501   
01502   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01503   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01504   
01505   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01506   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01507   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01508   
01509   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01510   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01511   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01512   
01513   /* Process locked */
01514   __HAL_LOCK(hqspi);
01515   
01516   if(hqspi->State == HAL_QSPI_STATE_READY)
01517   {
01518     
01519     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01520     
01521     /* Update state */
01522     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01523     
01524     /* Wait till BUSY flag reset */
01525     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
01526     
01527     if (status == HAL_OK)
01528     {
01529       /* Configure QSPI: PSMAR register with the status match value */
01530       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01531       
01532       /* Configure QSPI: PSMKR register with the status mask value */
01533       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01534       
01535       /* Configure QSPI: PIR register with the interval value */
01536       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01537       
01538       /* Configure QSPI: CR register with Match mode and Automatic stop enabled 
01539       (otherwise there will be an infinite loop in blocking mode) */
01540       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 
01541                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
01542       
01543       /* Call the configuration function */
01544       cmd->NbData = cfg->StatusBytesSize;
01545       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01546       
01547       /* Wait until SM flag is set to go back in idle state */
01548       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
01549 
01550       if (status == HAL_OK)
01551       {
01552         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
01553         
01554         /* Update state */
01555         hqspi->State = HAL_QSPI_STATE_READY;
01556       }
01557     }
01558   }
01559   else
01560   {
01561     status = HAL_BUSY;   
01562   }
01563   /* Process unlocked */
01564   __HAL_UNLOCK(hqspi);
01565   
01566   /* Return function status */
01567   return status;  
01568 }
01569 
01570 /**
01571   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode. 
01572   * @param  hqspi QSPI handle
01573   * @param  cmd structure that contains the command configuration information.
01574   * @param  cfg structure that contains the polling configuration information.
01575   * @note   This function is used only in Automatic Polling Mode
01576   * @retval HAL status
01577   */
01578 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
01579 {
01580   __IO uint32_t count = 0U;
01581   HAL_StatusTypeDef status = HAL_OK;
01582   
01583   /* Check the parameters */
01584   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01585   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01586   {
01587     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01588   }
01589   
01590   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01591   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01592   {
01593     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01594   }
01595   
01596   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01597   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01598   {
01599     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01600   }
01601   
01602   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01603   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01604   
01605   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01606   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01607   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01608   
01609   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01610   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01611   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01612   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
01613   
01614   /* Process locked */
01615   __HAL_LOCK(hqspi);
01616   
01617   if(hqspi->State == HAL_QSPI_STATE_READY)
01618   {
01619     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01620     
01621     /* Update state */
01622     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01623 
01624     /* Wait till BUSY flag reset */
01625     count = (hqspi->Timeout) * (SystemCoreClock / 16U / 1000U);
01626     do 
01627     {
01628       if (count-- == 0U)
01629       { 
01630         hqspi->State     = HAL_QSPI_STATE_ERROR;
01631         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
01632         status = HAL_TIMEOUT;
01633       }
01634     } 
01635     while ((__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_BUSY)) != RESET);
01636     
01637     if (status == HAL_OK)
01638     {
01639       /* Configure QSPI: PSMAR register with the status match value */
01640       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01641       
01642       /* Configure QSPI: PSMKR register with the status mask value */
01643       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01644       
01645       /* Configure QSPI: PIR register with the interval value */
01646       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01647       
01648       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
01649       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 
01650                (cfg->MatchMode | cfg->AutomaticStop));
01651       
01652       /* Clear interrupt */
01653       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
01654       
01655       /* Call the configuration function */
01656       cmd->NbData = cfg->StatusBytesSize;
01657       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01658 
01659       /* Process unlocked */
01660       __HAL_UNLOCK(hqspi);
01661   
01662       /* Enable the QSPI Transfer Error and status match Interrupt */
01663       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
01664 
01665     }
01666     else
01667     {
01668       /* Process unlocked */
01669       __HAL_UNLOCK(hqspi);
01670     }
01671   }
01672   else
01673   {
01674     status = HAL_BUSY;   
01675 
01676     /* Process unlocked */
01677     __HAL_UNLOCK(hqspi);
01678   }
01679   
01680   /* Return function status */
01681   return status;  
01682 }
01683 
01684 /**
01685   * @brief  Configure the Memory Mapped mode. 
01686   * @param  hqspi QSPI handle
01687   * @param  cmd structure that contains the command configuration information.
01688   * @param  cfg structure that contains the memory mapped configuration information.
01689   * @note   This function is used only in Memory mapped Mode
01690   * @retval HAL status
01691   */
01692 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
01693 {
01694   HAL_StatusTypeDef status = HAL_ERROR;
01695   uint32_t tickstart = HAL_GetTick();
01696   
01697   /* Check the parameters */
01698   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01699   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01700   {
01701   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01702   }
01703 
01704   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01705   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01706   {
01707     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01708   }
01709 
01710   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01711   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01712   {
01713     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01714   }
01715 
01716   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01717   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01718 
01719   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01720   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01721   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01722 
01723   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
01724   
01725   /* Process locked */
01726   __HAL_LOCK(hqspi);
01727   
01728   if(hqspi->State == HAL_QSPI_STATE_READY)
01729   {
01730     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01731     
01732     /* Update state */
01733     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
01734     
01735     /* Wait till BUSY flag reset */
01736     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
01737     
01738     if (status == HAL_OK)
01739     {
01740       /* Configure QSPI: CR register with timeout counter enable */
01741     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
01742 
01743     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
01744       {
01745         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
01746         
01747         /* Configure QSPI: LPTR register with the low-power timeout value */
01748         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
01749         
01750         /* Clear interrupt */
01751         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
01752 
01753         /* Enable the QSPI TimeOut Interrupt */
01754         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
01755       }
01756       
01757       /* Call the configuration function */
01758       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
01759     }
01760   }
01761   else
01762   {
01763     status = HAL_BUSY;   
01764   }
01765 
01766   /* Process unlocked */
01767   __HAL_UNLOCK(hqspi);
01768   
01769   /* Return function status */
01770   return status;  
01771 }
01772 
01773 /**
01774   * @brief  Transfer Error callbacks
01775   * @param  hqspi QSPI handle
01776   * @retval None
01777   */
01778 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
01779 {
01780   /* Prevent unused argument(s) compilation warning */
01781   UNUSED(hqspi);
01782   
01783   /* NOTE : This function Should not be modified, when the callback is needed,
01784             the HAL_QSPI_ErrorCallback could be implemented in the user file
01785    */
01786 }
01787 
01788 /**
01789   * @brief  Abort completed callback.
01790   * @param  hqspi QSPI handle
01791   * @retval None
01792   */
01793 __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
01794 {
01795   /* Prevent unused argument(s) compilation warning */
01796   UNUSED(hqspi);
01797 
01798   /* NOTE: This function should not be modified, when the callback is needed,
01799            the HAL_QSPI_AbortCpltCallback could be implemented in the user file
01800    */
01801 }
01802 
01803 /**
01804   * @brief  Command completed callback.
01805   * @param  hqspi QSPI handle
01806   * @retval None
01807   */
01808 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
01809 {
01810   /* Prevent unused argument(s) compilation warning */
01811   UNUSED(hqspi);
01812   
01813   /* NOTE: This function Should not be modified, when the callback is needed,
01814            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
01815    */
01816 }
01817 
01818 /**
01819   * @brief  Rx Transfer completed callbacks.
01820   * @param  hqspi QSPI handle
01821   * @retval None
01822   */
01823 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
01824 {
01825   /* Prevent unused argument(s) compilation warning */
01826   UNUSED(hqspi);
01827   
01828   /* NOTE: This function Should not be modified, when the callback is needed,
01829            the HAL_QSPI_RxCpltCallback could be implemented in the user file
01830    */
01831 }
01832 
01833 /**
01834   * @brief  Tx Transfer completed callbacks.
01835   * @param  hqspi QSPI handle
01836   * @retval None
01837   */
01838  __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
01839 {
01840   /* Prevent unused argument(s) compilation warning */
01841   UNUSED(hqspi);
01842   
01843   /* NOTE: This function Should not be modified, when the callback is needed,
01844            the HAL_QSPI_TxCpltCallback could be implemented in the user file
01845    */ 
01846 }
01847 
01848 /**
01849   * @brief  Rx Half Transfer completed callbacks.
01850   * @param  hqspi QSPI handle
01851   * @retval None
01852   */
01853 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01854 {
01855   /* Prevent unused argument(s) compilation warning */
01856   UNUSED(hqspi);
01857   
01858   /* NOTE: This function Should not be modified, when the callback is needed,
01859            the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
01860    */
01861 }
01862 
01863 /**
01864   * @brief  Tx Half Transfer completed callbacks.
01865   * @param  hqspi QSPI handle
01866   * @retval None
01867   */
01868  __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01869 {
01870   /* Prevent unused argument(s) compilation warning */
01871   UNUSED(hqspi);
01872   
01873   /* NOTE: This function Should not be modified, when the callback is needed,
01874            the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
01875    */ 
01876 }
01877 
01878 /**
01879   * @brief  FIFO Threshold callbacks
01880   * @param  hqspi QSPI handle
01881   * @retval None
01882   */
01883 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
01884 {
01885   /* Prevent unused argument(s) compilation warning */
01886   UNUSED(hqspi);
01887   
01888   /* NOTE : This function Should not be modified, when the callback is needed,
01889             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
01890    */
01891 }
01892 
01893 /**
01894   * @brief  Status Match callbacks
01895   * @param  hqspi QSPI handle
01896   * @retval None
01897   */
01898 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
01899 {
01900   /* Prevent unused argument(s) compilation warning */
01901   UNUSED(hqspi);
01902     
01903   /* NOTE : This function Should not be modified, when the callback is needed,
01904             the HAL_QSPI_StatusMatchCallback could be implemented in the user file
01905    */
01906 }
01907 
01908 /**
01909   * @brief  Timeout callbacks
01910   * @param  hqspi QSPI handle
01911   * @retval None
01912   */
01913 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
01914 {
01915   /* Prevent unused argument(s) compilation warning */
01916   UNUSED(hqspi);
01917   
01918   /* NOTE : This function Should not be modified, when the callback is needed,
01919             the HAL_QSPI_TimeOutCallback could be implemented in the user file
01920    */
01921 }
01922 
01923 /**
01924   * @}
01925   */
01926 
01927 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions 
01928   *  @brief   QSPI control and State functions 
01929   *
01930 @verbatim   
01931  ===============================================================================
01932                   ##### Peripheral Control and State functions #####
01933  ===============================================================================  
01934     [..]
01935     This subsection provides a set of functions allowing to :
01936       (+) Check in run-time the state of the driver. 
01937       (+) Check the error code set during last operation.
01938       (+) Abort any operation.
01939 
01940 @endverbatim
01941   * @{
01942   */
01943 
01944 /**
01945   * @brief  Return the QSPI handle state.
01946   * @param  hqspi QSPI handle
01947   * @retval HAL state
01948   */
01949 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
01950 {
01951   /* Return QSPI handle state */
01952   return hqspi->State;
01953 }
01954 
01955 /**
01956 * @brief  Return the QSPI error code
01957 * @param  hqspi QSPI handle
01958 * @retval QSPI Error Code
01959 */
01960 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
01961 {
01962   return hqspi->ErrorCode;
01963 }
01964 
01965 /**
01966 * @brief  Abort the current transmission
01967 * @param  hqspi QSPI handle
01968 * @retval HAL status
01969 */
01970 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
01971 {
01972   HAL_StatusTypeDef status = HAL_OK;
01973   uint32_t tickstart = HAL_GetTick();
01974   
01975   /* Check if the state is in one of the busy states */
01976   if ((hqspi->State & 0x2U) != 0U)
01977   {
01978     /* Process unlocked */
01979     __HAL_UNLOCK(hqspi);
01980 
01981     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
01982     {
01983       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
01984       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01985       
01986       /* Abort DMA channel */
01987       status = HAL_DMA_Abort(hqspi->hdma);
01988       if(status != HAL_OK)
01989       {
01990         hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
01991       }
01992     }  
01993     
01994     /* Configure QSPI: CR register with Abort request */
01995     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
01996     
01997     /* Wait until TC flag is set to go back in idle state */
01998     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
01999 
02000     if(status == HAL_OK)
02001     {
02002       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02003       
02004       /* Wait until BUSY flag is reset */
02005       status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
02006     }
02007     
02008     if (status == HAL_OK)
02009     {
02010       /* Update state */
02011       hqspi->State = HAL_QSPI_STATE_READY;
02012     }
02013   }
02014 
02015   return status;
02016 }
02017 
02018 /**
02019 * @brief  Abort the current transmission (non-blocking function)
02020 * @param  hqspi QSPI handle
02021 * @retval HAL status
02022 */
02023 HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
02024 {
02025   HAL_StatusTypeDef status = HAL_OK;
02026   
02027   /* Check if the state is in one of the busy states */
02028   if ((hqspi->State & 0x2U) != 0U)
02029   {
02030     /* Process unlocked */
02031     __HAL_UNLOCK(hqspi);
02032     
02033     /* Update QSPI state */
02034     hqspi->State = HAL_QSPI_STATE_ABORT;   
02035     
02036     /* Disable all interrupts */
02037     __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
02038     
02039     if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
02040     {
02041       /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
02042       CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
02043       
02044       /* Abort DMA channel */
02045       hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
02046       HAL_DMA_Abort_IT(hqspi->hdma);
02047     }  
02048     else
02049     {
02050       /* Clear interrupt */
02051       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02052       
02053       /* Enable the QSPI Transfer Complete Interrupt */
02054       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02055       
02056       /* Configure QSPI: CR register with Abort request */
02057       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
02058     }
02059   }
02060 
02061   return status;
02062 }
02063 
02064 /** @brief Set QSPI timeout
02065   * @param  hqspi QSPI handle.
02066   * @param  Timeout Timeout for the QSPI memory access.
02067   * @retval None
02068   */
02069 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
02070 {
02071   hqspi->Timeout = Timeout;
02072 }
02073 
02074 /** @brief Set QSPI Fifo threshold.
02075   * @param  hqspi QSPI handle.
02076   * @param  Threshold Threshold of the Fifo (value between 1 and 16).
02077   * @retval HAL status
02078   */
02079 HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
02080 {
02081   HAL_StatusTypeDef status = HAL_OK;
02082 
02083   /* Process locked */
02084   __HAL_LOCK(hqspi);
02085 
02086   if(hqspi->State == HAL_QSPI_STATE_READY)
02087   {
02088     /* Synchronize init structure with new FIFO threshold value */
02089     hqspi->Init.FifoThreshold = Threshold;
02090     
02091     /* Configure QSPI FIFO Threshold */
02092     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, 
02093                ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
02094   }
02095   else
02096   {
02097     status = HAL_BUSY;   
02098   }
02099   
02100   /* Process unlocked */
02101   __HAL_UNLOCK(hqspi);
02102 
02103   /* Return function status */
02104   return status;
02105 }
02106 
02107 /** @brief Get QSPI Fifo threshold.
02108   * @param  hqspi QSPI handle.
02109   * @retval Fifo threshold (value between 1 and 16)
02110   */
02111 uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
02112 {
02113   return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
02114 }
02115 
02116 /**
02117   * @}
02118   */
02119 
02120 /* Private functions ---------------------------------------------------------*/
02121  
02122 /**
02123   * @brief  DMA QSPI receive process complete callback. 
02124   * @param  hdma DMA handle
02125   * @retval None
02126   */
02127 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)  
02128 {
02129   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02130   hqspi->RxXferCount = 0U;
02131   
02132   /* Enable the QSPI transfer complete Interrupt */
02133   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02134 }
02135 
02136 /**
02137   * @brief  DMA QSPI transmit process complete callback. 
02138   * @param  hdma DMA handle
02139   * @retval None
02140   */
02141 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)     
02142 {
02143   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02144   hqspi->TxXferCount = 0U;
02145   
02146   /* Enable the QSPI transfer complete Interrupt */
02147   __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02148 }
02149 
02150 /**
02151   * @brief  DMA QSPI receive process half complete callback 
02152   * @param  hdma  DMA handle
02153   * @retval None
02154   */
02155 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
02156 {
02157   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
02158 
02159   HAL_QSPI_RxHalfCpltCallback(hqspi); 
02160 }
02161 
02162 /**
02163   * @brief  DMA QSPI transmit process half complete callback 
02164   * @param  hdma  DMA handle
02165   * @retval None
02166   */
02167 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
02168 {
02169   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
02170 
02171   HAL_QSPI_TxHalfCpltCallback(hqspi);
02172 }
02173 
02174 /**
02175   * @brief  DMA QSPI communication error callback.
02176   * @param  hdma DMA handle
02177   * @retval None
02178   */
02179 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)   
02180 {
02181   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02182   
02183   /* if DMA error is FIFO error ignore it */
02184   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
02185   {
02186     hqspi->RxXferCount = 0U;
02187     hqspi->TxXferCount = 0U;
02188     hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
02189     
02190     /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
02191     CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
02192     
02193     /* Abort the QSPI */
02194     HAL_QSPI_Abort_IT(hqspi);
02195   }
02196 }
02197 
02198 /**
02199   * @brief  DMA QSPI abort complete callback.
02200   * @param  hdma DMA handle
02201   * @retval None
02202   */
02203 static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)   
02204 {
02205   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02206 
02207   hqspi->RxXferCount = 0U;
02208   hqspi->TxXferCount = 0U;
02209 
02210   if(hqspi->State == HAL_QSPI_STATE_ABORT)
02211   {
02212     /* DMA Abort called by QSPI abort */
02213     /* Clear interrupt */
02214     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
02215     
02216     /* Enable the QSPI Transfer Complete Interrupt */
02217     __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
02218     
02219     /* Configure QSPI: CR register with Abort request */
02220     SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
02221   }
02222   else
02223   {
02224     /* DMA Abort called due to a transfer error interrupt */
02225     /* Change state of QSPI */
02226     hqspi->State = HAL_QSPI_STATE_READY;
02227     
02228     /* Error callback */
02229     HAL_QSPI_ErrorCallback(hqspi);
02230   }
02231 }
02232 /**
02233   * @brief  Wait for a flag state until timeout.
02234   * @param  hqspi QSPI handle
02235   * @param  Flag Flag checked
02236   * @param  State Value of the flag expected
02237   * @param  Timeout Duration of the time out
02238   * @param  tickstart tick start value
02239   * @retval HAL status
02240   */
02241 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, 
02242                                                         FlagStatus State, uint32_t tickstart, uint32_t Timeout)
02243 {
02244   /* Wait until flag is in expected state */    
02245   while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
02246   {
02247     /* Check for the Timeout */
02248     if (Timeout != HAL_MAX_DELAY)
02249     {
02250       if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
02251       {
02252         hqspi->State     = HAL_QSPI_STATE_ERROR;
02253         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
02254         
02255         return HAL_ERROR;
02256       }
02257     }
02258   }
02259   return HAL_OK;
02260 }
02261 
02262 /**
02263   * @brief  Configure the communication registers.
02264   * @param  hqspi QSPI handle
02265   * @param  cmd structure that contains the command configuration information
02266   * @param  FunctionalMode functional mode to configured
02267   *           This parameter can be one of the following values:
02268   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
02269   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
02270   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
02271   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
02272   * @retval None
02273   */
02274 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
02275 {
02276   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
02277 
02278   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
02279   {
02280     /* Configure QSPI: DLR register with the number of data to read or write */
02281     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
02282   }
02283       
02284   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
02285   {
02286     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
02287     {
02288       /* Configure QSPI: ABR register with alternate bytes value */
02289       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
02290 
02291       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02292       {
02293         /*---- Command with instruction, address and alternate bytes ----*/
02294         /* Configure QSPI: CCR register with all communications parameters */
02295         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02296                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateBytesSize |
02297                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
02298                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
02299 
02300         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02301         {
02302           /* Configure QSPI: AR register with address value */
02303           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02304         }
02305       }
02306       else
02307       {
02308         /*---- Command with instruction and alternate bytes ----*/
02309         /* Configure QSPI: CCR register with all communications parameters */
02310         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02311                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateBytesSize |
02312                                          cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode | 
02313                                          cmd->Instruction | FunctionalMode));
02314       }
02315     }
02316     else
02317     {
02318       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02319       {
02320         /*---- Command with instruction and address ----*/
02321         /* Configure QSPI: CCR register with all communications parameters */
02322         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02323                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateByteMode | 
02324                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | 
02325                                          cmd->Instruction | FunctionalMode));
02326 
02327         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02328         {
02329           /* Configure QSPI: AR register with address value */
02330           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02331         }
02332       }
02333       else
02334       {
02335         /*---- Command with only instruction ----*/
02336         /* Configure QSPI: CCR register with all communications parameters */
02337         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02338                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateByteMode | 
02339                                          cmd->AddressMode | cmd->InstructionMode | cmd->Instruction  | 
02340                                          FunctionalMode));
02341       }
02342     }
02343   }
02344   else
02345   {
02346     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
02347     {
02348       /* Configure QSPI: ABR register with alternate bytes value */
02349       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
02350 
02351       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02352       {
02353         /*---- Command with address and alternate bytes ----*/
02354         /* Configure QSPI: CCR register with all communications parameters */
02355         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02356                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateBytesSize |
02357                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
02358                                          cmd->InstructionMode | FunctionalMode));
02359 
02360         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02361         {
02362           /* Configure QSPI: AR register with address value */
02363           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02364         }
02365       }
02366       else
02367       {
02368         /*---- Command with only alternate bytes ----*/
02369         /* Configure QSPI: CCR register with all communications parameters */
02370         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02371                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateBytesSize |
02372                                          cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode | 
02373                                          FunctionalMode));
02374       }
02375     }
02376     else
02377     {
02378       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
02379       {
02380         /*---- Command with only address ----*/
02381         /* Configure QSPI: CCR register with all communications parameters */
02382         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02383                                          cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateByteMode | 
02384                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | 
02385                                          FunctionalMode));
02386 
02387         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
02388         {
02389           /* Configure QSPI: AR register with address value */
02390           WRITE_REG(hqspi->Instance->AR, cmd->Address);
02391         }
02392       }
02393       else
02394       {
02395         /*---- Command with only data phase ----*/
02396         if (cmd->DataMode != QSPI_DATA_NONE)
02397         {
02398           /* Configure QSPI: CCR register with all communications parameters */
02399           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
02400                                            cmd->DataMode | (cmd->DummyCycles << 18U) | cmd->AlternateByteMode | 
02401                                            cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
02402         }
02403       }
02404     }
02405   }
02406 }
02407 /**
02408   * @}
02409   */
02410 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx 
02411           STM32F413xx || STM32F423xx */
02412 
02413 #endif /* HAL_QSPI_MODULE_ENABLED */
02414 /**
02415   * @}
02416   */
02417 
02418 /**
02419   * @}
02420   */
02421 
02422 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/