Hal Drivers for L4

Dependents:   BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo

Fork of STM32L4xx_HAL_Driver by Senior Design: Sound Monitor

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.1.0
00006   * @date    16-September-2015
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() function aborts any on-going operation and flushes the fifo.
00117       (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
00118 
00119     *** Workarounds linked to Silicon Limitation ***
00120     ====================================================
00121     [..]
00122       (#) Workarounds Implemented inside HAL Driver
00123          (++) Extra data written in the FIFO at the end of a read transfer
00124 
00125   @endverbatim
00126   ******************************************************************************
00127   * @attention
00128   *
00129   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00130   *
00131   * Redistribution and use in source and binary forms, with or without modification,
00132   * are permitted provided that the following conditions are met:
00133   *   1. Redistributions of source code must retain the above copyright notice,
00134   *      this list of conditions and the following disclaimer.
00135   *   2. Redistributions in binary form must reproduce the above copyright notice,
00136   *      this list of conditions and the following disclaimer in the documentation
00137   *      and/or other materials provided with the distribution.
00138   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00139   *      may be used to endorse or promote products derived from this software
00140   *      without specific prior written permission.
00141   *
00142   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00143   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00144   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00145   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00146   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00147   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00148   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00149   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00150   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00151   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00152   *
00153   ******************************************************************************  
00154   */
00155 
00156 /* Includes ------------------------------------------------------------------*/
00157 #include "stm32l4xx_hal.h"
00158 
00159 /** @addtogroup STM32L4xx_HAL_Driver
00160   * @{
00161   */
00162 
00163 /** @defgroup QSPI QSPI
00164   * @brief QSPI HAL module driver
00165   * @{
00166   */
00167 #ifdef HAL_QSPI_MODULE_ENABLED
00168     
00169 /* Private typedef -----------------------------------------------------------*/
00170 
00171 /* Private define ------------------------------------------------------------*/
00172 /** @defgroup QSPI_Private_Constants QSPI Private Constants
00173   * @{
00174   */
00175 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000)          /*!<Indirect write mode*/
00176 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ  ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
00177 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING   ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
00178 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED  ((uint32_t)QUADSPI_CCR_FMODE)   /*!<Memory-mapped mode*/
00179 /**
00180   * @}
00181   */
00182 
00183 /* Private macro -------------------------------------------------------------*/
00184 /** @defgroup QSPI_Private_Macros QSPI Private Macros
00185   * @{
00186   */
00187 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
00188                                        ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ)  || \
00189                                        ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING)   || \
00190                                        ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
00191 /**
00192   * @}
00193   */
00194 
00195 /* Private variables ---------------------------------------------------------*/
00196 
00197 /* Private function prototypes -----------------------------------------------*/
00198 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
00199 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
00200 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00201 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00202 static void QSPI_DMAError(DMA_HandleTypeDef *hdma); 
00203 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout);
00204 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
00205 
00206 /* Exported functions --------------------------------------------------------*/
00207 
00208 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
00209   * @{
00210   */
00211 
00212 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions 
00213   *  @brief    Initialization and Configuration functions 
00214   *
00215 @verbatim    
00216 ===============================================================================
00217             ##### Initialization and Configuration functions #####
00218  ===============================================================================
00219     [..]
00220     This subsection provides a set of functions allowing to :
00221       (+) Initialize the QuadSPI.
00222       (+) De-initialize the QuadSPI.
00223 
00224 @endverbatim
00225   * @{
00226   */
00227 
00228 /**
00229   * @brief Initialize the QSPI mode according to the specified parameters
00230   *        in the QSPI_InitTypeDef and initialize the associated handle.
00231   * @param hqspi: QSPI handle
00232   * @retval HAL status
00233   */
00234 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
00235 {
00236   HAL_StatusTypeDef status = HAL_ERROR;
00237   
00238   /* Check the QSPI handle allocation */
00239   if(hqspi == NULL)
00240   {
00241     return HAL_ERROR;
00242   }
00243 
00244   /* Check the parameters */
00245   assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
00246   assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
00247   assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
00248   assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
00249   assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
00250   assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
00251   assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
00252 
00253   /* Process locked */
00254   __HAL_LOCK(hqspi);
00255   
00256   if(hqspi->State == HAL_QSPI_STATE_RESET)
00257   {  
00258     /* Allocate lock resource and initialize it */
00259     hqspi->Lock = HAL_UNLOCKED;
00260 
00261     /* Init the low level hardware : GPIO, CLOCK */
00262     HAL_QSPI_MspInit(hqspi);
00263     
00264     /* Configure the default timeout for the QSPI memory access */
00265     HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
00266   }
00267   
00268   /* Configure QSPI FIFO Threshold */
00269   MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, 
00270              ((hqspi->Init.FifoThreshold - 1) << POSITION_VAL(QUADSPI_CR_FTHRES)));
00271 
00272   /* Wait till BUSY flag reset */
00273   status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
00274 
00275   if(status == HAL_OK)
00276   {
00277     /* Configure QSPI Clock Prescaler and Sample Shift */
00278     MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT), 
00279                ((hqspi->Init.ClockPrescaler << POSITION_VAL(QUADSPI_CR_PRESCALER)) | 
00280                 hqspi->Init.SampleShifting));
00281 
00282     /* Configure QSPI Flash Size, CS High Time and Clock Mode */
00283     MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE), 
00284                ((hqspi->Init.FlashSize << POSITION_VAL(QUADSPI_DCR_FSIZE)) | 
00285                 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
00286 
00287     /* Enable the QSPI peripheral */
00288     __HAL_QSPI_ENABLE(hqspi);
00289   
00290     /* Set QSPI error code to none */
00291     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;  
00292 
00293     /* Initialize the QSPI state */
00294     hqspi->State = HAL_QSPI_STATE_READY;
00295   }
00296   
00297   /* Release Lock */
00298   __HAL_UNLOCK(hqspi);
00299 
00300   /* Return function status */
00301   return status;
00302 }
00303 
00304 /**
00305   * @brief De-Initialize the QSPI peripheral. 
00306   * @param hqspi: QSPI handle
00307   * @retval HAL status
00308   */
00309 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
00310 {
00311   /* Check the QSPI handle allocation */
00312   if(hqspi == NULL)
00313   {
00314     return HAL_ERROR;
00315   }
00316 
00317   /* Process locked */
00318   __HAL_LOCK(hqspi);
00319 
00320   /* Disable the QSPI Peripheral Clock */
00321   __HAL_QSPI_DISABLE(hqspi);
00322 
00323   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00324   HAL_QSPI_MspDeInit(hqspi);
00325 
00326   /* Set QSPI error code to none */
00327   hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00328 
00329   /* Initialize the QSPI state */
00330   hqspi->State = HAL_QSPI_STATE_RESET;
00331 
00332   /* Release Lock */
00333   __HAL_UNLOCK(hqspi);
00334 
00335   return HAL_OK;
00336 }
00337 
00338 /**
00339   * @brief Initialize the QSPI MSP.
00340   * @param hqspi: QSPI handle
00341   * @retval None
00342   */
00343  __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
00344 {
00345   /* NOTE : This function should not be modified, when the callback is needed,
00346             the HAL_QSPI_MspInit can be implemented in the user file
00347    */ 
00348 }
00349 
00350 /**
00351   * @brief DeInitialize the QSPI MSP.
00352   * @param hqspi: QSPI handle
00353   * @retval None
00354   */
00355  __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
00356 {
00357   /* NOTE : This function should not be modified, when the callback is needed,
00358             the HAL_QSPI_MspDeInit can be implemented in the user file
00359    */ 
00360 }
00361 
00362 /**
00363   * @}
00364   */
00365 
00366 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions 
00367   *  @brief QSPI Transmit/Receive functions 
00368   *
00369 @verbatim   
00370  ===============================================================================
00371                       ##### IO operation functions #####
00372  ===============================================================================
00373     [..]
00374     This subsection provides a set of functions allowing to :
00375       (+) Handle the interrupts.
00376       (+) Handle the command sequence.
00377       (+) Transmit data in blocking, interrupt or DMA mode.
00378       (+) Receive data in blocking, interrupt or DMA mode.
00379       (+) Manage the auto-polling functional mode.
00380       (+) Manage the memory-mapped functional mode.
00381 
00382 @endverbatim
00383   * @{
00384   */
00385 
00386 /**
00387   * @brief Handle QSPI interrupt request.
00388   * @param hqspi: QSPI handle
00389   * @retval None
00390   */
00391 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
00392 {
00393   __IO uint32_t *data_reg;
00394   uint32_t flag = 0, itsource = 0;
00395 
00396   /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
00397   flag     = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT);
00398   itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_FT);
00399   
00400   if((flag != RESET) && (itsource != RESET))
00401   {
00402     data_reg = &hqspi->Instance->DR;
00403 
00404     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00405     {
00406       /* Transmission process */
00407       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
00408       {
00409         if (hqspi->TxXferCount > 0)
00410         {
00411           /* Fill the FIFO until it is full */
00412           *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
00413           hqspi->TxXferCount--;
00414         }
00415         else
00416         {
00417           /* No more data available for the transfer */
00418           break;
00419         }
00420       }
00421     }
00422     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00423     {
00424       /* Receiving Process */
00425       while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
00426       {
00427         if (hqspi->RxXferCount > 0)
00428         {
00429           /* Read the FIFO until it is empty */
00430           *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00431           hqspi->RxXferCount--;
00432         }
00433         else
00434         {
00435           /* All data have been received for the transfer */
00436           break;
00437         }
00438       }
00439     }
00440     
00441     /* FIFO Threshold callback */
00442     HAL_QSPI_FifoThresholdCallback(hqspi);
00443   }
00444 
00445   /* QSPI Transfer Complete interrupt occurred -------------------------------*/
00446   flag     = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TC);
00447   itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TC);
00448   
00449   if((flag != RESET) && (itsource != RESET))
00450   {
00451     /* Clear interrupt */
00452     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00453 
00454     /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
00455     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00456     
00457     /* Transfer complete callback */
00458     if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
00459     {
00460       /* Clear Busy bit */
00461       HAL_QSPI_Abort(hqspi);
00462       
00463       /* TX Complete callback */
00464       HAL_QSPI_TxCpltCallback(hqspi);
00465     }
00466     else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
00467     {
00468       data_reg = &hqspi->Instance->DR;
00469       while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0)
00470       {
00471         if (hqspi->RxXferCount > 0)
00472         {
00473           /* Read the last data received in the FIFO until it is empty */
00474           *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00475           hqspi->RxXferCount--;
00476         }
00477         else
00478         {
00479           /* All data have been received for the transfer */
00480           break;
00481         }
00482       }
00483 
00484       /* Workaround - Extra data written in the FIFO at the end of a read transfer */
00485       HAL_QSPI_Abort(hqspi);
00486 
00487       /* RX Complete callback */
00488       HAL_QSPI_RxCpltCallback(hqspi);
00489     }
00490     else if(hqspi->State == HAL_QSPI_STATE_BUSY)
00491     {
00492       /* Command Complete callback */
00493       HAL_QSPI_CmdCpltCallback(hqspi);
00494     }
00495 
00496     /* Change state of QSPI */
00497     hqspi->State = HAL_QSPI_STATE_READY;
00498   }
00499 
00500   /* QSPI Status Match interrupt occurred ------------------------------------*/
00501   flag     = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_SM);
00502   itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_SM);
00503   
00504   if((flag != RESET) && (itsource != RESET))
00505   {
00506     /* Clear interrupt */
00507     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
00508    
00509     /* Check if the automatic poll mode stop is activated */
00510     if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0)
00511     {
00512       /* Disable the QSPI Transfer Error and Status Match Interrupts */
00513       __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
00514 
00515       /* Change state of QSPI */
00516       hqspi->State = HAL_QSPI_STATE_READY;
00517     }
00518 
00519     /* Status match callback */
00520     HAL_QSPI_StatusMatchCallback(hqspi);
00521   }
00522 
00523   /* QSPI Transfer Error interrupt occurred ----------------------------------*/
00524   flag     = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TE);
00525   itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TE);
00526   
00527   if((flag != RESET) && (itsource != RESET))
00528   {
00529     /* Clear interrupt */
00530     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE);
00531     
00532     /* Disable all the QSPI Interrupts */
00533     __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
00534 
00535     /* Set error code */
00536     hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
00537     
00538     /* Change state of QSPI */
00539     hqspi->State = HAL_QSPI_STATE_ERROR;
00540 
00541     /* Error callback */
00542     HAL_QSPI_ErrorCallback(hqspi);
00543   }
00544 
00545   /* QSPI Timeout interrupt occurred -----------------------------------------*/
00546   flag     = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TO);
00547   itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TO);
00548   
00549   if((flag != RESET) && (itsource != RESET))
00550   {
00551     /* Clear interrupt */
00552     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
00553     
00554     /* Timeout callback */
00555     HAL_QSPI_TimeOutCallback(hqspi);
00556   }
00557 }
00558 
00559 /**
00560   * @brief Set the command configuration. 
00561   * @param hqspi: QSPI handle
00562   * @param cmd : structure that contains the command configuration information
00563   * @param Timeout : Timeout duration
00564   * @note   This function is used only in Indirect Read or Write Modes
00565   * @retval HAL status
00566   */
00567 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
00568 {
00569   HAL_StatusTypeDef status = HAL_ERROR;
00570   
00571   /* Check the parameters */
00572   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00573   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00574   {
00575     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00576   }
00577 
00578   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00579   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00580   {
00581     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00582   }
00583 
00584   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00585   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00586   {
00587     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00588   }
00589 
00590   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00591   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00592 
00593   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00594   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00595   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00596   
00597   /* Process locked */
00598   __HAL_LOCK(hqspi);
00599 
00600   if(hqspi->State == HAL_QSPI_STATE_READY)
00601   {
00602     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00603     
00604     /* Update QSPI state */
00605     hqspi->State = HAL_QSPI_STATE_BUSY;   
00606     
00607     /* Wait till BUSY flag reset */
00608     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout);
00609     
00610     if (status == HAL_OK)
00611     {
00612       /* Call the configuration function */
00613       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00614       
00615       if (cmd->DataMode == QSPI_DATA_NONE)
00616       {
00617         /* When there is no data phase, the transfer start as soon as the configuration is done 
00618         so wait until TC flag is set to go back in idle state */
00619         if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
00620         { 
00621           status = HAL_TIMEOUT;
00622         }
00623         else
00624         {
00625           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00626           
00627           /* Update QSPI state */
00628           hqspi->State = HAL_QSPI_STATE_READY;   
00629         }
00630         
00631       }
00632       else
00633       {
00634         /* Update QSPI state */
00635         hqspi->State = HAL_QSPI_STATE_READY;   
00636       }
00637     }
00638   }
00639   else
00640   {
00641     status = HAL_BUSY;   
00642   }
00643   
00644   /* Process unlocked */
00645   __HAL_UNLOCK(hqspi);
00646 
00647   /* Return function status */
00648   return status;
00649 }
00650 
00651 /**
00652   * @brief Set the command configuration in interrupt mode. 
00653   * @param hqspi: QSPI handle
00654   * @param cmd : structure that contains the command configuration information
00655   * @note   This function is used only in Indirect Read or Write Modes
00656   * @retval HAL status
00657   */
00658 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
00659 {
00660   HAL_StatusTypeDef status = HAL_ERROR;
00661   
00662   /* Check the parameters */
00663   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
00664   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
00665   {
00666     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
00667   }
00668 
00669   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
00670   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
00671   {
00672     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
00673   }
00674 
00675   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
00676   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
00677   {
00678     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
00679   }
00680 
00681   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
00682   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
00683 
00684   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
00685   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
00686   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
00687   
00688   /* Process locked */
00689   __HAL_LOCK(hqspi);
00690 
00691   if(hqspi->State == HAL_QSPI_STATE_READY)
00692   {
00693     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00694     
00695     /* Update QSPI state */
00696     hqspi->State = HAL_QSPI_STATE_BUSY;   
00697     
00698     /* Wait till BUSY flag reset */
00699     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
00700     
00701     if (status == HAL_OK)
00702     {
00703       if (cmd->DataMode == QSPI_DATA_NONE)
00704       {
00705         /* When there is no data phase, the transfer start as soon as the configuration is done 
00706         so activate TC and TE interrupts */
00707         /* Clear interrupt */
00708         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
00709 
00710         /* Enable the QSPI Transfer Error Interrupt */
00711         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
00712       }
00713       
00714       /* Call the configuration function */
00715       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00716       
00717       if (cmd->DataMode != QSPI_DATA_NONE)
00718       {
00719         /* Update QSPI state */
00720         hqspi->State = HAL_QSPI_STATE_READY;   
00721       }
00722     }
00723   }
00724   else
00725   {
00726     status = HAL_BUSY;   
00727   }
00728   
00729   /* Process unlocked */
00730   __HAL_UNLOCK(hqspi);
00731 
00732   /* Return function status */
00733   return status;
00734 }
00735 
00736 /**
00737   * @brief Transmit an amount of data in blocking mode. 
00738   * @param hqspi: QSPI handle
00739   * @param pData: pointer to data buffer
00740   * @param Timeout : Timeout duration
00741   * @note   This function is used only in Indirect Write Mode
00742   * @retval HAL status
00743   */
00744 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
00745 {
00746   HAL_StatusTypeDef status = HAL_OK;
00747   __IO uint32_t *data_reg = &hqspi->Instance->DR;
00748 
00749   /* Process locked */
00750   __HAL_LOCK(hqspi);
00751 
00752   if(hqspi->State == HAL_QSPI_STATE_READY)
00753   {
00754     if(pData != NULL )
00755     {
00756       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00757     
00758       /* Update state */
00759       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
00760       
00761       /* Configure counters and size of the handle */
00762       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
00763       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
00764       hqspi->pTxBuffPtr = pData;
00765     
00766       /* Configure QSPI: CCR register with functional as indirect write */
00767       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00768 
00769       while(hqspi->TxXferCount > 0)
00770       {
00771         /* Wait until FT flag is set to send data */
00772         if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, Timeout) != HAL_OK)
00773         { 
00774           status = HAL_TIMEOUT;
00775           break;
00776         }
00777 
00778         *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
00779         hqspi->TxXferCount--;
00780       }
00781     
00782       if (status == HAL_OK)
00783       {
00784         /* Wait until TC flag is set to go back in idle state */
00785         if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
00786         { 
00787           status = HAL_TIMEOUT;
00788         }
00789         else
00790         {
00791           /* Clear Transfer Complete bit */
00792           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00793           
00794           /* Clear Busy bit */
00795           status = HAL_QSPI_Abort(hqspi);
00796         }
00797       }
00798     
00799       /* Update QSPI state */
00800       hqspi->State = HAL_QSPI_STATE_READY;    
00801     }
00802     else
00803     {
00804       status = HAL_ERROR;
00805     }
00806   }
00807   else
00808   {
00809     status = HAL_BUSY;
00810   }
00811 
00812   /* Process unlocked */
00813   __HAL_UNLOCK(hqspi);
00814 
00815   return status;
00816 }
00817 
00818 
00819 /**
00820   * @brief Receive an amount of data in blocking mode.
00821   * @param hqspi: QSPI handle
00822   * @param pData: pointer to data buffer
00823   * @param Timeout : Timeout duration
00824   * @note   This function is used only in Indirect Read Mode
00825   * @retval HAL status
00826   */
00827 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
00828 {
00829   HAL_StatusTypeDef status = HAL_OK;
00830   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
00831   __IO uint32_t *data_reg = &hqspi->Instance->DR;
00832 
00833   /* Process locked */
00834   __HAL_LOCK(hqspi);
00835 
00836   if(hqspi->State == HAL_QSPI_STATE_READY)
00837   {
00838     if(pData != NULL )
00839     {
00840       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00841     
00842       /* Update state */
00843       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
00844     
00845       /* Configure counters and size of the handle */
00846       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
00847       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
00848       hqspi->pRxBuffPtr = pData;
00849 
00850       /* Configure QSPI: CCR register with functional as indirect read */
00851       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
00852 
00853       /* Start the transfer by re-writing the address in AR register */
00854       WRITE_REG(hqspi->Instance->AR, addr_reg);
00855       
00856       while(hqspi->RxXferCount > 0)
00857       {
00858         /* Wait until FT or TC flag is set to read received data */
00859         if(QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, Timeout) != HAL_OK)
00860         { 
00861           status = HAL_TIMEOUT;
00862           break;
00863         }
00864 
00865         *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
00866         hqspi->RxXferCount--;
00867       }
00868     
00869       if (status == HAL_OK)
00870       {
00871         /* Wait until TC flag is set to go back in idle state */
00872         if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK)
00873         { 
00874           status = HAL_TIMEOUT;
00875         }
00876         else
00877         {
00878           /* Clear Transfer Complete bit */
00879           __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
00880 
00881           /* Workaround - Extra data written in the FIFO at the end of a read transfer */
00882           status = HAL_QSPI_Abort(hqspi);
00883         }
00884       }
00885 
00886       /* Update QSPI state */
00887       hqspi->State = HAL_QSPI_STATE_READY;    
00888     }
00889     else
00890     {
00891       status = HAL_ERROR;
00892     }
00893   }
00894   else
00895   {
00896     status = HAL_BUSY;
00897   }
00898   
00899   /* Process unlocked */
00900   __HAL_UNLOCK(hqspi);
00901 
00902   return status;
00903 }
00904 
00905 /**
00906   * @brief  Send an amount of data in non-blocking mode with interrupt.
00907   * @param  hqspi: QSPI handle
00908   * @param  pData: pointer to data buffer
00909   * @note   This function is used only in Indirect Write Mode
00910   * @retval HAL status
00911   */
00912 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
00913 {  
00914   HAL_StatusTypeDef status = HAL_OK;
00915 
00916   /* Process locked */
00917   __HAL_LOCK(hqspi);
00918 
00919   if(hqspi->State == HAL_QSPI_STATE_READY)
00920   {
00921     if(pData != NULL )
00922     {
00923       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00924 
00925       /* Update state */
00926       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
00927 
00928       /* Configure counters and size of the handle */
00929       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
00930       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
00931       hqspi->pTxBuffPtr = pData;
00932     
00933       /* Configure QSPI: CCR register with functional as indirect write */
00934       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
00935     
00936       /* Clear interrupt */
00937       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
00938 
00939       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
00940       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
00941     }
00942     else
00943     {
00944       status = HAL_ERROR;
00945     }
00946   }
00947   else
00948   {
00949     status = HAL_BUSY;
00950   }
00951 
00952   /* Process unlocked */
00953   __HAL_UNLOCK(hqspi);
00954 
00955   return status;
00956 }
00957 
00958 /**
00959   * @brief  Receive an amount of data in non-blocking mode with interrupt.
00960   * @param  hqspi: QSPI handle
00961   * @param  pData: pointer to data buffer
00962   * @note   This function is used only in Indirect Read Mode
00963   * @retval HAL status
00964   */
00965 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
00966 {
00967   HAL_StatusTypeDef status = HAL_OK;
00968   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
00969 
00970   /* Process locked */
00971   __HAL_LOCK(hqspi);
00972 
00973   if(hqspi->State == HAL_QSPI_STATE_READY)
00974   {
00975     if(pData != NULL )
00976     {
00977       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
00978     
00979       /* Update state */
00980       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
00981     
00982       /* Configure counters and size of the handle */
00983       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
00984       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
00985       hqspi->pRxBuffPtr = pData;
00986 
00987       /* Configure QSPI: CCR register with functional as indirect read */
00988       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
00989 
00990       /* Start the transfer by re-writing the address in AR register */
00991       WRITE_REG(hqspi->Instance->AR, addr_reg);
00992 
00993       /* Clear interrupt */
00994       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
00995 
00996       /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
00997       __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
00998     }
00999     else
01000     {
01001       status = HAL_ERROR;
01002     }
01003   }
01004   else
01005   {
01006     status = HAL_BUSY;   
01007   }
01008 
01009   /* Process unlocked */
01010   __HAL_UNLOCK(hqspi);
01011 
01012   return status;
01013 }
01014 
01015 /**
01016   * @brief  Send an amount of data in non-blocking mode with DMA. 
01017   * @param  hqspi: QSPI handle
01018   * @param  pData: pointer to data buffer
01019   * @note   This function is used only in Indirect Write Mode
01020   * @retval HAL status
01021   */
01022 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01023 {
01024   HAL_StatusTypeDef status = HAL_OK;
01025   uint32_t *tmp;
01026   
01027   /* Process locked */
01028   __HAL_LOCK(hqspi);
01029 
01030   if(hqspi->State == HAL_QSPI_STATE_READY)
01031   {
01032     if(pData != NULL ) 
01033     {
01034       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01035 
01036       /* Update state */
01037       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
01038 
01039       /* Configure counters and size of the handle */
01040       hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
01041       hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
01042       hqspi->pTxBuffPtr = pData;
01043     
01044       /* Configure QSPI: CCR register with functional mode as indirect write */
01045       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
01046     
01047       /* Set the QSPI DMA transfer complete callback */
01048       hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
01049     
01050       /* Set the QSPI DMA Half transfer complete callback */
01051       hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
01052     
01053       /* Set the DMA error callback */
01054       hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01055       
01056       /* Configure the direction of the DMA */
01057       hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
01058       MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
01059 
01060       /* Enable the QSPI transmit DMA Channel */
01061       tmp = (uint32_t*)&pData;
01062       HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize);
01063     
01064       /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01065       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01066     }
01067     else
01068     {
01069       status = HAL_OK;
01070     }
01071   }
01072   else
01073   {
01074     status = HAL_BUSY;   
01075   }
01076 
01077   /* Process unlocked */
01078   __HAL_UNLOCK(hqspi);
01079 
01080   return status;
01081 }
01082 
01083 /**
01084   * @brief  Receive an amount of data in non-blocking mode with DMA. 
01085   * @param  hqspi: QSPI handle
01086   * @param  pData: pointer to data buffer.
01087   * @note   This function is used only in Indirect Read Mode
01088   * @retval HAL status
01089   */
01090 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
01091 {
01092   HAL_StatusTypeDef status = HAL_OK;
01093   uint32_t *tmp;
01094   uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
01095   
01096   /* Process locked */
01097   __HAL_LOCK(hqspi);
01098 
01099   if(hqspi->State == HAL_QSPI_STATE_READY)
01100   {
01101     if(pData != NULL ) 
01102     {
01103       hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01104     
01105       /* Update state */
01106       hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
01107     
01108       /* Configure counters and size of the handle */
01109       hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
01110       hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
01111       hqspi->pRxBuffPtr = pData;
01112 
01113       /* Set the QSPI DMA transfer complete callback */
01114       hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
01115     
01116       /* Set the QSPI DMA Half transfer complete callback */
01117       hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
01118     
01119       /* Set the DMA error callback */
01120       hqspi->hdma->XferErrorCallback = QSPI_DMAError;
01121       
01122       /* Configure the direction of the DMA */
01123       hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
01124       MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction);
01125 
01126       /* Enable the DMA Channel */
01127       tmp = (uint32_t*)&pData;
01128       HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
01129     
01130       /* Configure QSPI: CCR register with functional as indirect read */
01131       MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
01132 
01133       /* Start the transfer by re-writing the address in AR register */
01134       WRITE_REG(hqspi->Instance->AR, addr_reg);
01135 
01136       /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
01137       SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01138     }
01139     else
01140     {
01141       status = HAL_ERROR;
01142     }
01143   }
01144   else
01145   {
01146     status = HAL_BUSY; 
01147   }
01148 
01149   /* Process unlocked */
01150   __HAL_UNLOCK(hqspi);
01151 
01152   return status;
01153 }
01154 
01155 /**
01156   * @brief  Configure the QSPI Automatic Polling Mode in blocking mode. 
01157   * @param  hqspi: QSPI handle
01158   * @param  cmd: structure that contains the command configuration information.
01159   * @param  cfg: structure that contains the polling configuration information.
01160   * @param  Timeout : Timeout duration
01161   * @note   This function is used only in Automatic Polling Mode
01162   * @retval HAL status
01163   */
01164 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
01165 {
01166   HAL_StatusTypeDef status = HAL_ERROR;
01167   
01168   /* Check the parameters */
01169   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01170   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01171   {
01172     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01173   }
01174 
01175   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01176   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01177   {
01178     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01179   }
01180 
01181   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01182   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01183   {
01184     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01185   }
01186 
01187   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01188   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01189 
01190   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01191   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01192   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01193 
01194   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01195   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01196   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01197   
01198   /* Process locked */
01199   __HAL_LOCK(hqspi);
01200   
01201   if(hqspi->State == HAL_QSPI_STATE_READY)
01202   {
01203     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01204     
01205     /* Update state */
01206     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01207     
01208     /* Wait till BUSY flag reset */
01209     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout);
01210     
01211     if (status == HAL_OK)
01212     {
01213       /* Configure QSPI: PSMAR register with the status match value */
01214       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01215       
01216       /* Configure QSPI: PSMKR register with the status mask value */
01217       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01218       
01219       /* Configure QSPI: PIR register with the interval value */
01220       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01221       
01222       /* Configure QSPI: CR register with Match mode and Automatic stop enabled 
01223       (otherwise there will be an infinite loop in blocking mode) */
01224       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 
01225                (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
01226       
01227       /* Call the configuration function */
01228       cmd->NbData = cfg->StatusBytesSize;
01229       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01230       
01231       /* Wait until SM flag is set to go back in idle state */
01232       if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, Timeout) != HAL_OK)
01233       { 
01234         status = HAL_TIMEOUT;
01235       }
01236       else
01237       {
01238         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
01239         
01240         /* Update state */
01241         hqspi->State = HAL_QSPI_STATE_READY;
01242       }
01243     }
01244   }
01245   else
01246   {
01247     status = HAL_BUSY;   
01248   }
01249   
01250   /* Process unlocked */
01251   __HAL_UNLOCK(hqspi);
01252   
01253   /* Return function status */
01254   return status;  
01255 }
01256 
01257 /**
01258   * @brief  Configure the QSPI Automatic Polling Mode in non-blocking mode. 
01259   * @param  hqspi: QSPI handle
01260   * @param  cmd: structure that contains the command configuration information.
01261   * @param  cfg: structure that contains the polling configuration information.
01262   * @note   This function is used only in Automatic Polling Mode
01263   * @retval HAL status
01264   */
01265 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
01266 {
01267   HAL_StatusTypeDef status = HAL_ERROR;
01268   
01269   /* Check the parameters */
01270   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01271   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01272   {
01273     assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01274   }
01275 
01276   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01277   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01278   {
01279     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01280   }
01281 
01282   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01283   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01284   {
01285     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01286   }
01287 
01288   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01289   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01290 
01291   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01292   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01293   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01294 
01295   assert_param(IS_QSPI_INTERVAL(cfg->Interval));
01296   assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
01297   assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
01298   assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
01299   
01300   /* Process locked */
01301   __HAL_LOCK(hqspi);
01302   
01303   if(hqspi->State == HAL_QSPI_STATE_READY)
01304   {
01305     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01306     
01307     /* Update state */
01308     hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
01309     
01310     /* Wait till BUSY flag reset */
01311     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
01312     
01313     if (status == HAL_OK)
01314     {
01315       /* Configure QSPI: PSMAR register with the status match value */
01316       WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
01317       
01318       /* Configure QSPI: PSMKR register with the status mask value */
01319       WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
01320       
01321       /* Configure QSPI: PIR register with the interval value */
01322       WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
01323       
01324       /* Configure QSPI: CR register with Match mode and Automatic stop mode */
01325       MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 
01326                (cfg->MatchMode | cfg->AutomaticStop));
01327       
01328       /* Clear interrupt */
01329       __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
01330 
01331       /* Enable the QSPI Transfer Error and status match Interrupt */
01332       __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
01333 
01334       /* Call the configuration function */
01335       cmd->NbData = cfg->StatusBytesSize;
01336       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
01337     }
01338   }
01339   else
01340   {
01341     status = HAL_BUSY;   
01342   }
01343   
01344   /* Process unlocked */
01345   __HAL_UNLOCK(hqspi);
01346   
01347   /* Return function status */
01348   return status;  
01349 }
01350 
01351 /**
01352   * @brief  Configure the Memory Mapped mode. 
01353   * @param  hqspi: QSPI handle
01354   * @param  cmd: structure that contains the command configuration information.
01355   * @param  cfg: structure that contains the memory mapped configuration information.
01356   * @note   This function is used only in Memory mapped Mode
01357   * @retval HAL status
01358   */
01359 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
01360 {
01361   HAL_StatusTypeDef status = HAL_ERROR;
01362   
01363   /* Check the parameters */
01364   assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
01365   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01366   {
01367   assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
01368   }
01369 
01370   assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
01371   if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01372   {
01373     assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
01374   }
01375 
01376   assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
01377   if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01378   {
01379     assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
01380   }
01381 
01382   assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
01383   assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
01384 
01385   assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
01386   assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
01387   assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
01388 
01389   assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
01390   
01391   /* Process locked */
01392   __HAL_LOCK(hqspi);
01393   
01394   if(hqspi->State == HAL_QSPI_STATE_READY)
01395   {
01396     hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
01397     
01398     /* Update state */
01399     hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
01400     
01401     /* Wait till BUSY flag reset */
01402     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
01403     
01404     if (status == HAL_OK)
01405     {
01406       /* Configure QSPI: CR register with timeout counter enable */
01407     MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
01408       
01409     if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
01410       {
01411         assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
01412         
01413         /* Configure QSPI: LPTR register with the low-power timeout value */
01414         WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
01415         
01416         /* Clear interrupt */
01417         __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
01418 
01419         /* Enable the QSPI TimeOut Interrupt */
01420         __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
01421       }
01422       
01423       /* Call the configuration function */
01424       QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
01425     }
01426   }
01427   else
01428   {
01429     status = HAL_BUSY;   
01430   }
01431   
01432   /* Process unlocked */
01433   __HAL_UNLOCK(hqspi);
01434   
01435   /* Return function status */
01436   return status;  
01437 }
01438 
01439 /**
01440   * @brief  Transfer Error callback.
01441   * @param  hqspi: QSPI handle
01442   * @retval None
01443   */
01444 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
01445 {
01446   /* NOTE : This function should not be modified, when the callback is needed,
01447             the HAL_QSPI_ErrorCallback could be implemented in the user file
01448    */
01449 }
01450 
01451 /**
01452   * @brief  Command completed callback.
01453   * @param  hqspi: QSPI handle
01454   * @retval None
01455   */
01456 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
01457 {
01458   /* NOTE: This function should not be modified, when the callback is needed,
01459            the HAL_QSPI_CmdCpltCallback could be implemented in the user file
01460    */
01461 }
01462 
01463 /**
01464   * @brief  Rx Transfer completed callback.
01465   * @param  hqspi: QSPI handle
01466   * @retval None
01467   */
01468 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
01469 {
01470   /* NOTE: This function should not be modified, when the callback is needed,
01471            the HAL_QSPI_RxCpltCallback could be implemented in the user file
01472    */
01473 }
01474 
01475 /**
01476   * @brief  Tx Transfer completed callback.
01477   * @param  hqspi: QSPI handle
01478   * @retval None
01479   */
01480  __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
01481 {
01482   /* NOTE: This function should not be modified, when the callback is needed,
01483            the HAL_QSPI_TxCpltCallback could be implemented in the user file
01484    */ 
01485 }
01486 
01487 /**
01488   * @brief  Rx Half Transfer completed callback.
01489   * @param  hqspi: QSPI handle
01490   * @retval None
01491   */
01492 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01493 {
01494   /* NOTE: This function should not be modified, when the callback is needed,
01495            the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
01496    */
01497 }
01498 
01499 /**
01500   * @brief  Tx Half Transfer completed callback.
01501   * @param  hqspi: QSPI handle
01502   * @retval None
01503   */
01504  __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
01505 {
01506   /* NOTE: This function should not be modified, when the callback is needed,
01507            the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
01508    */ 
01509 }
01510 
01511 /**
01512   * @brief  FIFO Threshold callback.
01513   * @param  hqspi: QSPI handle
01514   * @retval None
01515   */
01516 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
01517 {
01518   /* NOTE : This function should not be modified, when the callback is needed,
01519             the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
01520    */
01521 }
01522 
01523 /**
01524   * @brief  Status Match callback.
01525   * @param  hqspi: QSPI handle
01526   * @retval None
01527   */
01528 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
01529 {
01530   /* NOTE : This function should not be modified, when the callback is needed,
01531             the HAL_QSPI_StatusMatchCallback could be implemented in the user file
01532    */
01533 }
01534 
01535 /**
01536   * @brief  Timeout callback.
01537   * @param  hqspi: QSPI handle
01538   * @retval None
01539   */
01540 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
01541 {
01542   /* NOTE : This function should not be modified, when the callback is needed,
01543             the HAL_QSPI_TimeOutCallback could be implemented in the user file
01544    */
01545 }
01546 
01547 /**
01548   * @}
01549   */
01550 
01551 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions 
01552   *  @brief   QSPI control and State functions 
01553   *
01554 @verbatim   
01555  ===============================================================================
01556                   ##### Peripheral Control and State functions #####
01557  ===============================================================================  
01558     [..]
01559     This subsection provides a set of functions allowing to :
01560       (+) Check in run-time the state of the driver. 
01561       (+) Check the error code set during last operation.
01562       (+) Abort any operation.
01563 
01564   
01565 @endverbatim
01566   * @{
01567   */
01568 
01569 /**
01570   * @brief  Return the QSPI handle state.
01571   * @param  hqspi: QSPI handle
01572   * @retval HAL state
01573   */
01574 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
01575 {
01576   /* Return QSPI handle state */
01577   return hqspi->State;
01578 }
01579 
01580 /**
01581 * @brief  Return the QSPI error code.
01582 * @param  hqspi: QSPI handle
01583 * @retval QSPI Error Code
01584 */
01585 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
01586 {
01587   return hqspi->ErrorCode;
01588 }
01589 
01590 /**
01591 * @brief  Abort the current transmission.
01592 * @param  hqspi: QSPI handle
01593 * @retval HAL status
01594 */
01595 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
01596 {
01597   HAL_StatusTypeDef status = HAL_ERROR;
01598   
01599   /* Configure QSPI: CR register with Abort request */
01600   SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
01601 
01602   /* Wait until TC flag is set to go back in idle state */
01603   if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
01604   { 
01605     status = HAL_TIMEOUT;
01606   }
01607   else
01608   {
01609     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
01610     
01611     /* Wait until BUSY flag is reset */
01612     status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout);
01613 
01614     /* Update state */
01615     hqspi->State = HAL_QSPI_STATE_READY;
01616   }
01617 
01618   return status;
01619 }
01620 
01621 /** @brief Set QSPI timeout.
01622   * @param  hqspi: QSPI handle.
01623   * @param  Timeout: Timeout for the QSPI memory access.
01624   * @retval None
01625   */
01626 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
01627 {
01628   hqspi->Timeout = Timeout;
01629 }
01630 
01631 /**
01632   * @}
01633   */
01634 
01635 /**
01636   * @brief  DMA QSPI receive process complete callback. 
01637   * @param  hdma: DMA handle
01638   * @retval None
01639   */
01640 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)  
01641 {
01642   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01643   hqspi->RxXferCount = 0;
01644   
01645   /* Wait for QSPI TC Flag */
01646   if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
01647   {
01648     /* Timeout occurred */ 
01649     HAL_QSPI_ErrorCallback(hqspi);
01650   }
01651   else
01652   {
01653     /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
01654     CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01655 
01656     /* Disable the DMA channel */
01657     HAL_DMA_Abort(hdma);
01658 
01659     /* Clear Transfer Complete bit */
01660     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
01661 
01662     /* Workaround - Extra data written in the FIFO at the end of a read transfer */
01663     HAL_QSPI_Abort(hqspi);
01664 
01665     /* Update state */
01666     hqspi->State = HAL_QSPI_STATE_READY;
01667     
01668     HAL_QSPI_RxCpltCallback(hqspi);
01669   }
01670 }
01671 
01672 /**
01673   * @brief  DMA QSPI transmit process complete callback. 
01674   * @param  hdma: DMA handle
01675   * @retval None
01676   */
01677 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)     
01678 {
01679   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01680   hqspi->TxXferCount = 0;
01681   
01682   /* Wait for QSPI TC Flag */
01683   if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK)
01684   {
01685     /* Timeout occurred */ 
01686     HAL_QSPI_ErrorCallback(hqspi);
01687   }
01688   else
01689   {
01690     /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
01691     CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
01692   
01693     /* Disable the DMA channel */
01694     HAL_DMA_Abort(hdma);
01695 
01696     /* Clear Transfer Complete bit */
01697     __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
01698 
01699     /* Clear Busy bit */
01700     HAL_QSPI_Abort(hqspi);
01701 
01702     /* Update state */
01703     hqspi->State = HAL_QSPI_STATE_READY;
01704     
01705     HAL_QSPI_TxCpltCallback(hqspi);
01706   }
01707 }
01708 
01709 /**
01710   * @brief  DMA QSPI receive process half complete callback. 
01711   * @param  hdma : DMA handle
01712   * @retval None
01713   */
01714 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
01715 {
01716   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
01717 
01718   HAL_QSPI_RxHalfCpltCallback(hqspi); 
01719 }
01720 
01721 /**
01722   * @brief  DMA QSPI transmit process half complete callback.
01723   * @param  hdma : DMA handle
01724   * @retval None
01725   */
01726 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
01727 {
01728   QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
01729 
01730   HAL_QSPI_TxHalfCpltCallback(hqspi);
01731 }
01732 
01733 /**
01734   * @brief  DMA QSPI communication error callback.
01735   * @param  hdma: DMA handle
01736   * @retval None
01737   */
01738 static void QSPI_DMAError(DMA_HandleTypeDef *hdma)   
01739 {
01740   QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01741 
01742   hqspi->RxXferCount = 0;
01743   hqspi->TxXferCount = 0;
01744   hqspi->State       = HAL_QSPI_STATE_ERROR;
01745   hqspi->ErrorCode   |= HAL_QSPI_ERROR_DMA;
01746 
01747   HAL_QSPI_ErrorCallback(hqspi);
01748 }
01749 
01750 /**
01751   * @brief  Wait for a flag state until timeout.
01752   * @param  hqspi: QSPI handle
01753   * @param  Flag: Flag checked
01754   * @param  State: Value of the flag expected
01755   * @param  Timeout: Duration of the timeout
01756   * @retval HAL status
01757   */
01758 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
01759                                                         FlagStatus State, uint32_t Timeout)
01760 {
01761   uint32_t tickstart = HAL_GetTick();
01762   
01763   /* Wait until flag is in expected state */    
01764   while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
01765   {
01766     /* Check for the Timeout */
01767     if (Timeout != HAL_MAX_DELAY)
01768     {
01769       if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
01770       {
01771         hqspi->State     = HAL_QSPI_STATE_ERROR;
01772         hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
01773         
01774         return HAL_TIMEOUT;
01775       }
01776     }
01777   }
01778   return HAL_OK;
01779 }
01780 
01781 /**
01782   * @brief  Configure the communication registers.
01783   * @param  hqspi: QSPI handle
01784   * @param  cmd: structure that contains the command configuration information
01785   * @param  FunctionalMode: functional mode to configured
01786   *           This parameter can be one of the following values:
01787   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
01788   *            @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
01789   *            @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
01790   *            @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
01791   * @retval None
01792   */
01793 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
01794 {
01795   assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
01796 
01797   if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
01798   {
01799     /* Configure QSPI: DLR register with the number of data to read or write */
01800     WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1));
01801   }
01802 
01803   if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
01804   {
01805     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01806     {
01807       /* Configure QSPI: ABR register with alternate bytes value */
01808       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
01809 
01810       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01811       {
01812         /*---- Command with instruction, address and alternate bytes ----*/
01813         /* Configure QSPI: CCR register with all communications parameters */
01814         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01815                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01816                                          cmd->AlternateBytesSize | cmd->AlternateByteMode | 
01817                                          cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | 
01818                                          cmd->Instruction | FunctionalMode));
01819 
01820         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
01821         {
01822           /* Configure QSPI: AR register with address value */
01823           WRITE_REG(hqspi->Instance->AR, cmd->Address);
01824         }
01825       }
01826       else
01827       {
01828         /*---- Command with instruction and alternate bytes ----*/
01829         /* Configure QSPI: CCR register with all communications parameters */
01830         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01831                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01832                                          cmd->AlternateBytesSize | cmd->AlternateByteMode | 
01833                                          cmd->AddressMode | cmd->InstructionMode | 
01834                                          cmd->Instruction | FunctionalMode));
01835       }
01836     }
01837     else
01838     {
01839       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01840       {
01841         /*---- Command with instruction and address ----*/
01842         /* Configure QSPI: CCR register with all communications parameters */
01843         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01844                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01845                                          cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode | 
01846                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
01847 
01848         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
01849         {
01850           /* Configure QSPI: AR register with address value */
01851           WRITE_REG(hqspi->Instance->AR, cmd->Address);
01852         }
01853       }
01854       else
01855       {
01856         /*---- Command with only instruction ----*/
01857         /* Configure QSPI: CCR register with all communications parameters */
01858         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01859                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01860                                          cmd->AlternateByteMode | cmd->AddressMode | 
01861                                          cmd->InstructionMode | cmd->Instruction | FunctionalMode));
01862       }
01863     }
01864   }
01865   else
01866   {
01867     if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
01868     {
01869       /* Configure QSPI: ABR register with alternate bytes value */
01870       WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
01871 
01872       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01873       {
01874         /*---- Command with address and alternate bytes ----*/
01875         /* Configure QSPI: CCR register with all communications parameters */
01876         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01877                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01878                                          cmd->AlternateBytesSize | cmd->AlternateByteMode | 
01879                                          cmd->AddressSize | cmd->AddressMode | 
01880                                          cmd->InstructionMode | FunctionalMode));
01881 
01882         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
01883         {
01884           /* Configure QSPI: AR register with address value */
01885           WRITE_REG(hqspi->Instance->AR, cmd->Address);
01886         }
01887       }
01888       else
01889       {
01890         /*---- Command with only alternate bytes ----*/
01891         /* Configure QSPI: CCR register with all communications parameters */
01892         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01893                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01894                                          cmd->AlternateBytesSize | cmd->AlternateByteMode | 
01895                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
01896       }
01897     }
01898     else
01899     {
01900       if (cmd->AddressMode != QSPI_ADDRESS_NONE)
01901       {
01902         /*---- Command with only address ----*/
01903         /* Configure QSPI: CCR register with all communications parameters */
01904         WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01905                                          cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01906                                          cmd->AlternateByteMode | cmd->AddressSize | 
01907                                          cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
01908 
01909         if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
01910         {
01911           /* Configure QSPI: AR register with address value */
01912           WRITE_REG(hqspi->Instance->AR, cmd->Address);
01913         }
01914       }
01915       else
01916       {
01917         /*---- Command with only data phase ----*/
01918         if (cmd->DataMode != QSPI_DATA_NONE)
01919         {
01920           /* Configure QSPI: CCR register with all communications parameters */
01921           WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 
01922                                            cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 
01923                                            cmd->AlternateByteMode | cmd->AddressMode | 
01924                                            cmd->InstructionMode | FunctionalMode));
01925         }
01926       }
01927     }
01928   }
01929 }
01930 
01931 /**
01932   * @}
01933   */
01934 
01935 #endif /* HAL_QSPI_MODULE_ENABLED */
01936 /**
01937   * @}
01938   */
01939 
01940 /**
01941   * @}
01942   */
01943 
01944 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01945