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