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