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