TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_qspi.c Source File

stm32l4xx_hal_qspi.c

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