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.
Fork of TUKS-COURSE-TIMER by
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 17:38:49 by
