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