Hal Drivers for L4
Dependents: BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo
Fork of STM32L4xx_HAL_Driver by
stm32l4xx_hal_qspi.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_qspi.c 00004 * @author MCD Application Team 00005 * @version V1.1.0 00006 * @date 16-September-2015 00007 * @brief QSPI HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the QuadSPI interface (QSPI). 00010 * + Initialization and de-initialization functions 00011 * + Indirect functional mode management 00012 * + Memory-mapped functional mode management 00013 * + Auto-polling functional mode management 00014 * + Interrupts and flags management 00015 * + DMA channel configuration for indirect functional mode 00016 * + Errors management and abort functionality 00017 * 00018 * 00019 @verbatim 00020 =============================================================================== 00021 ##### How to use this driver ##### 00022 =============================================================================== 00023 [..] 00024 *** Initialization *** 00025 ====================== 00026 [..] 00027 (#) As prerequisite, fill in the HAL_QSPI_MspInit() : 00028 (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE(). 00029 (++) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET(). 00030 (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). 00031 (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init(). 00032 (++) If interrupt mode is used, enable and configure QuadSPI global 00033 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). 00034 (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel 00035 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), 00036 link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure 00037 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). 00038 (#) Configure the flash size, the clock prescaler, the fifo threshold, the 00039 clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function. 00040 00041 *** Indirect functional mode *** 00042 ================================ 00043 [..] 00044 (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT() 00045 functions : 00046 (++) Instruction phase : the mode used and if present the instruction opcode. 00047 (++) Address phase : the mode used and if present the size and the address value. 00048 (++) Alternate-bytes phase : the mode used and if present the size and the alternate 00049 bytes values. 00050 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). 00051 (++) Data phase : the mode used and if present the number of bytes. 00052 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 00053 if activated. 00054 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. 00055 (#) If no data is required for the command, it is sent directly to the memory : 00056 (++) In polling mode, the output of the function is done when the transfer is complete. 00057 (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete. 00058 (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or 00059 HAL_QSPI_Transmit_IT() after the command configuration : 00060 (++) In polling mode, the output of the function is done when the transfer is complete. 00061 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold 00062 is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete. 00063 (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and 00064 HAL_QSPI_TxCpltCallback() will be called when the transfer is complete. 00065 (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or 00066 HAL_QSPI_Receive_IT() after the command configuration : 00067 (++) In polling mode, the output of the function is done when the transfer is complete. 00068 (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold 00069 is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete. 00070 (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and 00071 HAL_QSPI_RxCpltCallback() will be called when the transfer is complete. 00072 00073 *** Auto-polling functional mode *** 00074 ==================================== 00075 [..] 00076 (#) Configure the command sequence and the auto-polling functional mode using the 00077 HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions : 00078 (++) Instruction phase : the mode used and if present the instruction opcode. 00079 (++) Address phase : the mode used and if present the size and the address value. 00080 (++) Alternate-bytes phase : the mode used and if present the size and the alternate 00081 bytes values. 00082 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). 00083 (++) Data phase : the mode used. 00084 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 00085 if activated. 00086 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. 00087 (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND), 00088 the polling interval and the automatic stop activation. 00089 (#) After the configuration : 00090 (++) In polling mode, the output of the function is done when the status match is reached. The 00091 automatic stop is activated to avoid an infinite loop. 00092 (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached. 00093 00094 *** Memory-mapped functional mode *** 00095 ===================================== 00096 [..] 00097 (#) Configure the command sequence and the memory-mapped functional mode using the 00098 HAL_QSPI_MemoryMapped() functions : 00099 (++) Instruction phase : the mode used and if present the instruction opcode. 00100 (++) Address phase : the mode used and the size. 00101 (++) Alternate-bytes phase : the mode used and if present the size and the alternate 00102 bytes values. 00103 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). 00104 (++) Data phase : the mode used. 00105 (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay 00106 if activated. 00107 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. 00108 (++) The timeout activation and the timeout period. 00109 (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on 00110 the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires. 00111 00112 *** Errors management and abort functionality *** 00113 ================================================== 00114 [..] 00115 (#) HAL_QSPI_GetError() function gives the error raised during the last operation. 00116 (#) HAL_QSPI_Abort() function aborts any on-going operation and flushes the fifo. 00117 (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver. 00118 00119 *** Workarounds linked to Silicon Limitation *** 00120 ==================================================== 00121 [..] 00122 (#) Workarounds Implemented inside HAL Driver 00123 (++) Extra data written in the FIFO at the end of a read transfer 00124 00125 @endverbatim 00126 ****************************************************************************** 00127 * @attention 00128 * 00129 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00130 * 00131 * Redistribution and use in source and binary forms, with or without modification, 00132 * are permitted provided that the following conditions are met: 00133 * 1. Redistributions of source code must retain the above copyright notice, 00134 * this list of conditions and the following disclaimer. 00135 * 2. Redistributions in binary form must reproduce the above copyright notice, 00136 * this list of conditions and the following disclaimer in the documentation 00137 * and/or other materials provided with the distribution. 00138 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00139 * may be used to endorse or promote products derived from this software 00140 * without specific prior written permission. 00141 * 00142 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00143 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00144 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00145 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00146 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00147 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00148 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00149 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00150 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00151 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00152 * 00153 ****************************************************************************** 00154 */ 00155 00156 /* Includes ------------------------------------------------------------------*/ 00157 #include "stm32l4xx_hal.h" 00158 00159 /** @addtogroup STM32L4xx_HAL_Driver 00160 * @{ 00161 */ 00162 00163 /** @defgroup QSPI QSPI 00164 * @brief QSPI HAL module driver 00165 * @{ 00166 */ 00167 #ifdef HAL_QSPI_MODULE_ENABLED 00168 00169 /* Private typedef -----------------------------------------------------------*/ 00170 00171 /* Private define ------------------------------------------------------------*/ 00172 /** @defgroup QSPI_Private_Constants QSPI Private Constants 00173 * @{ 00174 */ 00175 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!<Indirect write mode*/ 00176 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/ 00177 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/ 00178 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/ 00179 /** 00180 * @} 00181 */ 00182 00183 /* Private macro -------------------------------------------------------------*/ 00184 /** @defgroup QSPI_Private_Macros QSPI Private Macros 00185 * @{ 00186 */ 00187 #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \ 00188 ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \ 00189 ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \ 00190 ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)) 00191 /** 00192 * @} 00193 */ 00194 00195 /* Private variables ---------------------------------------------------------*/ 00196 00197 /* Private function prototypes -----------------------------------------------*/ 00198 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma); 00199 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma); 00200 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00201 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00202 static void QSPI_DMAError(DMA_HandleTypeDef *hdma); 00203 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Timeout); 00204 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode); 00205 00206 /* Exported functions --------------------------------------------------------*/ 00207 00208 /** @defgroup QSPI_Exported_Functions QSPI Exported Functions 00209 * @{ 00210 */ 00211 00212 /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions 00213 * @brief Initialization and Configuration functions 00214 * 00215 @verbatim 00216 =============================================================================== 00217 ##### Initialization and Configuration functions ##### 00218 =============================================================================== 00219 [..] 00220 This subsection provides a set of functions allowing to : 00221 (+) Initialize the QuadSPI. 00222 (+) De-initialize the QuadSPI. 00223 00224 @endverbatim 00225 * @{ 00226 */ 00227 00228 /** 00229 * @brief Initialize the QSPI mode according to the specified parameters 00230 * in the QSPI_InitTypeDef and initialize the associated handle. 00231 * @param hqspi: QSPI handle 00232 * @retval HAL status 00233 */ 00234 HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi) 00235 { 00236 HAL_StatusTypeDef status = HAL_ERROR; 00237 00238 /* Check the QSPI handle allocation */ 00239 if(hqspi == NULL) 00240 { 00241 return HAL_ERROR; 00242 } 00243 00244 /* Check the parameters */ 00245 assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance)); 00246 assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler)); 00247 assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold)); 00248 assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting)); 00249 assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize)); 00250 assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime)); 00251 assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode)); 00252 00253 /* Process locked */ 00254 __HAL_LOCK(hqspi); 00255 00256 if(hqspi->State == HAL_QSPI_STATE_RESET) 00257 { 00258 /* Allocate lock resource and initialize it */ 00259 hqspi->Lock = HAL_UNLOCKED; 00260 00261 /* Init the low level hardware : GPIO, CLOCK */ 00262 HAL_QSPI_MspInit(hqspi); 00263 00264 /* Configure the default timeout for the QSPI memory access */ 00265 HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE); 00266 } 00267 00268 /* Configure QSPI FIFO Threshold */ 00269 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, 00270 ((hqspi->Init.FifoThreshold - 1) << POSITION_VAL(QUADSPI_CR_FTHRES))); 00271 00272 /* Wait till BUSY flag reset */ 00273 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); 00274 00275 if(status == HAL_OK) 00276 { 00277 /* Configure QSPI Clock Prescaler and Sample Shift */ 00278 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT), 00279 ((hqspi->Init.ClockPrescaler << POSITION_VAL(QUADSPI_CR_PRESCALER)) | 00280 hqspi->Init.SampleShifting)); 00281 00282 /* Configure QSPI Flash Size, CS High Time and Clock Mode */ 00283 MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE), 00284 ((hqspi->Init.FlashSize << POSITION_VAL(QUADSPI_DCR_FSIZE)) | 00285 hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode)); 00286 00287 /* Enable the QSPI peripheral */ 00288 __HAL_QSPI_ENABLE(hqspi); 00289 00290 /* Set QSPI error code to none */ 00291 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00292 00293 /* Initialize the QSPI state */ 00294 hqspi->State = HAL_QSPI_STATE_READY; 00295 } 00296 00297 /* Release Lock */ 00298 __HAL_UNLOCK(hqspi); 00299 00300 /* Return function status */ 00301 return status; 00302 } 00303 00304 /** 00305 * @brief De-Initialize the QSPI peripheral. 00306 * @param hqspi: QSPI handle 00307 * @retval HAL status 00308 */ 00309 HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi) 00310 { 00311 /* Check the QSPI handle allocation */ 00312 if(hqspi == NULL) 00313 { 00314 return HAL_ERROR; 00315 } 00316 00317 /* Process locked */ 00318 __HAL_LOCK(hqspi); 00319 00320 /* Disable the QSPI Peripheral Clock */ 00321 __HAL_QSPI_DISABLE(hqspi); 00322 00323 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ 00324 HAL_QSPI_MspDeInit(hqspi); 00325 00326 /* Set QSPI error code to none */ 00327 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00328 00329 /* Initialize the QSPI state */ 00330 hqspi->State = HAL_QSPI_STATE_RESET; 00331 00332 /* Release Lock */ 00333 __HAL_UNLOCK(hqspi); 00334 00335 return HAL_OK; 00336 } 00337 00338 /** 00339 * @brief Initialize the QSPI MSP. 00340 * @param hqspi: QSPI handle 00341 * @retval None 00342 */ 00343 __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi) 00344 { 00345 /* NOTE : This function should not be modified, when the callback is needed, 00346 the HAL_QSPI_MspInit can be implemented in the user file 00347 */ 00348 } 00349 00350 /** 00351 * @brief DeInitialize the QSPI MSP. 00352 * @param hqspi: QSPI handle 00353 * @retval None 00354 */ 00355 __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi) 00356 { 00357 /* NOTE : This function should not be modified, when the callback is needed, 00358 the HAL_QSPI_MspDeInit can be implemented in the user file 00359 */ 00360 } 00361 00362 /** 00363 * @} 00364 */ 00365 00366 /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions 00367 * @brief QSPI Transmit/Receive functions 00368 * 00369 @verbatim 00370 =============================================================================== 00371 ##### IO operation functions ##### 00372 =============================================================================== 00373 [..] 00374 This subsection provides a set of functions allowing to : 00375 (+) Handle the interrupts. 00376 (+) Handle the command sequence. 00377 (+) Transmit data in blocking, interrupt or DMA mode. 00378 (+) Receive data in blocking, interrupt or DMA mode. 00379 (+) Manage the auto-polling functional mode. 00380 (+) Manage the memory-mapped functional mode. 00381 00382 @endverbatim 00383 * @{ 00384 */ 00385 00386 /** 00387 * @brief Handle QSPI interrupt request. 00388 * @param hqspi: QSPI handle 00389 * @retval None 00390 */ 00391 void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi) 00392 { 00393 __IO uint32_t *data_reg; 00394 uint32_t flag = 0, itsource = 0; 00395 00396 /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/ 00397 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT); 00398 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_FT); 00399 00400 if((flag != RESET) && (itsource != RESET)) 00401 { 00402 data_reg = &hqspi->Instance->DR; 00403 00404 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX) 00405 { 00406 /* Transmission process */ 00407 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0) 00408 { 00409 if (hqspi->TxXferCount > 0) 00410 { 00411 /* Fill the FIFO until it is full */ 00412 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++; 00413 hqspi->TxXferCount--; 00414 } 00415 else 00416 { 00417 /* No more data available for the transfer */ 00418 break; 00419 } 00420 } 00421 } 00422 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX) 00423 { 00424 /* Receiving Process */ 00425 while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0) 00426 { 00427 if (hqspi->RxXferCount > 0) 00428 { 00429 /* Read the FIFO until it is empty */ 00430 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; 00431 hqspi->RxXferCount--; 00432 } 00433 else 00434 { 00435 /* All data have been received for the transfer */ 00436 break; 00437 } 00438 } 00439 } 00440 00441 /* FIFO Threshold callback */ 00442 HAL_QSPI_FifoThresholdCallback(hqspi); 00443 } 00444 00445 /* QSPI Transfer Complete interrupt occurred -------------------------------*/ 00446 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TC); 00447 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TC); 00448 00449 if((flag != RESET) && (itsource != RESET)) 00450 { 00451 /* Clear interrupt */ 00452 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 00453 00454 /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */ 00455 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT); 00456 00457 /* Transfer complete callback */ 00458 if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX) 00459 { 00460 /* Clear Busy bit */ 00461 HAL_QSPI_Abort(hqspi); 00462 00463 /* TX Complete callback */ 00464 HAL_QSPI_TxCpltCallback(hqspi); 00465 } 00466 else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX) 00467 { 00468 data_reg = &hqspi->Instance->DR; 00469 while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0) 00470 { 00471 if (hqspi->RxXferCount > 0) 00472 { 00473 /* Read the last data received in the FIFO until it is empty */ 00474 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; 00475 hqspi->RxXferCount--; 00476 } 00477 else 00478 { 00479 /* All data have been received for the transfer */ 00480 break; 00481 } 00482 } 00483 00484 /* Workaround - Extra data written in the FIFO at the end of a read transfer */ 00485 HAL_QSPI_Abort(hqspi); 00486 00487 /* RX Complete callback */ 00488 HAL_QSPI_RxCpltCallback(hqspi); 00489 } 00490 else if(hqspi->State == HAL_QSPI_STATE_BUSY) 00491 { 00492 /* Command Complete callback */ 00493 HAL_QSPI_CmdCpltCallback(hqspi); 00494 } 00495 00496 /* Change state of QSPI */ 00497 hqspi->State = HAL_QSPI_STATE_READY; 00498 } 00499 00500 /* QSPI Status Match interrupt occurred ------------------------------------*/ 00501 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_SM); 00502 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_SM); 00503 00504 if((flag != RESET) && (itsource != RESET)) 00505 { 00506 /* Clear interrupt */ 00507 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM); 00508 00509 /* Check if the automatic poll mode stop is activated */ 00510 if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0) 00511 { 00512 /* Disable the QSPI Transfer Error and Status Match Interrupts */ 00513 __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE)); 00514 00515 /* Change state of QSPI */ 00516 hqspi->State = HAL_QSPI_STATE_READY; 00517 } 00518 00519 /* Status match callback */ 00520 HAL_QSPI_StatusMatchCallback(hqspi); 00521 } 00522 00523 /* QSPI Transfer Error interrupt occurred ----------------------------------*/ 00524 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TE); 00525 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TE); 00526 00527 if((flag != RESET) && (itsource != RESET)) 00528 { 00529 /* Clear interrupt */ 00530 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE); 00531 00532 /* Disable all the QSPI Interrupts */ 00533 __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT); 00534 00535 /* Set error code */ 00536 hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER; 00537 00538 /* Change state of QSPI */ 00539 hqspi->State = HAL_QSPI_STATE_ERROR; 00540 00541 /* Error callback */ 00542 HAL_QSPI_ErrorCallback(hqspi); 00543 } 00544 00545 /* QSPI Timeout interrupt occurred -----------------------------------------*/ 00546 flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TO); 00547 itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TO); 00548 00549 if((flag != RESET) && (itsource != RESET)) 00550 { 00551 /* Clear interrupt */ 00552 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO); 00553 00554 /* Timeout callback */ 00555 HAL_QSPI_TimeOutCallback(hqspi); 00556 } 00557 } 00558 00559 /** 00560 * @brief Set the command configuration. 00561 * @param hqspi: QSPI handle 00562 * @param cmd : structure that contains the command configuration information 00563 * @param Timeout : Timeout duration 00564 * @note This function is used only in Indirect Read or Write Modes 00565 * @retval HAL status 00566 */ 00567 HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout) 00568 { 00569 HAL_StatusTypeDef status = HAL_ERROR; 00570 00571 /* Check the parameters */ 00572 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 00573 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 00574 { 00575 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); 00576 } 00577 00578 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); 00579 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 00580 { 00581 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); 00582 } 00583 00584 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); 00585 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 00586 { 00587 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); 00588 } 00589 00590 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); 00591 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); 00592 00593 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); 00594 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); 00595 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); 00596 00597 /* Process locked */ 00598 __HAL_LOCK(hqspi); 00599 00600 if(hqspi->State == HAL_QSPI_STATE_READY) 00601 { 00602 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00603 00604 /* Update QSPI state */ 00605 hqspi->State = HAL_QSPI_STATE_BUSY; 00606 00607 /* Wait till BUSY flag reset */ 00608 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout); 00609 00610 if (status == HAL_OK) 00611 { 00612 /* Call the configuration function */ 00613 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 00614 00615 if (cmd->DataMode == QSPI_DATA_NONE) 00616 { 00617 /* When there is no data phase, the transfer start as soon as the configuration is done 00618 so wait until TC flag is set to go back in idle state */ 00619 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) 00620 { 00621 status = HAL_TIMEOUT; 00622 } 00623 else 00624 { 00625 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 00626 00627 /* Update QSPI state */ 00628 hqspi->State = HAL_QSPI_STATE_READY; 00629 } 00630 00631 } 00632 else 00633 { 00634 /* Update QSPI state */ 00635 hqspi->State = HAL_QSPI_STATE_READY; 00636 } 00637 } 00638 } 00639 else 00640 { 00641 status = HAL_BUSY; 00642 } 00643 00644 /* Process unlocked */ 00645 __HAL_UNLOCK(hqspi); 00646 00647 /* Return function status */ 00648 return status; 00649 } 00650 00651 /** 00652 * @brief Set the command configuration in interrupt mode. 00653 * @param hqspi: QSPI handle 00654 * @param cmd : structure that contains the command configuration information 00655 * @note This function is used only in Indirect Read or Write Modes 00656 * @retval HAL status 00657 */ 00658 HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd) 00659 { 00660 HAL_StatusTypeDef status = HAL_ERROR; 00661 00662 /* Check the parameters */ 00663 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 00664 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 00665 { 00666 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); 00667 } 00668 00669 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); 00670 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 00671 { 00672 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); 00673 } 00674 00675 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); 00676 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 00677 { 00678 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); 00679 } 00680 00681 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); 00682 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); 00683 00684 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); 00685 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); 00686 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); 00687 00688 /* Process locked */ 00689 __HAL_LOCK(hqspi); 00690 00691 if(hqspi->State == HAL_QSPI_STATE_READY) 00692 { 00693 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00694 00695 /* Update QSPI state */ 00696 hqspi->State = HAL_QSPI_STATE_BUSY; 00697 00698 /* Wait till BUSY flag reset */ 00699 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); 00700 00701 if (status == HAL_OK) 00702 { 00703 if (cmd->DataMode == QSPI_DATA_NONE) 00704 { 00705 /* When there is no data phase, the transfer start as soon as the configuration is done 00706 so activate TC and TE interrupts */ 00707 /* Clear interrupt */ 00708 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC); 00709 00710 /* Enable the QSPI Transfer Error Interrupt */ 00711 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC); 00712 } 00713 00714 /* Call the configuration function */ 00715 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 00716 00717 if (cmd->DataMode != QSPI_DATA_NONE) 00718 { 00719 /* Update QSPI state */ 00720 hqspi->State = HAL_QSPI_STATE_READY; 00721 } 00722 } 00723 } 00724 else 00725 { 00726 status = HAL_BUSY; 00727 } 00728 00729 /* Process unlocked */ 00730 __HAL_UNLOCK(hqspi); 00731 00732 /* Return function status */ 00733 return status; 00734 } 00735 00736 /** 00737 * @brief Transmit an amount of data in blocking mode. 00738 * @param hqspi: QSPI handle 00739 * @param pData: pointer to data buffer 00740 * @param Timeout : Timeout duration 00741 * @note This function is used only in Indirect Write Mode 00742 * @retval HAL status 00743 */ 00744 HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout) 00745 { 00746 HAL_StatusTypeDef status = HAL_OK; 00747 __IO uint32_t *data_reg = &hqspi->Instance->DR; 00748 00749 /* Process locked */ 00750 __HAL_LOCK(hqspi); 00751 00752 if(hqspi->State == HAL_QSPI_STATE_READY) 00753 { 00754 if(pData != NULL ) 00755 { 00756 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00757 00758 /* Update state */ 00759 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; 00760 00761 /* Configure counters and size of the handle */ 00762 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 00763 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 00764 hqspi->pTxBuffPtr = pData; 00765 00766 /* Configure QSPI: CCR register with functional as indirect write */ 00767 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 00768 00769 while(hqspi->TxXferCount > 0) 00770 { 00771 /* Wait until FT flag is set to send data */ 00772 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, Timeout) != HAL_OK) 00773 { 00774 status = HAL_TIMEOUT; 00775 break; 00776 } 00777 00778 *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++; 00779 hqspi->TxXferCount--; 00780 } 00781 00782 if (status == HAL_OK) 00783 { 00784 /* Wait until TC flag is set to go back in idle state */ 00785 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) 00786 { 00787 status = HAL_TIMEOUT; 00788 } 00789 else 00790 { 00791 /* Clear Transfer Complete bit */ 00792 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 00793 00794 /* Clear Busy bit */ 00795 status = HAL_QSPI_Abort(hqspi); 00796 } 00797 } 00798 00799 /* Update QSPI state */ 00800 hqspi->State = HAL_QSPI_STATE_READY; 00801 } 00802 else 00803 { 00804 status = HAL_ERROR; 00805 } 00806 } 00807 else 00808 { 00809 status = HAL_BUSY; 00810 } 00811 00812 /* Process unlocked */ 00813 __HAL_UNLOCK(hqspi); 00814 00815 return status; 00816 } 00817 00818 00819 /** 00820 * @brief Receive an amount of data in blocking mode. 00821 * @param hqspi: QSPI handle 00822 * @param pData: pointer to data buffer 00823 * @param Timeout : Timeout duration 00824 * @note This function is used only in Indirect Read Mode 00825 * @retval HAL status 00826 */ 00827 HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout) 00828 { 00829 HAL_StatusTypeDef status = HAL_OK; 00830 uint32_t addr_reg = READ_REG(hqspi->Instance->AR); 00831 __IO uint32_t *data_reg = &hqspi->Instance->DR; 00832 00833 /* Process locked */ 00834 __HAL_LOCK(hqspi); 00835 00836 if(hqspi->State == HAL_QSPI_STATE_READY) 00837 { 00838 if(pData != NULL ) 00839 { 00840 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00841 00842 /* Update state */ 00843 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; 00844 00845 /* Configure counters and size of the handle */ 00846 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 00847 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 00848 hqspi->pRxBuffPtr = pData; 00849 00850 /* Configure QSPI: CCR register with functional as indirect read */ 00851 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); 00852 00853 /* Start the transfer by re-writing the address in AR register */ 00854 WRITE_REG(hqspi->Instance->AR, addr_reg); 00855 00856 while(hqspi->RxXferCount > 0) 00857 { 00858 /* Wait until FT or TC flag is set to read received data */ 00859 if(QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, Timeout) != HAL_OK) 00860 { 00861 status = HAL_TIMEOUT; 00862 break; 00863 } 00864 00865 *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; 00866 hqspi->RxXferCount--; 00867 } 00868 00869 if (status == HAL_OK) 00870 { 00871 /* Wait until TC flag is set to go back in idle state */ 00872 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) 00873 { 00874 status = HAL_TIMEOUT; 00875 } 00876 else 00877 { 00878 /* Clear Transfer Complete bit */ 00879 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 00880 00881 /* Workaround - Extra data written in the FIFO at the end of a read transfer */ 00882 status = HAL_QSPI_Abort(hqspi); 00883 } 00884 } 00885 00886 /* Update QSPI state */ 00887 hqspi->State = HAL_QSPI_STATE_READY; 00888 } 00889 else 00890 { 00891 status = HAL_ERROR; 00892 } 00893 } 00894 else 00895 { 00896 status = HAL_BUSY; 00897 } 00898 00899 /* Process unlocked */ 00900 __HAL_UNLOCK(hqspi); 00901 00902 return status; 00903 } 00904 00905 /** 00906 * @brief Send an amount of data in non-blocking mode with interrupt. 00907 * @param hqspi: QSPI handle 00908 * @param pData: pointer to data buffer 00909 * @note This function is used only in Indirect Write Mode 00910 * @retval HAL status 00911 */ 00912 HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData) 00913 { 00914 HAL_StatusTypeDef status = HAL_OK; 00915 00916 /* Process locked */ 00917 __HAL_LOCK(hqspi); 00918 00919 if(hqspi->State == HAL_QSPI_STATE_READY) 00920 { 00921 if(pData != NULL ) 00922 { 00923 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00924 00925 /* Update state */ 00926 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; 00927 00928 /* Configure counters and size of the handle */ 00929 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 00930 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 00931 hqspi->pTxBuffPtr = pData; 00932 00933 /* Configure QSPI: CCR register with functional as indirect write */ 00934 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 00935 00936 /* Clear interrupt */ 00937 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC); 00938 00939 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */ 00940 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC); 00941 } 00942 else 00943 { 00944 status = HAL_ERROR; 00945 } 00946 } 00947 else 00948 { 00949 status = HAL_BUSY; 00950 } 00951 00952 /* Process unlocked */ 00953 __HAL_UNLOCK(hqspi); 00954 00955 return status; 00956 } 00957 00958 /** 00959 * @brief Receive an amount of data in non-blocking mode with interrupt. 00960 * @param hqspi: QSPI handle 00961 * @param pData: pointer to data buffer 00962 * @note This function is used only in Indirect Read Mode 00963 * @retval HAL status 00964 */ 00965 HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData) 00966 { 00967 HAL_StatusTypeDef status = HAL_OK; 00968 uint32_t addr_reg = READ_REG(hqspi->Instance->AR); 00969 00970 /* Process locked */ 00971 __HAL_LOCK(hqspi); 00972 00973 if(hqspi->State == HAL_QSPI_STATE_READY) 00974 { 00975 if(pData != NULL ) 00976 { 00977 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 00978 00979 /* Update state */ 00980 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; 00981 00982 /* Configure counters and size of the handle */ 00983 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 00984 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 00985 hqspi->pRxBuffPtr = pData; 00986 00987 /* Configure QSPI: CCR register with functional as indirect read */ 00988 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); 00989 00990 /* Start the transfer by re-writing the address in AR register */ 00991 WRITE_REG(hqspi->Instance->AR, addr_reg); 00992 00993 /* Clear interrupt */ 00994 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC); 00995 00996 /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */ 00997 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC); 00998 } 00999 else 01000 { 01001 status = HAL_ERROR; 01002 } 01003 } 01004 else 01005 { 01006 status = HAL_BUSY; 01007 } 01008 01009 /* Process unlocked */ 01010 __HAL_UNLOCK(hqspi); 01011 01012 return status; 01013 } 01014 01015 /** 01016 * @brief Send an amount of data in non-blocking mode with DMA. 01017 * @param hqspi: QSPI handle 01018 * @param pData: pointer to data buffer 01019 * @note This function is used only in Indirect Write Mode 01020 * @retval HAL status 01021 */ 01022 HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData) 01023 { 01024 HAL_StatusTypeDef status = HAL_OK; 01025 uint32_t *tmp; 01026 01027 /* Process locked */ 01028 __HAL_LOCK(hqspi); 01029 01030 if(hqspi->State == HAL_QSPI_STATE_READY) 01031 { 01032 if(pData != NULL ) 01033 { 01034 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 01035 01036 /* Update state */ 01037 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; 01038 01039 /* Configure counters and size of the handle */ 01040 hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 01041 hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 01042 hqspi->pTxBuffPtr = pData; 01043 01044 /* Configure QSPI: CCR register with functional mode as indirect write */ 01045 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 01046 01047 /* Set the QSPI DMA transfer complete callback */ 01048 hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt; 01049 01050 /* Set the QSPI DMA Half transfer complete callback */ 01051 hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt; 01052 01053 /* Set the DMA error callback */ 01054 hqspi->hdma->XferErrorCallback = QSPI_DMAError; 01055 01056 /* Configure the direction of the DMA */ 01057 hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; 01058 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction); 01059 01060 /* Enable the QSPI transmit DMA Channel */ 01061 tmp = (uint32_t*)&pData; 01062 HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize); 01063 01064 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */ 01065 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); 01066 } 01067 else 01068 { 01069 status = HAL_OK; 01070 } 01071 } 01072 else 01073 { 01074 status = HAL_BUSY; 01075 } 01076 01077 /* Process unlocked */ 01078 __HAL_UNLOCK(hqspi); 01079 01080 return status; 01081 } 01082 01083 /** 01084 * @brief Receive an amount of data in non-blocking mode with DMA. 01085 * @param hqspi: QSPI handle 01086 * @param pData: pointer to data buffer. 01087 * @note This function is used only in Indirect Read Mode 01088 * @retval HAL status 01089 */ 01090 HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData) 01091 { 01092 HAL_StatusTypeDef status = HAL_OK; 01093 uint32_t *tmp; 01094 uint32_t addr_reg = READ_REG(hqspi->Instance->AR); 01095 01096 /* Process locked */ 01097 __HAL_LOCK(hqspi); 01098 01099 if(hqspi->State == HAL_QSPI_STATE_READY) 01100 { 01101 if(pData != NULL ) 01102 { 01103 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 01104 01105 /* Update state */ 01106 hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; 01107 01108 /* Configure counters and size of the handle */ 01109 hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; 01110 hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; 01111 hqspi->pRxBuffPtr = pData; 01112 01113 /* Set the QSPI DMA transfer complete callback */ 01114 hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt; 01115 01116 /* Set the QSPI DMA Half transfer complete callback */ 01117 hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt; 01118 01119 /* Set the DMA error callback */ 01120 hqspi->hdma->XferErrorCallback = QSPI_DMAError; 01121 01122 /* Configure the direction of the DMA */ 01123 hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; 01124 MODIFY_REG(hqspi->hdma->Instance->CCR, DMA_CCR_DIR, hqspi->hdma->Init.Direction); 01125 01126 /* Enable the DMA Channel */ 01127 tmp = (uint32_t*)&pData; 01128 HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize); 01129 01130 /* Configure QSPI: CCR register with functional as indirect read */ 01131 MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); 01132 01133 /* Start the transfer by re-writing the address in AR register */ 01134 WRITE_REG(hqspi->Instance->AR, addr_reg); 01135 01136 /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */ 01137 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); 01138 } 01139 else 01140 { 01141 status = HAL_ERROR; 01142 } 01143 } 01144 else 01145 { 01146 status = HAL_BUSY; 01147 } 01148 01149 /* Process unlocked */ 01150 __HAL_UNLOCK(hqspi); 01151 01152 return status; 01153 } 01154 01155 /** 01156 * @brief Configure the QSPI Automatic Polling Mode in blocking mode. 01157 * @param hqspi: QSPI handle 01158 * @param cmd: structure that contains the command configuration information. 01159 * @param cfg: structure that contains the polling configuration information. 01160 * @param Timeout : Timeout duration 01161 * @note This function is used only in Automatic Polling Mode 01162 * @retval HAL status 01163 */ 01164 HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout) 01165 { 01166 HAL_StatusTypeDef status = HAL_ERROR; 01167 01168 /* Check the parameters */ 01169 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 01170 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 01171 { 01172 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); 01173 } 01174 01175 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); 01176 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01177 { 01178 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); 01179 } 01180 01181 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); 01182 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 01183 { 01184 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); 01185 } 01186 01187 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); 01188 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); 01189 01190 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); 01191 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); 01192 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); 01193 01194 assert_param(IS_QSPI_INTERVAL(cfg->Interval)); 01195 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize)); 01196 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode)); 01197 01198 /* Process locked */ 01199 __HAL_LOCK(hqspi); 01200 01201 if(hqspi->State == HAL_QSPI_STATE_READY) 01202 { 01203 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 01204 01205 /* Update state */ 01206 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING; 01207 01208 /* Wait till BUSY flag reset */ 01209 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout); 01210 01211 if (status == HAL_OK) 01212 { 01213 /* Configure QSPI: PSMAR register with the status match value */ 01214 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match); 01215 01216 /* Configure QSPI: PSMKR register with the status mask value */ 01217 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask); 01218 01219 /* Configure QSPI: PIR register with the interval value */ 01220 WRITE_REG(hqspi->Instance->PIR, cfg->Interval); 01221 01222 /* Configure QSPI: CR register with Match mode and Automatic stop enabled 01223 (otherwise there will be an infinite loop in blocking mode) */ 01224 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 01225 (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE)); 01226 01227 /* Call the configuration function */ 01228 cmd->NbData = cfg->StatusBytesSize; 01229 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING); 01230 01231 /* Wait until SM flag is set to go back in idle state */ 01232 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, Timeout) != HAL_OK) 01233 { 01234 status = HAL_TIMEOUT; 01235 } 01236 else 01237 { 01238 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM); 01239 01240 /* Update state */ 01241 hqspi->State = HAL_QSPI_STATE_READY; 01242 } 01243 } 01244 } 01245 else 01246 { 01247 status = HAL_BUSY; 01248 } 01249 01250 /* Process unlocked */ 01251 __HAL_UNLOCK(hqspi); 01252 01253 /* Return function status */ 01254 return status; 01255 } 01256 01257 /** 01258 * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode. 01259 * @param hqspi: QSPI handle 01260 * @param cmd: structure that contains the command configuration information. 01261 * @param cfg: structure that contains the polling configuration information. 01262 * @note This function is used only in Automatic Polling Mode 01263 * @retval HAL status 01264 */ 01265 HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg) 01266 { 01267 HAL_StatusTypeDef status = HAL_ERROR; 01268 01269 /* Check the parameters */ 01270 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 01271 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 01272 { 01273 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); 01274 } 01275 01276 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); 01277 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01278 { 01279 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); 01280 } 01281 01282 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); 01283 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 01284 { 01285 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); 01286 } 01287 01288 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); 01289 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); 01290 01291 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); 01292 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); 01293 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); 01294 01295 assert_param(IS_QSPI_INTERVAL(cfg->Interval)); 01296 assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize)); 01297 assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode)); 01298 assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop)); 01299 01300 /* Process locked */ 01301 __HAL_LOCK(hqspi); 01302 01303 if(hqspi->State == HAL_QSPI_STATE_READY) 01304 { 01305 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 01306 01307 /* Update state */ 01308 hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING; 01309 01310 /* Wait till BUSY flag reset */ 01311 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); 01312 01313 if (status == HAL_OK) 01314 { 01315 /* Configure QSPI: PSMAR register with the status match value */ 01316 WRITE_REG(hqspi->Instance->PSMAR, cfg->Match); 01317 01318 /* Configure QSPI: PSMKR register with the status mask value */ 01319 WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask); 01320 01321 /* Configure QSPI: PIR register with the interval value */ 01322 WRITE_REG(hqspi->Instance->PIR, cfg->Interval); 01323 01324 /* Configure QSPI: CR register with Match mode and Automatic stop mode */ 01325 MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), 01326 (cfg->MatchMode | cfg->AutomaticStop)); 01327 01328 /* Clear interrupt */ 01329 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM); 01330 01331 /* Enable the QSPI Transfer Error and status match Interrupt */ 01332 __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE)); 01333 01334 /* Call the configuration function */ 01335 cmd->NbData = cfg->StatusBytesSize; 01336 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING); 01337 } 01338 } 01339 else 01340 { 01341 status = HAL_BUSY; 01342 } 01343 01344 /* Process unlocked */ 01345 __HAL_UNLOCK(hqspi); 01346 01347 /* Return function status */ 01348 return status; 01349 } 01350 01351 /** 01352 * @brief Configure the Memory Mapped mode. 01353 * @param hqspi: QSPI handle 01354 * @param cmd: structure that contains the command configuration information. 01355 * @param cfg: structure that contains the memory mapped configuration information. 01356 * @note This function is used only in Memory mapped Mode 01357 * @retval HAL status 01358 */ 01359 HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg) 01360 { 01361 HAL_StatusTypeDef status = HAL_ERROR; 01362 01363 /* Check the parameters */ 01364 assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 01365 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 01366 { 01367 assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); 01368 } 01369 01370 assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); 01371 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01372 { 01373 assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); 01374 } 01375 01376 assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); 01377 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 01378 { 01379 assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); 01380 } 01381 01382 assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); 01383 assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); 01384 01385 assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); 01386 assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); 01387 assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); 01388 01389 assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation)); 01390 01391 /* Process locked */ 01392 __HAL_LOCK(hqspi); 01393 01394 if(hqspi->State == HAL_QSPI_STATE_READY) 01395 { 01396 hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; 01397 01398 /* Update state */ 01399 hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED; 01400 01401 /* Wait till BUSY flag reset */ 01402 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); 01403 01404 if (status == HAL_OK) 01405 { 01406 /* Configure QSPI: CR register with timeout counter enable */ 01407 MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation); 01408 01409 if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE) 01410 { 01411 assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod)); 01412 01413 /* Configure QSPI: LPTR register with the low-power timeout value */ 01414 WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod); 01415 01416 /* Clear interrupt */ 01417 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO); 01418 01419 /* Enable the QSPI TimeOut Interrupt */ 01420 __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO); 01421 } 01422 01423 /* Call the configuration function */ 01424 QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED); 01425 } 01426 } 01427 else 01428 { 01429 status = HAL_BUSY; 01430 } 01431 01432 /* Process unlocked */ 01433 __HAL_UNLOCK(hqspi); 01434 01435 /* Return function status */ 01436 return status; 01437 } 01438 01439 /** 01440 * @brief Transfer Error callback. 01441 * @param hqspi: QSPI handle 01442 * @retval None 01443 */ 01444 __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi) 01445 { 01446 /* NOTE : This function should not be modified, when the callback is needed, 01447 the HAL_QSPI_ErrorCallback could be implemented in the user file 01448 */ 01449 } 01450 01451 /** 01452 * @brief Command completed callback. 01453 * @param hqspi: QSPI handle 01454 * @retval None 01455 */ 01456 __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi) 01457 { 01458 /* NOTE: This function should not be modified, when the callback is needed, 01459 the HAL_QSPI_CmdCpltCallback could be implemented in the user file 01460 */ 01461 } 01462 01463 /** 01464 * @brief Rx Transfer completed callback. 01465 * @param hqspi: QSPI handle 01466 * @retval None 01467 */ 01468 __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi) 01469 { 01470 /* NOTE: This function should not be modified, when the callback is needed, 01471 the HAL_QSPI_RxCpltCallback could be implemented in the user file 01472 */ 01473 } 01474 01475 /** 01476 * @brief Tx Transfer completed callback. 01477 * @param hqspi: QSPI handle 01478 * @retval None 01479 */ 01480 __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi) 01481 { 01482 /* NOTE: This function should not be modified, when the callback is needed, 01483 the HAL_QSPI_TxCpltCallback could be implemented in the user file 01484 */ 01485 } 01486 01487 /** 01488 * @brief Rx Half Transfer completed callback. 01489 * @param hqspi: QSPI handle 01490 * @retval None 01491 */ 01492 __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi) 01493 { 01494 /* NOTE: This function should not be modified, when the callback is needed, 01495 the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file 01496 */ 01497 } 01498 01499 /** 01500 * @brief Tx Half Transfer completed callback. 01501 * @param hqspi: QSPI handle 01502 * @retval None 01503 */ 01504 __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi) 01505 { 01506 /* NOTE: This function should not be modified, when the callback is needed, 01507 the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file 01508 */ 01509 } 01510 01511 /** 01512 * @brief FIFO Threshold callback. 01513 * @param hqspi: QSPI handle 01514 * @retval None 01515 */ 01516 __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi) 01517 { 01518 /* NOTE : This function should not be modified, when the callback is needed, 01519 the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file 01520 */ 01521 } 01522 01523 /** 01524 * @brief Status Match callback. 01525 * @param hqspi: QSPI handle 01526 * @retval None 01527 */ 01528 __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi) 01529 { 01530 /* NOTE : This function should not be modified, when the callback is needed, 01531 the HAL_QSPI_StatusMatchCallback could be implemented in the user file 01532 */ 01533 } 01534 01535 /** 01536 * @brief Timeout callback. 01537 * @param hqspi: QSPI handle 01538 * @retval None 01539 */ 01540 __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi) 01541 { 01542 /* NOTE : This function should not be modified, when the callback is needed, 01543 the HAL_QSPI_TimeOutCallback could be implemented in the user file 01544 */ 01545 } 01546 01547 /** 01548 * @} 01549 */ 01550 01551 /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions 01552 * @brief QSPI control and State functions 01553 * 01554 @verbatim 01555 =============================================================================== 01556 ##### Peripheral Control and State functions ##### 01557 =============================================================================== 01558 [..] 01559 This subsection provides a set of functions allowing to : 01560 (+) Check in run-time the state of the driver. 01561 (+) Check the error code set during last operation. 01562 (+) Abort any operation. 01563 01564 01565 @endverbatim 01566 * @{ 01567 */ 01568 01569 /** 01570 * @brief Return the QSPI handle state. 01571 * @param hqspi: QSPI handle 01572 * @retval HAL state 01573 */ 01574 HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi) 01575 { 01576 /* Return QSPI handle state */ 01577 return hqspi->State; 01578 } 01579 01580 /** 01581 * @brief Return the QSPI error code. 01582 * @param hqspi: QSPI handle 01583 * @retval QSPI Error Code 01584 */ 01585 uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi) 01586 { 01587 return hqspi->ErrorCode; 01588 } 01589 01590 /** 01591 * @brief Abort the current transmission. 01592 * @param hqspi: QSPI handle 01593 * @retval HAL status 01594 */ 01595 HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi) 01596 { 01597 HAL_StatusTypeDef status = HAL_ERROR; 01598 01599 /* Configure QSPI: CR register with Abort request */ 01600 SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT); 01601 01602 /* Wait until TC flag is set to go back in idle state */ 01603 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) 01604 { 01605 status = HAL_TIMEOUT; 01606 } 01607 else 01608 { 01609 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 01610 01611 /* Wait until BUSY flag is reset */ 01612 status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); 01613 01614 /* Update state */ 01615 hqspi->State = HAL_QSPI_STATE_READY; 01616 } 01617 01618 return status; 01619 } 01620 01621 /** @brief Set QSPI timeout. 01622 * @param hqspi: QSPI handle. 01623 * @param Timeout: Timeout for the QSPI memory access. 01624 * @retval None 01625 */ 01626 void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) 01627 { 01628 hqspi->Timeout = Timeout; 01629 } 01630 01631 /** 01632 * @} 01633 */ 01634 01635 /** 01636 * @brief DMA QSPI receive process complete callback. 01637 * @param hdma: DMA handle 01638 * @retval None 01639 */ 01640 static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma) 01641 { 01642 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01643 hqspi->RxXferCount = 0; 01644 01645 /* Wait for QSPI TC Flag */ 01646 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) 01647 { 01648 /* Timeout occurred */ 01649 HAL_QSPI_ErrorCallback(hqspi); 01650 } 01651 else 01652 { 01653 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */ 01654 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); 01655 01656 /* Disable the DMA channel */ 01657 HAL_DMA_Abort(hdma); 01658 01659 /* Clear Transfer Complete bit */ 01660 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 01661 01662 /* Workaround - Extra data written in the FIFO at the end of a read transfer */ 01663 HAL_QSPI_Abort(hqspi); 01664 01665 /* Update state */ 01666 hqspi->State = HAL_QSPI_STATE_READY; 01667 01668 HAL_QSPI_RxCpltCallback(hqspi); 01669 } 01670 } 01671 01672 /** 01673 * @brief DMA QSPI transmit process complete callback. 01674 * @param hdma: DMA handle 01675 * @retval None 01676 */ 01677 static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma) 01678 { 01679 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01680 hqspi->TxXferCount = 0; 01681 01682 /* Wait for QSPI TC Flag */ 01683 if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) 01684 { 01685 /* Timeout occurred */ 01686 HAL_QSPI_ErrorCallback(hqspi); 01687 } 01688 else 01689 { 01690 /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */ 01691 CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); 01692 01693 /* Disable the DMA channel */ 01694 HAL_DMA_Abort(hdma); 01695 01696 /* Clear Transfer Complete bit */ 01697 __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); 01698 01699 /* Clear Busy bit */ 01700 HAL_QSPI_Abort(hqspi); 01701 01702 /* Update state */ 01703 hqspi->State = HAL_QSPI_STATE_READY; 01704 01705 HAL_QSPI_TxCpltCallback(hqspi); 01706 } 01707 } 01708 01709 /** 01710 * @brief DMA QSPI receive process half complete callback. 01711 * @param hdma : DMA handle 01712 * @retval None 01713 */ 01714 static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 01715 { 01716 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 01717 01718 HAL_QSPI_RxHalfCpltCallback(hqspi); 01719 } 01720 01721 /** 01722 * @brief DMA QSPI transmit process half complete callback. 01723 * @param hdma : DMA handle 01724 * @retval None 01725 */ 01726 static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01727 { 01728 QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 01729 01730 HAL_QSPI_TxHalfCpltCallback(hqspi); 01731 } 01732 01733 /** 01734 * @brief DMA QSPI communication error callback. 01735 * @param hdma: DMA handle 01736 * @retval None 01737 */ 01738 static void QSPI_DMAError(DMA_HandleTypeDef *hdma) 01739 { 01740 QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01741 01742 hqspi->RxXferCount = 0; 01743 hqspi->TxXferCount = 0; 01744 hqspi->State = HAL_QSPI_STATE_ERROR; 01745 hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA; 01746 01747 HAL_QSPI_ErrorCallback(hqspi); 01748 } 01749 01750 /** 01751 * @brief Wait for a flag state until timeout. 01752 * @param hqspi: QSPI handle 01753 * @param Flag: Flag checked 01754 * @param State: Value of the flag expected 01755 * @param Timeout: Duration of the timeout 01756 * @retval HAL status 01757 */ 01758 static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, 01759 FlagStatus State, uint32_t Timeout) 01760 { 01761 uint32_t tickstart = HAL_GetTick(); 01762 01763 /* Wait until flag is in expected state */ 01764 while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State) 01765 { 01766 /* Check for the Timeout */ 01767 if (Timeout != HAL_MAX_DELAY) 01768 { 01769 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) 01770 { 01771 hqspi->State = HAL_QSPI_STATE_ERROR; 01772 hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT; 01773 01774 return HAL_TIMEOUT; 01775 } 01776 } 01777 } 01778 return HAL_OK; 01779 } 01780 01781 /** 01782 * @brief Configure the communication registers. 01783 * @param hqspi: QSPI handle 01784 * @param cmd: structure that contains the command configuration information 01785 * @param FunctionalMode: functional mode to configured 01786 * This parameter can be one of the following values: 01787 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode 01788 * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode 01789 * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode 01790 * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode 01791 * @retval None 01792 */ 01793 static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode) 01794 { 01795 assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode)); 01796 01797 if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)) 01798 { 01799 /* Configure QSPI: DLR register with the number of data to read or write */ 01800 WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1)); 01801 } 01802 01803 if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) 01804 { 01805 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 01806 { 01807 /* Configure QSPI: ABR register with alternate bytes value */ 01808 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes); 01809 01810 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01811 { 01812 /*---- Command with instruction, address and alternate bytes ----*/ 01813 /* Configure QSPI: CCR register with all communications parameters */ 01814 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01815 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01816 cmd->AlternateBytesSize | cmd->AlternateByteMode | 01817 cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | 01818 cmd->Instruction | FunctionalMode)); 01819 01820 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) 01821 { 01822 /* Configure QSPI: AR register with address value */ 01823 WRITE_REG(hqspi->Instance->AR, cmd->Address); 01824 } 01825 } 01826 else 01827 { 01828 /*---- Command with instruction and alternate bytes ----*/ 01829 /* Configure QSPI: CCR register with all communications parameters */ 01830 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01831 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01832 cmd->AlternateBytesSize | cmd->AlternateByteMode | 01833 cmd->AddressMode | cmd->InstructionMode | 01834 cmd->Instruction | FunctionalMode)); 01835 } 01836 } 01837 else 01838 { 01839 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01840 { 01841 /*---- Command with instruction and address ----*/ 01842 /* Configure QSPI: CCR register with all communications parameters */ 01843 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01844 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01845 cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode | 01846 cmd->InstructionMode | cmd->Instruction | FunctionalMode)); 01847 01848 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) 01849 { 01850 /* Configure QSPI: AR register with address value */ 01851 WRITE_REG(hqspi->Instance->AR, cmd->Address); 01852 } 01853 } 01854 else 01855 { 01856 /*---- Command with only instruction ----*/ 01857 /* Configure QSPI: CCR register with all communications parameters */ 01858 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01859 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01860 cmd->AlternateByteMode | cmd->AddressMode | 01861 cmd->InstructionMode | cmd->Instruction | FunctionalMode)); 01862 } 01863 } 01864 } 01865 else 01866 { 01867 if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) 01868 { 01869 /* Configure QSPI: ABR register with alternate bytes value */ 01870 WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes); 01871 01872 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01873 { 01874 /*---- Command with address and alternate bytes ----*/ 01875 /* Configure QSPI: CCR register with all communications parameters */ 01876 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01877 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01878 cmd->AlternateBytesSize | cmd->AlternateByteMode | 01879 cmd->AddressSize | cmd->AddressMode | 01880 cmd->InstructionMode | FunctionalMode)); 01881 01882 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) 01883 { 01884 /* Configure QSPI: AR register with address value */ 01885 WRITE_REG(hqspi->Instance->AR, cmd->Address); 01886 } 01887 } 01888 else 01889 { 01890 /*---- Command with only alternate bytes ----*/ 01891 /* Configure QSPI: CCR register with all communications parameters */ 01892 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01893 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01894 cmd->AlternateBytesSize | cmd->AlternateByteMode | 01895 cmd->AddressMode | cmd->InstructionMode | FunctionalMode)); 01896 } 01897 } 01898 else 01899 { 01900 if (cmd->AddressMode != QSPI_ADDRESS_NONE) 01901 { 01902 /*---- Command with only address ----*/ 01903 /* Configure QSPI: CCR register with all communications parameters */ 01904 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01905 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01906 cmd->AlternateByteMode | cmd->AddressSize | 01907 cmd->AddressMode | cmd->InstructionMode | FunctionalMode)); 01908 01909 if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) 01910 { 01911 /* Configure QSPI: AR register with address value */ 01912 WRITE_REG(hqspi->Instance->AR, cmd->Address); 01913 } 01914 } 01915 else 01916 { 01917 /*---- Command with only data phase ----*/ 01918 if (cmd->DataMode != QSPI_DATA_NONE) 01919 { 01920 /* Configure QSPI: CCR register with all communications parameters */ 01921 WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | 01922 cmd->DataMode | (cmd->DummyCycles << POSITION_VAL(QUADSPI_CCR_DCYC)) | 01923 cmd->AlternateByteMode | cmd->AddressMode | 01924 cmd->InstructionMode | FunctionalMode)); 01925 } 01926 } 01927 } 01928 } 01929 } 01930 01931 /** 01932 * @} 01933 */ 01934 01935 #endif /* HAL_QSPI_MODULE_ENABLED */ 01936 /** 01937 * @} 01938 */ 01939 01940 /** 01941 * @} 01942 */ 01943 01944 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01945
Generated on Tue Jul 12 2022 11:35:14 by 1.7.2