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