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