You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2338 lines
74 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_qspi.c
  4. * @author MCD Application Team
  5. * @version V1.2.2
  6. * @date 14-April-2017
  7. * @brief QSPI HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the QuadSPI interface (QSPI).
  10. * + Initialization and de-initialization functions
  11. * + Indirect functional mode management
  12. * + Memory-mapped functional mode management
  13. * + Auto-polling functional mode management
  14. * + Interrupts and flags management
  15. * + DMA channel configuration for indirect functional mode
  16. * + Errors management and abort functionality
  17. *
  18. *
  19. @verbatim
  20. ===============================================================================
  21. ##### How to use this driver #####
  22. ===============================================================================
  23. [..]
  24. *** Initialization ***
  25. ======================
  26. [..]
  27. (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
  28. (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
  29. (++) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
  30. (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
  31. (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
  32. (++) If interrupt mode is used, enable and configure QuadSPI global
  33. interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
  34. (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
  35. with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
  36. link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
  37. DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
  38. (#) Configure the flash size, the clock prescaler, the fifo threshold, the
  39. clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
  40. *** Indirect functional mode ***
  41. ================================
  42. [..]
  43. (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
  44. functions :
  45. (++) Instruction phase : the mode used and if present the instruction opcode.
  46. (++) Address phase : the mode used and if present the size and the address value.
  47. (++) Alternate-bytes phase : the mode used and if present the size and the alternate
  48. bytes values.
  49. (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
  50. (++) Data phase : the mode used and if present the number of bytes.
  51. (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
  52. if activated.
  53. (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
  54. (#) If no data is required for the command, it is sent directly to the memory :
  55. (++) In polling mode, the output of the function is done when the transfer is complete.
  56. (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
  57. (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
  58. HAL_QSPI_Transmit_IT() after the command configuration :
  59. (++) In polling mode, the output of the function is done when the transfer is complete.
  60. (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
  61. is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
  62. (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
  63. HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
  64. (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
  65. HAL_QSPI_Receive_IT() after the command configuration :
  66. (++) In polling mode, the output of the function is done when the transfer is complete.
  67. (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
  68. is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
  69. (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
  70. HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
  71. *** Auto-polling functional mode ***
  72. ====================================
  73. [..]
  74. (#) Configure the command sequence and the auto-polling functional mode using the
  75. HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
  76. (++) Instruction phase : the mode used and if present the instruction opcode.
  77. (++) Address phase : the mode used and if present the size and the address value.
  78. (++) Alternate-bytes phase : the mode used and if present the size and the alternate
  79. bytes values.
  80. (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
  81. (++) Data phase : the mode used.
  82. (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
  83. if activated.
  84. (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
  85. (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
  86. the polling interval and the automatic stop activation.
  87. (#) After the configuration :
  88. (++) In polling mode, the output of the function is done when the status match is reached. The
  89. automatic stop is activated to avoid an infinite loop.
  90. (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
  91. *** Memory-mapped functional mode ***
  92. =====================================
  93. [..]
  94. (#) Configure the command sequence and the memory-mapped functional mode using the
  95. HAL_QSPI_MemoryMapped() functions :
  96. (++) Instruction phase : the mode used and if present the instruction opcode.
  97. (++) Address phase : the mode used and the size.
  98. (++) Alternate-bytes phase : the mode used and if present the size and the alternate
  99. bytes values.
  100. (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
  101. (++) Data phase : the mode used.
  102. (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
  103. if activated.
  104. (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
  105. (++) The timeout activation and the timeout period.
  106. (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
  107. the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
  108. *** Errors management and abort functionality ***
  109. ==================================================
  110. [..]
  111. (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
  112. (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
  113. flushes the fifo :
  114. (++) In polling mode, the output of the function is done when the transfer
  115. complete bit is set and the busy bit cleared.
  116. (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
  117. the transfer complete bi is set.
  118. *** Control functions ***
  119. =========================
  120. [..]
  121. (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
  122. (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
  123. (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
  124. (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
  125. *** Workarounds linked to Silicon Limitation ***
  126. ====================================================
  127. [..]
  128. (#) Workarounds Implemented inside HAL Driver
  129. (++) Extra data written in the FIFO at the end of a read transfer
  130. @endverbatim
  131. ******************************************************************************
  132. * @attention
  133. *
  134. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  135. *
  136. * Redistribution and use in source and binary forms, with or without modification,
  137. * are permitted provided that the following conditions are met:
  138. * 1. Redistributions of source code must retain the above copyright notice,
  139. * this list of conditions and the following disclaimer.
  140. * 2. Redistributions in binary form must reproduce the above copyright notice,
  141. * this list of conditions and the following disclaimer in the documentation
  142. * and/or other materials provided with the distribution.
  143. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  144. * may be used to endorse or promote products derived from this software
  145. * without specific prior written permission.
  146. *
  147. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  148. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  149. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  150. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  151. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  152. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  153. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  154. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  155. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  156. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  157. *
  158. ******************************************************************************
  159. */
  160. /* Includes ------------------------------------------------------------------*/
  161. #include "stm32f7xx_hal.h"
  162. /** @addtogroup STM32F7xx_HAL_Driver
  163. * @{
  164. */
  165. /** @defgroup QSPI QSPI
  166. * @brief HAL QSPI module driver
  167. * @{
  168. */
  169. #ifdef HAL_QSPI_MODULE_ENABLED
  170. /* Private typedef -----------------------------------------------------------*/
  171. /* Private define ------------------------------------------------------------*/
  172. /** @addtogroup QSPI_Private_Constants
  173. * @{
  174. */
  175. #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000U) /*!<Indirect write mode*/
  176. #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
  177. #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
  178. #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
  179. /**
  180. * @}
  181. */
  182. /* Private macro -------------------------------------------------------------*/
  183. /** @addtogroup QSPI_Private_Macros QSPI Private Macros
  184. * @{
  185. */
  186. #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
  187. ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
  188. ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
  189. ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
  190. /**
  191. * @}
  192. */
  193. /* Private variables ---------------------------------------------------------*/
  194. /* Private function prototypes -----------------------------------------------*/
  195. /** @addtogroup QSPI_Private_Functions QSPI Private Functions
  196. * @{
  197. */
  198. static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
  199. static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
  200. static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
  201. static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
  202. static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
  203. static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
  204. static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t tickstart, uint32_t Timeout);
  205. static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
  206. /**
  207. * @}
  208. */
  209. /* Exported functions ---------------------------------------------------------*/
  210. /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
  211. * @{
  212. */
  213. /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
  214. * @brief Initialization and Configuration functions
  215. *
  216. @verbatim
  217. ===============================================================================
  218. ##### Initialization and Configuration functions #####
  219. ===============================================================================
  220. [..]
  221. This subsection provides a set of functions allowing to :
  222. (+) Initialize the QuadSPI.
  223. (+) De-initialize the QuadSPI.
  224. @endverbatim
  225. * @{
  226. */
  227. /**
  228. * @brief Initializes the QSPI mode according to the specified parameters
  229. * in the QSPI_InitTypeDef and creates the associated handle.
  230. * @param hqspi: qspi handle
  231. * @retval HAL status
  232. */
  233. HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
  234. {
  235. HAL_StatusTypeDef status = HAL_ERROR;
  236. uint32_t tickstart = HAL_GetTick();
  237. /* Check the QSPI handle allocation */
  238. if(hqspi == NULL)
  239. {
  240. return HAL_ERROR;
  241. }
  242. /* Check the parameters */
  243. assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
  244. assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
  245. assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
  246. assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
  247. assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
  248. assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
  249. assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
  250. assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
  251. if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
  252. {
  253. assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
  254. }
  255. /* Process locked */
  256. __HAL_LOCK(hqspi);
  257. if(hqspi->State == HAL_QSPI_STATE_RESET)
  258. {
  259. /* Allocate lock resource and initialize it */
  260. hqspi->Lock = HAL_UNLOCKED;
  261. /* Init the low level hardware : GPIO, CLOCK */
  262. HAL_QSPI_MspInit(hqspi);
  263. /* Configure the default timeout for the QSPI memory access */
  264. HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
  265. }
  266. /* Configure QSPI FIFO Threshold */
  267. MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, ((hqspi->Init.FifoThreshold - 1) << 8));
  268. /* Wait till BUSY flag reset */
  269. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
  270. if(status == HAL_OK)
  271. {
  272. /* Configure QSPI Clock Prescaler and Sample Shift */
  273. MODIFY_REG(hqspi->Instance->CR,(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM), ((hqspi->Init.ClockPrescaler << 24)| hqspi->Init.SampleShifting | hqspi->Init.FlashID| hqspi->Init.DualFlash ));
  274. /* Configure QSPI Flash Size, CS High Time and Clock Mode */
  275. MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
  276. ((hqspi->Init.FlashSize << 16) | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
  277. /* Enable the QSPI peripheral */
  278. __HAL_QSPI_ENABLE(hqspi);
  279. /* Set QSPI error code to none */
  280. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  281. /* Initialize the QSPI state */
  282. hqspi->State = HAL_QSPI_STATE_READY;
  283. }
  284. /* Release Lock */
  285. __HAL_UNLOCK(hqspi);
  286. /* Return function status */
  287. return status;
  288. }
  289. /**
  290. * @brief DeInitializes the QSPI peripheral
  291. * @param hqspi: qspi handle
  292. * @retval HAL status
  293. */
  294. HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
  295. {
  296. /* Check the QSPI handle allocation */
  297. if(hqspi == NULL)
  298. {
  299. return HAL_ERROR;
  300. }
  301. /* Process locked */
  302. __HAL_LOCK(hqspi);
  303. /* Disable the QSPI Peripheral Clock */
  304. __HAL_QSPI_DISABLE(hqspi);
  305. /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
  306. HAL_QSPI_MspDeInit(hqspi);
  307. /* Set QSPI error code to none */
  308. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  309. /* Initialize the QSPI state */
  310. hqspi->State = HAL_QSPI_STATE_RESET;
  311. /* Release Lock */
  312. __HAL_UNLOCK(hqspi);
  313. return HAL_OK;
  314. }
  315. /**
  316. * @brief QSPI MSP Init
  317. * @param hqspi: QSPI handle
  318. * @retval None
  319. */
  320. __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
  321. {
  322. /* Prevent unused argument(s) compilation warning */
  323. UNUSED(hqspi);
  324. /* NOTE : This function should not be modified, when the callback is needed,
  325. the HAL_QSPI_MspInit can be implemented in the user file
  326. */
  327. }
  328. /**
  329. * @brief QSPI MSP DeInit
  330. * @param hqspi: QSPI handle
  331. * @retval None
  332. */
  333. __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
  334. {
  335. /* Prevent unused argument(s) compilation warning */
  336. UNUSED(hqspi);
  337. /* NOTE : This function should not be modified, when the callback is needed,
  338. the HAL_QSPI_MspDeInit can be implemented in the user file
  339. */
  340. }
  341. /**
  342. * @}
  343. */
  344. /** @defgroup QSPI_Exported_Functions_Group2 IO operation functions
  345. * @brief QSPI Transmit/Receive functions
  346. *
  347. @verbatim
  348. ===============================================================================
  349. ##### IO operation functions #####
  350. ===============================================================================
  351. [..]
  352. This subsection provides a set of functions allowing to :
  353. (+) Handle the interrupts.
  354. (+) Handle the command sequence.
  355. (+) Transmit data in blocking, interrupt or DMA mode.
  356. (+) Receive data in blocking, interrupt or DMA mode.
  357. (+) Manage the auto-polling functional mode.
  358. (+) Manage the memory-mapped functional mode.
  359. @endverbatim
  360. * @{
  361. */
  362. /**
  363. * @brief This function handles QSPI interrupt request.
  364. * @param hqspi: QSPI handle
  365. * @retval None.
  366. */
  367. void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
  368. {
  369. __IO uint32_t *data_reg;
  370. uint32_t flag = READ_REG(hqspi->Instance->SR);
  371. uint32_t itsource = READ_REG(hqspi->Instance->CR);
  372. /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
  373. if(((flag & QSPI_FLAG_FT)!= RESET) && ((itsource & QSPI_IT_FT)!= RESET))
  374. {
  375. data_reg = &hqspi->Instance->DR;
  376. if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
  377. {
  378. /* Transmission process */
  379. while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
  380. {
  381. if (hqspi->TxXferCount > 0)
  382. {
  383. /* Fill the FIFO until it is full */
  384. *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
  385. hqspi->TxXferCount--;
  386. }
  387. else
  388. {
  389. /* No more data available for the transfer */
  390. /* Disable the QSPI FIFO Threshold Interrupt */
  391. __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
  392. break;
  393. }
  394. }
  395. }
  396. else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
  397. {
  398. /* Receiving Process */
  399. while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0)
  400. {
  401. if (hqspi->RxXferCount > 0)
  402. {
  403. /* Read the FIFO until it is empty */
  404. *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
  405. hqspi->RxXferCount--;
  406. }
  407. else
  408. {
  409. /* All data have been received for the transfer */
  410. /* Disable the QSPI FIFO Threshold Interrupt */
  411. __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
  412. break;
  413. }
  414. }
  415. }
  416. /* FIFO Threshold callback */
  417. HAL_QSPI_FifoThresholdCallback(hqspi);
  418. }
  419. /* QSPI Transfer Complete interrupt occurred -------------------------------*/
  420. else if(((flag & QSPI_FLAG_TC)!= RESET) && ((itsource & QSPI_IT_TC)!= RESET))
  421. {
  422. /* Clear interrupt */
  423. WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
  424. /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
  425. __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
  426. /* Transfer complete callback */
  427. if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
  428. {
  429. if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
  430. {
  431. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  432. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  433. /* Disable the DMA channel */
  434. __HAL_DMA_DISABLE(hqspi->hdma);
  435. }
  436. #if defined(QSPI1_V1_0)
  437. /* Clear Busy bit */
  438. HAL_QSPI_Abort_IT(hqspi);
  439. #endif
  440. /* Change state of QSPI */
  441. hqspi->State = HAL_QSPI_STATE_READY;
  442. /* TX Complete callback */
  443. HAL_QSPI_TxCpltCallback(hqspi);
  444. }
  445. else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
  446. {
  447. if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
  448. {
  449. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  450. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  451. /* Disable the DMA channel */
  452. __HAL_DMA_DISABLE(hqspi->hdma);
  453. }
  454. else
  455. {
  456. data_reg = &hqspi->Instance->DR;
  457. while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0)
  458. {
  459. if (hqspi->RxXferCount > 0)
  460. {
  461. /* Read the last data received in the FIFO until it is empty */
  462. *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
  463. hqspi->RxXferCount--;
  464. }
  465. else
  466. {
  467. /* All data have been received for the transfer */
  468. break;
  469. }
  470. }
  471. }
  472. #if defined(QSPI1_V1_0)
  473. /* Workaround - Extra data written in the FIFO at the end of a read transfer */
  474. HAL_QSPI_Abort_IT(hqspi);
  475. #endif /* QSPI_V1_0*/
  476. /* Change state of QSPI */
  477. hqspi->State = HAL_QSPI_STATE_READY;
  478. /* RX Complete callback */
  479. HAL_QSPI_RxCpltCallback(hqspi);
  480. }
  481. else if(hqspi->State == HAL_QSPI_STATE_BUSY)
  482. {
  483. /* Change state of QSPI */
  484. hqspi->State = HAL_QSPI_STATE_READY;
  485. /* Command Complete callback */
  486. HAL_QSPI_CmdCpltCallback(hqspi);
  487. }
  488. else if(hqspi->State == HAL_QSPI_STATE_ABORT)
  489. {
  490. /* Change state of QSPI */
  491. hqspi->State = HAL_QSPI_STATE_READY;
  492. if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
  493. {
  494. /* Abort called by the user */
  495. /* Abort Complete callback */
  496. HAL_QSPI_AbortCpltCallback(hqspi);
  497. }
  498. else
  499. {
  500. /* Abort due to an error (eg : DMA error) */
  501. /* Error callback */
  502. HAL_QSPI_ErrorCallback(hqspi);
  503. }
  504. }
  505. }
  506. /* QSPI Status Match interrupt occurred ------------------------------------*/
  507. else if(((flag & QSPI_FLAG_SM)!= RESET) && ((itsource & QSPI_IT_SM)!= RESET))
  508. {
  509. /* Clear interrupt */
  510. WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
  511. /* Check if the automatic poll mode stop is activated */
  512. if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0)
  513. {
  514. /* Disable the QSPI Transfer Error and Status Match Interrupts */
  515. __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
  516. /* Change state of QSPI */
  517. hqspi->State = HAL_QSPI_STATE_READY;
  518. }
  519. /* Status match callback */
  520. HAL_QSPI_StatusMatchCallback(hqspi);
  521. }
  522. /* QSPI Transfer Error interrupt occurred ----------------------------------*/
  523. else if(((flag & QSPI_FLAG_TE)!= RESET) && ((itsource & QSPI_IT_TE)!= RESET))
  524. {
  525. /* Clear interrupt */
  526. WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
  527. /* Disable all the QSPI Interrupts */
  528. __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
  529. /* Set error code */
  530. hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
  531. if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
  532. {
  533. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  534. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  535. /* Disable the DMA channel */
  536. hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
  537. HAL_DMA_Abort_IT(hqspi->hdma);
  538. }
  539. else
  540. {
  541. /* Change state of QSPI */
  542. hqspi->State = HAL_QSPI_STATE_READY;
  543. /* Error callback */
  544. HAL_QSPI_ErrorCallback(hqspi);
  545. }
  546. }
  547. /* QSPI Timeout interrupt occurred -----------------------------------------*/
  548. else if(((flag & QSPI_FLAG_TO)!= RESET) && ((itsource & QSPI_IT_TO)!= RESET))
  549. {
  550. /* Clear interrupt */
  551. WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
  552. /* Time out callback */
  553. HAL_QSPI_TimeOutCallback(hqspi);
  554. }
  555. }
  556. /**
  557. * @brief Sets the command configuration.
  558. * @param hqspi: QSPI handle
  559. * @param cmd : structure that contains the command configuration information
  560. * @param Timeout : Time out duration
  561. * @note This function is used only in Indirect Read or Write Modes
  562. * @retval HAL status
  563. */
  564. HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
  565. {
  566. HAL_StatusTypeDef status = HAL_ERROR;
  567. uint32_t tickstart = HAL_GetTick();
  568. /* Check the parameters */
  569. assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  570. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  571. {
  572. assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
  573. }
  574. assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
  575. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  576. {
  577. assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
  578. }
  579. assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
  580. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  581. {
  582. assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
  583. }
  584. assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
  585. assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
  586. assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
  587. assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
  588. assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
  589. /* Process locked */
  590. __HAL_LOCK(hqspi);
  591. if(hqspi->State == HAL_QSPI_STATE_READY)
  592. {
  593. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  594. /* Update QSPI state */
  595. hqspi->State = HAL_QSPI_STATE_BUSY;
  596. /* Wait till BUSY flag reset */
  597. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  598. if (status == HAL_OK)
  599. {
  600. /* Call the configuration function */
  601. QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  602. if (cmd->DataMode == QSPI_DATA_NONE)
  603. {
  604. /* When there is no data phase, the transfer start as soon as the configuration is done
  605. so wait until TC flag is set to go back in idle state */
  606. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
  607. if (status == HAL_OK)
  608. {
  609. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  610. /* Update QSPI state */
  611. hqspi->State = HAL_QSPI_STATE_READY;
  612. }
  613. }
  614. else
  615. {
  616. /* Update QSPI state */
  617. hqspi->State = HAL_QSPI_STATE_READY;
  618. }
  619. }
  620. }
  621. else
  622. {
  623. status = HAL_BUSY;
  624. }
  625. /* Process unlocked */
  626. __HAL_UNLOCK(hqspi);
  627. /* Return function status */
  628. return status;
  629. }
  630. /**
  631. * @brief Sets the command configuration in interrupt mode.
  632. * @param hqspi: QSPI handle
  633. * @param cmd : structure that contains the command configuration information
  634. * @note This function is used only in Indirect Read or Write Modes
  635. * @retval HAL status
  636. */
  637. HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
  638. {
  639. HAL_StatusTypeDef status = HAL_ERROR;
  640. uint32_t tickstart = HAL_GetTick();
  641. /* Check the parameters */
  642. assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  643. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  644. {
  645. assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
  646. }
  647. assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
  648. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  649. {
  650. assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
  651. }
  652. assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
  653. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  654. {
  655. assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
  656. }
  657. assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
  658. assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
  659. assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
  660. assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
  661. assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
  662. /* Process locked */
  663. __HAL_LOCK(hqspi);
  664. if(hqspi->State == HAL_QSPI_STATE_READY)
  665. {
  666. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  667. /* Update QSPI state */
  668. hqspi->State = HAL_QSPI_STATE_BUSY;
  669. /* Wait till BUSY flag reset */
  670. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
  671. if (status == HAL_OK)
  672. {
  673. if (cmd->DataMode == QSPI_DATA_NONE)
  674. {
  675. /* Clear interrupt */
  676. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
  677. }
  678. /* Call the configuration function */
  679. QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  680. if (cmd->DataMode == QSPI_DATA_NONE)
  681. {
  682. /* When there is no data phase, the transfer start as soon as the configuration is done
  683. so activate TC and TE interrupts */
  684. /* Process unlocked */
  685. __HAL_UNLOCK(hqspi);
  686. /* Enable the QSPI Transfer Error Interrupt */
  687. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
  688. }
  689. else
  690. {
  691. /* Update QSPI state */
  692. hqspi->State = HAL_QSPI_STATE_READY;
  693. /* Process unlocked */
  694. __HAL_UNLOCK(hqspi);
  695. }
  696. }
  697. else
  698. {
  699. /* Process unlocked */
  700. __HAL_UNLOCK(hqspi);
  701. }
  702. }
  703. else
  704. {
  705. status = HAL_BUSY;
  706. /* Process unlocked */
  707. __HAL_UNLOCK(hqspi);
  708. }
  709. /* Return function status */
  710. return status;
  711. }
  712. /**
  713. * @brief Transmit an amount of data in blocking mode.
  714. * @param hqspi: QSPI handle
  715. * @param pData: pointer to data buffer
  716. * @param Timeout : Time out duration
  717. * @note This function is used only in Indirect Write Mode
  718. * @retval HAL status
  719. */
  720. HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
  721. {
  722. HAL_StatusTypeDef status = HAL_OK;
  723. uint32_t tickstart = HAL_GetTick();
  724. __IO uint32_t *data_reg = &hqspi->Instance->DR;
  725. /* Process locked */
  726. __HAL_LOCK(hqspi);
  727. if(hqspi->State == HAL_QSPI_STATE_READY)
  728. {
  729. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  730. if(pData != NULL )
  731. {
  732. /* Update state */
  733. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
  734. /* Configure counters and size of the handle */
  735. hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
  736. hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
  737. hqspi->pTxBuffPtr = pData;
  738. /* Configure QSPI: CCR register with functional as indirect write */
  739. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  740. while(hqspi->TxXferCount > 0)
  741. {
  742. /* Wait until FT flag is set to send data */
  743. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
  744. if (status != HAL_OK)
  745. {
  746. break;
  747. }
  748. *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++;
  749. hqspi->TxXferCount--;
  750. }
  751. if (status == HAL_OK)
  752. {
  753. /* Wait until TC flag is set to go back in idle state */
  754. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
  755. if (status == HAL_OK)
  756. {
  757. /* Clear Transfer Complete bit */
  758. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  759. #if defined(QSPI1_V1_0)
  760. /* Clear Busy bit */
  761. status = HAL_QSPI_Abort(hqspi);
  762. #endif /* QSPI_V1_0 */
  763. }
  764. }
  765. /* Update QSPI state */
  766. hqspi->State = HAL_QSPI_STATE_READY;
  767. }
  768. else
  769. {
  770. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  771. status = HAL_ERROR;
  772. }
  773. }
  774. else
  775. {
  776. status = HAL_BUSY;
  777. }
  778. /* Process unlocked */
  779. __HAL_UNLOCK(hqspi);
  780. return status;
  781. }
  782. /**
  783. * @brief Receive an amount of data in blocking mode
  784. * @param hqspi: QSPI handle
  785. * @param pData: pointer to data buffer
  786. * @param Timeout : Time out duration
  787. * @note This function is used only in Indirect Read Mode
  788. * @retval HAL status
  789. */
  790. HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
  791. {
  792. HAL_StatusTypeDef status = HAL_OK;
  793. uint32_t tickstart = HAL_GetTick();
  794. uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
  795. __IO uint32_t *data_reg = &hqspi->Instance->DR;
  796. /* Process locked */
  797. __HAL_LOCK(hqspi);
  798. if(hqspi->State == HAL_QSPI_STATE_READY)
  799. {
  800. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  801. if(pData != NULL )
  802. {
  803. /* Update state */
  804. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
  805. /* Configure counters and size of the handle */
  806. hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
  807. hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
  808. hqspi->pRxBuffPtr = pData;
  809. /* Configure QSPI: CCR register with functional as indirect read */
  810. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  811. /* Start the transfer by re-writing the address in AR register */
  812. WRITE_REG(hqspi->Instance->AR, addr_reg);
  813. while(hqspi->RxXferCount > 0)
  814. {
  815. /* Wait until FT or TC flag is set to read received data */
  816. status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
  817. if (status != HAL_OK)
  818. {
  819. break;
  820. }
  821. *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg;
  822. hqspi->RxXferCount--;
  823. }
  824. if (status == HAL_OK)
  825. {
  826. /* Wait until TC flag is set to go back in idle state */
  827. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
  828. if (status == HAL_OK)
  829. {
  830. /* Clear Transfer Complete bit */
  831. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  832. #if defined(QSPI1_V1_0)
  833. /* Workaround - Extra data written in the FIFO at the end of a read transfer */
  834. status = HAL_QSPI_Abort(hqspi);
  835. #endif /* QSPI_V1_0 */
  836. }
  837. }
  838. /* Update QSPI state */
  839. hqspi->State = HAL_QSPI_STATE_READY;
  840. }
  841. else
  842. {
  843. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  844. status = HAL_ERROR;
  845. }
  846. }
  847. else
  848. {
  849. status = HAL_BUSY;
  850. }
  851. /* Process unlocked */
  852. __HAL_UNLOCK(hqspi);
  853. return status;
  854. }
  855. /**
  856. * @brief Send an amount of data in interrupt mode
  857. * @param hqspi: QSPI handle
  858. * @param pData: pointer to data buffer
  859. * @note This function is used only in Indirect Write Mode
  860. * @retval HAL status
  861. */
  862. HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
  863. {
  864. HAL_StatusTypeDef status = HAL_OK;
  865. /* Process locked */
  866. __HAL_LOCK(hqspi);
  867. if(hqspi->State == HAL_QSPI_STATE_READY)
  868. {
  869. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  870. if(pData != NULL )
  871. {
  872. /* Update state */
  873. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
  874. /* Configure counters and size of the handle */
  875. hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
  876. hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
  877. hqspi->pTxBuffPtr = pData;
  878. /* Configure QSPI: CCR register with functional as indirect write */
  879. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  880. /* Clear interrupt */
  881. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
  882. /* Process unlocked */
  883. __HAL_UNLOCK(hqspi);
  884. /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
  885. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
  886. }
  887. else
  888. {
  889. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  890. status = HAL_ERROR;
  891. /* Process unlocked */
  892. __HAL_UNLOCK(hqspi);
  893. }
  894. }
  895. else
  896. {
  897. status = HAL_BUSY;
  898. /* Process unlocked */
  899. __HAL_UNLOCK(hqspi);
  900. }
  901. return status;
  902. }
  903. /**
  904. * @brief Receive an amount of data in no-blocking mode with Interrupt
  905. * @param hqspi: QSPI handle
  906. * @param pData: pointer to data buffer
  907. * @note This function is used only in Indirect Read Mode
  908. * @retval HAL status
  909. */
  910. HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
  911. {
  912. HAL_StatusTypeDef status = HAL_OK;
  913. uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
  914. /* Process locked */
  915. __HAL_LOCK(hqspi);
  916. if(hqspi->State == HAL_QSPI_STATE_READY)
  917. {
  918. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  919. if(pData != NULL )
  920. {
  921. /* Update state */
  922. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
  923. /* Configure counters and size of the handle */
  924. hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1;
  925. hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1;
  926. hqspi->pRxBuffPtr = pData;
  927. /* Configure QSPI: CCR register with functional as indirect read */
  928. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  929. /* Start the transfer by re-writing the address in AR register */
  930. WRITE_REG(hqspi->Instance->AR, addr_reg);
  931. /* Clear interrupt */
  932. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
  933. /* Process unlocked */
  934. __HAL_UNLOCK(hqspi);
  935. /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
  936. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
  937. }
  938. else
  939. {
  940. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  941. status = HAL_ERROR;
  942. /* Process unlocked */
  943. __HAL_UNLOCK(hqspi);
  944. }
  945. }
  946. else
  947. {
  948. status = HAL_BUSY;
  949. /* Process unlocked */
  950. __HAL_UNLOCK(hqspi);
  951. }
  952. return status;
  953. }
  954. /**
  955. * @brief Sends an amount of data in non blocking mode with DMA.
  956. * @param hqspi: QSPI handle
  957. * @param pData: pointer to data buffer
  958. * @note This function is used only in Indirect Write Mode
  959. * @note If DMA peripheral access is configured as halfword, the number
  960. * of data and the fifo threshold should be aligned on halfword
  961. * @note If DMA peripheral access is configured as word, the number
  962. * of data and the fifo threshold should be aligned on word
  963. * @retval HAL status
  964. */
  965. HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
  966. {
  967. HAL_StatusTypeDef status = HAL_OK;
  968. uint32_t *tmp;
  969. uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1);
  970. /* Process locked */
  971. __HAL_LOCK(hqspi);
  972. if(hqspi->State == HAL_QSPI_STATE_READY)
  973. {
  974. /* Clear the error code */
  975. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  976. if(pData != NULL )
  977. {
  978. /* Configure counters of the handle */
  979. if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
  980. {
  981. hqspi->TxXferCount = data_size;
  982. }
  983. else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
  984. {
  985. if (((data_size % 2) != 0) || ((hqspi->Init.FifoThreshold % 2) != 0))
  986. {
  987. /* The number of data or the fifo threshold is not aligned on halfword
  988. => no transfer possible with DMA peripheral access configured as halfword */
  989. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  990. status = HAL_ERROR;
  991. /* Process unlocked */
  992. __HAL_UNLOCK(hqspi);
  993. }
  994. else
  995. {
  996. hqspi->TxXferCount = (data_size >> 1);
  997. }
  998. }
  999. else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
  1000. {
  1001. if (((data_size % 4) != 0) || ((hqspi->Init.FifoThreshold % 4) != 0))
  1002. {
  1003. /* The number of data or the fifo threshold is not aligned on word
  1004. => no transfer possible with DMA peripheral access configured as word */
  1005. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  1006. status = HAL_ERROR;
  1007. /* Process unlocked */
  1008. __HAL_UNLOCK(hqspi);
  1009. }
  1010. else
  1011. {
  1012. hqspi->TxXferCount = (data_size >> 2);
  1013. }
  1014. }
  1015. if (status == HAL_OK)
  1016. {
  1017. /* Update state */
  1018. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
  1019. /* Clear interrupt */
  1020. __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
  1021. /* Configure size and pointer of the handle */
  1022. hqspi->TxXferSize = hqspi->TxXferCount;
  1023. hqspi->pTxBuffPtr = pData;
  1024. /* Configure QSPI: CCR register with functional mode as indirect write */
  1025. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  1026. /* Set the QSPI DMA transfer complete callback */
  1027. hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
  1028. /* Set the QSPI DMA Half transfer complete callback */
  1029. hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
  1030. /* Set the DMA error callback */
  1031. hqspi->hdma->XferErrorCallback = QSPI_DMAError;
  1032. /* Clear the DMA abort callback */
  1033. hqspi->hdma->XferAbortCallback = NULL;
  1034. /* Configure the direction of the DMA */
  1035. hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
  1036. MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
  1037. /* Enable the QSPI transmit DMA Channel */
  1038. tmp = (uint32_t*)&pData;
  1039. HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize);
  1040. /* Process unlocked */
  1041. __HAL_UNLOCK(hqspi);
  1042. /* Enable the QSPI transfer error Interrupt */
  1043. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
  1044. /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
  1045. SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  1046. }
  1047. }
  1048. else
  1049. {
  1050. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  1051. status = HAL_ERROR;
  1052. /* Process unlocked */
  1053. __HAL_UNLOCK(hqspi);
  1054. }
  1055. }
  1056. else
  1057. {
  1058. status = HAL_BUSY;
  1059. /* Process unlocked */
  1060. __HAL_UNLOCK(hqspi);
  1061. }
  1062. return status;
  1063. }
  1064. /**
  1065. * @brief Receives an amount of data in non blocking mode with DMA.
  1066. * @param hqspi: QSPI handle
  1067. * @param pData: pointer to data buffer.
  1068. * @note This function is used only in Indirect Read Mode
  1069. * @note If DMA peripheral access is configured as halfword, the number
  1070. * of data and the fifo threshold should be aligned on halfword
  1071. * @note If DMA peripheral access is configured as word, the number
  1072. * of data and the fifo threshold should be aligned on word
  1073. * @retval HAL status
  1074. */
  1075. HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
  1076. {
  1077. HAL_StatusTypeDef status = HAL_OK;
  1078. uint32_t *tmp;
  1079. uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
  1080. uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1);
  1081. /* Process locked */
  1082. __HAL_LOCK(hqspi);
  1083. if(hqspi->State == HAL_QSPI_STATE_READY)
  1084. {
  1085. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  1086. if(pData != NULL )
  1087. {
  1088. /* Configure counters of the handle */
  1089. if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
  1090. {
  1091. hqspi->RxXferCount = data_size;
  1092. }
  1093. else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
  1094. {
  1095. if (((data_size % 2) != 0) || ((hqspi->Init.FifoThreshold % 2) != 0))
  1096. {
  1097. /* The number of data or the fifo threshold is not aligned on halfword
  1098. => no transfer possible with DMA peripheral access configured as halfword */
  1099. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  1100. status = HAL_ERROR;
  1101. /* Process unlocked */
  1102. __HAL_UNLOCK(hqspi);
  1103. }
  1104. else
  1105. {
  1106. hqspi->RxXferCount = (data_size >> 1);
  1107. }
  1108. }
  1109. else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
  1110. {
  1111. if (((data_size % 4) != 0) || ((hqspi->Init.FifoThreshold % 4) != 0))
  1112. {
  1113. /* The number of data or the fifo threshold is not aligned on word
  1114. => no transfer possible with DMA peripheral access configured as word */
  1115. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  1116. status = HAL_ERROR;
  1117. /* Process unlocked */
  1118. __HAL_UNLOCK(hqspi);
  1119. }
  1120. else
  1121. {
  1122. hqspi->RxXferCount = (data_size >> 2);
  1123. }
  1124. }
  1125. if (status == HAL_OK)
  1126. {
  1127. /* Update state */
  1128. hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
  1129. /* Clear interrupt */
  1130. __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
  1131. /* Configure size and pointer of the handle */
  1132. hqspi->RxXferSize = hqspi->RxXferCount;
  1133. hqspi->pRxBuffPtr = pData;
  1134. /* Set the QSPI DMA transfer complete callback */
  1135. hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
  1136. /* Set the QSPI DMA Half transfer complete callback */
  1137. hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
  1138. /* Set the DMA error callback */
  1139. hqspi->hdma->XferErrorCallback = QSPI_DMAError;
  1140. /* Clear the DMA abort callback */
  1141. hqspi->hdma->XferAbortCallback = NULL;
  1142. /* Configure the direction of the DMA */
  1143. hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
  1144. MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
  1145. /* Enable the DMA Channel */
  1146. tmp = (uint32_t*)&pData;
  1147. HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize);
  1148. /* Configure QSPI: CCR register with functional as indirect read */
  1149. MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  1150. /* Start the transfer by re-writing the address in AR register */
  1151. WRITE_REG(hqspi->Instance->AR, addr_reg);
  1152. /* Process unlocked */
  1153. __HAL_UNLOCK(hqspi);
  1154. /* Enable the QSPI transfer error Interrupt */
  1155. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
  1156. /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
  1157. SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  1158. }
  1159. }
  1160. else
  1161. {
  1162. hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
  1163. status = HAL_ERROR;
  1164. /* Process unlocked */
  1165. __HAL_UNLOCK(hqspi);
  1166. }
  1167. }
  1168. else
  1169. {
  1170. status = HAL_BUSY;
  1171. /* Process unlocked */
  1172. __HAL_UNLOCK(hqspi);
  1173. }
  1174. return status;
  1175. }
  1176. /**
  1177. * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
  1178. * @param hqspi: QSPI handle
  1179. * @param cmd: structure that contains the command configuration information.
  1180. * @param cfg: structure that contains the polling configuration information.
  1181. * @param Timeout : Time out duration
  1182. * @note This function is used only in Automatic Polling Mode
  1183. * @retval HAL status
  1184. */
  1185. HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
  1186. {
  1187. HAL_StatusTypeDef status = HAL_ERROR;
  1188. uint32_t tickstart = HAL_GetTick();
  1189. /* Check the parameters */
  1190. assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  1191. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  1192. {
  1193. assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
  1194. }
  1195. assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
  1196. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1197. {
  1198. assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
  1199. }
  1200. assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
  1201. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  1202. {
  1203. assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
  1204. }
  1205. assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
  1206. assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
  1207. assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
  1208. assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
  1209. assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
  1210. assert_param(IS_QSPI_INTERVAL(cfg->Interval));
  1211. assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
  1212. assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
  1213. /* Process locked */
  1214. __HAL_LOCK(hqspi);
  1215. if(hqspi->State == HAL_QSPI_STATE_READY)
  1216. {
  1217. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  1218. /* Update state */
  1219. hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
  1220. /* Wait till BUSY flag reset */
  1221. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  1222. if (status == HAL_OK)
  1223. {
  1224. /* Configure QSPI: PSMAR register with the status match value */
  1225. WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
  1226. /* Configure QSPI: PSMKR register with the status mask value */
  1227. WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
  1228. /* Configure QSPI: PIR register with the interval value */
  1229. WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
  1230. /* Configure QSPI: CR register with Match mode and Automatic stop enabled
  1231. (otherwise there will be an infinite loop in blocking mode) */
  1232. MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
  1233. (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
  1234. /* Call the configuration function */
  1235. cmd->NbData = cfg->StatusBytesSize;
  1236. QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
  1237. /* Wait until SM flag is set to go back in idle state */
  1238. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
  1239. if (status == HAL_OK)
  1240. {
  1241. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
  1242. /* Update state */
  1243. hqspi->State = HAL_QSPI_STATE_READY;
  1244. }
  1245. }
  1246. }
  1247. else
  1248. {
  1249. status = HAL_BUSY;
  1250. }
  1251. /* Process unlocked */
  1252. __HAL_UNLOCK(hqspi);
  1253. /* Return function status */
  1254. return status;
  1255. }
  1256. /**
  1257. * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
  1258. * @param hqspi: QSPI handle
  1259. * @param cmd: structure that contains the command configuration information.
  1260. * @param cfg: structure that contains the polling configuration information.
  1261. * @note This function is used only in Automatic Polling Mode
  1262. * @retval HAL status
  1263. */
  1264. HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
  1265. {
  1266. HAL_StatusTypeDef status = HAL_ERROR;
  1267. uint32_t tickstart = HAL_GetTick();
  1268. /* Check the parameters */
  1269. assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  1270. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  1271. {
  1272. assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
  1273. }
  1274. assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
  1275. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1276. {
  1277. assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
  1278. }
  1279. assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
  1280. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  1281. {
  1282. assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
  1283. }
  1284. assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
  1285. assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
  1286. assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
  1287. assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
  1288. assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
  1289. assert_param(IS_QSPI_INTERVAL(cfg->Interval));
  1290. assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
  1291. assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
  1292. assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
  1293. /* Process locked */
  1294. __HAL_LOCK(hqspi);
  1295. if(hqspi->State == HAL_QSPI_STATE_READY)
  1296. {
  1297. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  1298. /* Update state */
  1299. hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
  1300. /* Wait till BUSY flag reset */
  1301. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
  1302. if (status == HAL_OK)
  1303. {
  1304. /* Configure QSPI: PSMAR register with the status match value */
  1305. WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
  1306. /* Configure QSPI: PSMKR register with the status mask value */
  1307. WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
  1308. /* Configure QSPI: PIR register with the interval value */
  1309. WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
  1310. /* Configure QSPI: CR register with Match mode and Automatic stop mode */
  1311. MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
  1312. (cfg->MatchMode | cfg->AutomaticStop));
  1313. /* Clear interrupt */
  1314. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
  1315. /* Call the configuration function */
  1316. cmd->NbData = cfg->StatusBytesSize;
  1317. QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
  1318. /* Process unlocked */
  1319. __HAL_UNLOCK(hqspi);
  1320. /* Enable the QSPI Transfer Error and status match Interrupt */
  1321. __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
  1322. }
  1323. else
  1324. {
  1325. /* Process unlocked */
  1326. __HAL_UNLOCK(hqspi);
  1327. }
  1328. }
  1329. else
  1330. {
  1331. status = HAL_BUSY;
  1332. /* Process unlocked */
  1333. __HAL_UNLOCK(hqspi);
  1334. }
  1335. /* Return function status */
  1336. return status;
  1337. }
  1338. /**
  1339. * @brief Configure the Memory Mapped mode.
  1340. * @param hqspi: QSPI handle
  1341. * @param cmd: structure that contains the command configuration information.
  1342. * @param cfg: structure that contains the memory mapped configuration information.
  1343. * @note This function is used only in Memory mapped Mode
  1344. * @retval HAL status
  1345. */
  1346. HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
  1347. {
  1348. HAL_StatusTypeDef status = HAL_ERROR;
  1349. uint32_t tickstart = HAL_GetTick();
  1350. /* Check the parameters */
  1351. assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  1352. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  1353. {
  1354. assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
  1355. }
  1356. assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
  1357. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1358. {
  1359. assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
  1360. }
  1361. assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
  1362. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  1363. {
  1364. assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
  1365. }
  1366. assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
  1367. assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
  1368. assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
  1369. assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
  1370. assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
  1371. assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
  1372. /* Process locked */
  1373. __HAL_LOCK(hqspi);
  1374. if(hqspi->State == HAL_QSPI_STATE_READY)
  1375. {
  1376. hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
  1377. /* Update state */
  1378. hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
  1379. /* Wait till BUSY flag reset */
  1380. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
  1381. if (status == HAL_OK)
  1382. {
  1383. /* Configure QSPI: CR register with timeout counter enable */
  1384. MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
  1385. if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
  1386. {
  1387. assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
  1388. /* Configure QSPI: LPTR register with the low-power timeout value */
  1389. WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
  1390. /* Clear interrupt */
  1391. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
  1392. /* Enable the QSPI TimeOut Interrupt */
  1393. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
  1394. }
  1395. /* Call the configuration function */
  1396. QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
  1397. }
  1398. }
  1399. else
  1400. {
  1401. status = HAL_BUSY;
  1402. }
  1403. /* Process unlocked */
  1404. __HAL_UNLOCK(hqspi);
  1405. /* Return function status */
  1406. return status;
  1407. }
  1408. /**
  1409. * @brief Transfer Error callbacks
  1410. * @param hqspi: QSPI handle
  1411. * @retval None
  1412. */
  1413. __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
  1414. {
  1415. /* Prevent unused argument(s) compilation warning */
  1416. UNUSED(hqspi);
  1417. /* NOTE : This function Should not be modified, when the callback is needed,
  1418. the HAL_QSPI_ErrorCallback could be implemented in the user file
  1419. */
  1420. }
  1421. /**
  1422. * @brief Abort completed callback.
  1423. * @param hqspi: QSPI handle
  1424. * @retval None
  1425. */
  1426. __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
  1427. {
  1428. /* Prevent unused argument(s) compilation warning */
  1429. UNUSED(hqspi);
  1430. /* NOTE: This function should not be modified, when the callback is needed,
  1431. the HAL_QSPI_AbortCpltCallback could be implemented in the user file
  1432. */
  1433. }
  1434. /**
  1435. * @brief Command completed callback.
  1436. * @param hqspi: QSPI handle
  1437. * @retval None
  1438. */
  1439. __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
  1440. {
  1441. /* Prevent unused argument(s) compilation warning */
  1442. UNUSED(hqspi);
  1443. /* NOTE: This function Should not be modified, when the callback is needed,
  1444. the HAL_QSPI_CmdCpltCallback could be implemented in the user file
  1445. */
  1446. }
  1447. /**
  1448. * @brief Rx Transfer completed callbacks.
  1449. * @param hqspi: QSPI handle
  1450. * @retval None
  1451. */
  1452. __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
  1453. {
  1454. /* Prevent unused argument(s) compilation warning */
  1455. UNUSED(hqspi);
  1456. /* NOTE: This function Should not be modified, when the callback is needed,
  1457. the HAL_QSPI_RxCpltCallback could be implemented in the user file
  1458. */
  1459. }
  1460. /**
  1461. * @brief Tx Transfer completed callbacks.
  1462. * @param hqspi: QSPI handle
  1463. * @retval None
  1464. */
  1465. __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
  1466. {
  1467. /* Prevent unused argument(s) compilation warning */
  1468. UNUSED(hqspi);
  1469. /* NOTE: This function Should not be modified, when the callback is needed,
  1470. the HAL_QSPI_TxCpltCallback could be implemented in the user file
  1471. */
  1472. }
  1473. /**
  1474. * @brief Rx Half Transfer completed callbacks.
  1475. * @param hqspi: QSPI handle
  1476. * @retval None
  1477. */
  1478. __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
  1479. {
  1480. /* Prevent unused argument(s) compilation warning */
  1481. UNUSED(hqspi);
  1482. /* NOTE: This function Should not be modified, when the callback is needed,
  1483. the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
  1484. */
  1485. }
  1486. /**
  1487. * @brief Tx Half Transfer completed callbacks.
  1488. * @param hqspi: QSPI handle
  1489. * @retval None
  1490. */
  1491. __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
  1492. {
  1493. /* Prevent unused argument(s) compilation warning */
  1494. UNUSED(hqspi);
  1495. /* NOTE: This function Should not be modified, when the callback is needed,
  1496. the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
  1497. */
  1498. }
  1499. /**
  1500. * @brief FIFO Threshold callbacks
  1501. * @param hqspi: QSPI handle
  1502. * @retval None
  1503. */
  1504. __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
  1505. {
  1506. /* Prevent unused argument(s) compilation warning */
  1507. UNUSED(hqspi);
  1508. /* NOTE : This function Should not be modified, when the callback is needed,
  1509. the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
  1510. */
  1511. }
  1512. /**
  1513. * @brief Status Match callbacks
  1514. * @param hqspi: QSPI handle
  1515. * @retval None
  1516. */
  1517. __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
  1518. {
  1519. /* Prevent unused argument(s) compilation warning */
  1520. UNUSED(hqspi);
  1521. /* NOTE : This function Should not be modified, when the callback is needed,
  1522. the HAL_QSPI_StatusMatchCallback could be implemented in the user file
  1523. */
  1524. }
  1525. /**
  1526. * @brief Timeout callbacks
  1527. * @param hqspi: QSPI handle
  1528. * @retval None
  1529. */
  1530. __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
  1531. {
  1532. /* Prevent unused argument(s) compilation warning */
  1533. UNUSED(hqspi);
  1534. /* NOTE : This function Should not be modified, when the callback is needed,
  1535. the HAL_QSPI_TimeOutCallback could be implemented in the user file
  1536. */
  1537. }
  1538. /**
  1539. * @}
  1540. */
  1541. /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
  1542. * @brief QSPI control and State functions
  1543. *
  1544. @verbatim
  1545. ===============================================================================
  1546. ##### Peripheral Control and State functions #####
  1547. ===============================================================================
  1548. [..]
  1549. This subsection provides a set of functions allowing to :
  1550. (+) Check in run-time the state of the driver.
  1551. (+) Check the error code set during last operation.
  1552. (+) Abort any operation.
  1553. .....
  1554. @endverbatim
  1555. * @{
  1556. */
  1557. /**
  1558. * @brief Return the QSPI handle state.
  1559. * @param hqspi: QSPI handle
  1560. * @retval HAL state
  1561. */
  1562. HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
  1563. {
  1564. /* Return QSPI handle state */
  1565. return hqspi->State;
  1566. }
  1567. /**
  1568. * @brief Return the QSPI error code
  1569. * @param hqspi: QSPI handle
  1570. * @retval QSPI Error Code
  1571. */
  1572. uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
  1573. {
  1574. return hqspi->ErrorCode;
  1575. }
  1576. /**
  1577. * @brief Abort the current transmission
  1578. * @param hqspi: QSPI handle
  1579. * @retval HAL status
  1580. */
  1581. HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
  1582. {
  1583. HAL_StatusTypeDef status = HAL_OK;
  1584. uint32_t tickstart = HAL_GetTick();
  1585. /* Check if the state is in one of the busy states */
  1586. if ((hqspi->State & 0x2) != 0)
  1587. {
  1588. /* Process unlocked */
  1589. __HAL_UNLOCK(hqspi);
  1590. if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
  1591. {
  1592. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  1593. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  1594. /* Abort DMA channel */
  1595. status = HAL_DMA_Abort(hqspi->hdma);
  1596. if(status != HAL_OK)
  1597. {
  1598. hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
  1599. }
  1600. }
  1601. /* Configure QSPI: CR register with Abort request */
  1602. SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
  1603. /* Wait until TC flag is set to go back in idle state */
  1604. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
  1605. if(status == HAL_OK)
  1606. {
  1607. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  1608. /* Wait until BUSY flag is reset */
  1609. status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
  1610. }
  1611. if (status == HAL_OK)
  1612. {
  1613. /* Update state */
  1614. hqspi->State = HAL_QSPI_STATE_READY;
  1615. }
  1616. }
  1617. return status;
  1618. }
  1619. /**
  1620. * @brief Abort the current transmission (non-blocking function)
  1621. * @param hqspi: QSPI handle
  1622. * @retval HAL status
  1623. */
  1624. HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
  1625. {
  1626. HAL_StatusTypeDef status = HAL_OK;
  1627. /* Check if the state is in one of the busy states */
  1628. if ((hqspi->State & 0x2) != 0)
  1629. {
  1630. /* Process unlocked */
  1631. __HAL_UNLOCK(hqspi);
  1632. /* Update QSPI state */
  1633. hqspi->State = HAL_QSPI_STATE_ABORT;
  1634. /* Disable all interrupts */
  1635. __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
  1636. if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN)!= RESET)
  1637. {
  1638. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  1639. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  1640. /* Abort DMA channel */
  1641. hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
  1642. HAL_DMA_Abort_IT(hqspi->hdma);
  1643. }
  1644. else
  1645. {
  1646. /* Clear interrupt */
  1647. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  1648. /* Enable the QSPI Transfer Complete Interrupt */
  1649. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
  1650. /* Configure QSPI: CR register with Abort request */
  1651. SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
  1652. }
  1653. }
  1654. return status;
  1655. }
  1656. /** @brief Set QSPI timeout
  1657. * @param hqspi: QSPI handle.
  1658. * @param Timeout: Timeout for the QSPI memory access.
  1659. * @retval None
  1660. */
  1661. void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
  1662. {
  1663. hqspi->Timeout = Timeout;
  1664. }
  1665. /** @brief Set QSPI Fifo threshold.
  1666. * @param hqspi: QSPI handle.
  1667. * @param Threshold: Threshold of the Fifo (value between 1 and 16).
  1668. * @retval HAL status
  1669. */
  1670. HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
  1671. {
  1672. HAL_StatusTypeDef status = HAL_OK;
  1673. /* Process locked */
  1674. __HAL_LOCK(hqspi);
  1675. if(hqspi->State == HAL_QSPI_STATE_READY)
  1676. {
  1677. /* Synchronize init structure with new FIFO threshold value */
  1678. hqspi->Init.FifoThreshold = Threshold;
  1679. /* Configure QSPI FIFO Threshold */
  1680. MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
  1681. ((hqspi->Init.FifoThreshold - 1) << POSITION_VAL(QUADSPI_CR_FTHRES)));
  1682. }
  1683. else
  1684. {
  1685. status = HAL_BUSY;
  1686. }
  1687. /* Process unlocked */
  1688. __HAL_UNLOCK(hqspi);
  1689. /* Return function status */
  1690. return status;
  1691. }
  1692. /** @brief Get QSPI Fifo threshold.
  1693. * @param hqspi: QSPI handle.
  1694. * @retval Fifo threshold (value between 1 and 16)
  1695. */
  1696. uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
  1697. {
  1698. return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> POSITION_VAL(QUADSPI_CR_FTHRES)) + 1);
  1699. }
  1700. /**
  1701. * @}
  1702. */
  1703. /* Private functions ---------------------------------------------------------*/
  1704. /**
  1705. * @brief DMA QSPI receive process complete callback.
  1706. * @param hdma: DMA handle
  1707. * @retval None
  1708. */
  1709. static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
  1710. {
  1711. QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1712. hqspi->RxXferCount = 0;
  1713. /* Enable the QSPI transfer complete Interrupt */
  1714. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
  1715. }
  1716. /**
  1717. * @brief DMA QSPI transmit process complete callback.
  1718. * @param hdma: DMA handle
  1719. * @retval None
  1720. */
  1721. static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
  1722. {
  1723. QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1724. hqspi->TxXferCount = 0;
  1725. /* Enable the QSPI transfer complete Interrupt */
  1726. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
  1727. }
  1728. /**
  1729. * @brief DMA QSPI receive process half complete callback
  1730. * @param hdma : DMA handle
  1731. * @retval None
  1732. */
  1733. static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
  1734. {
  1735. QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1736. HAL_QSPI_RxHalfCpltCallback(hqspi);
  1737. }
  1738. /**
  1739. * @brief DMA QSPI transmit process half complete callback
  1740. * @param hdma : DMA handle
  1741. * @retval None
  1742. */
  1743. static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
  1744. {
  1745. QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1746. HAL_QSPI_TxHalfCpltCallback(hqspi);
  1747. }
  1748. /**
  1749. * @brief DMA QSPI communication error callback.
  1750. * @param hdma: DMA handle
  1751. * @retval None
  1752. */
  1753. static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
  1754. {
  1755. QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1756. /* if DMA error is FIFO error ignore it */
  1757. if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
  1758. {
  1759. hqspi->RxXferCount = 0;
  1760. hqspi->TxXferCount = 0;
  1761. hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
  1762. /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
  1763. CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
  1764. /* Abort the QSPI */
  1765. HAL_QSPI_Abort_IT(hqspi);
  1766. }
  1767. }
  1768. /**
  1769. * @brief DMA QSPI abort complete callback.
  1770. * @param hdma: DMA handle
  1771. * @retval None
  1772. */
  1773. static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
  1774. {
  1775. QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1776. hqspi->RxXferCount = 0;
  1777. hqspi->TxXferCount = 0;
  1778. if(hqspi->State == HAL_QSPI_STATE_ABORT)
  1779. {
  1780. /* DMA Abort called by QSPI abort */
  1781. /* Clear interrupt */
  1782. __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
  1783. /* Enable the QSPI Transfer Complete Interrupt */
  1784. __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
  1785. /* Configure QSPI: CR register with Abort request */
  1786. SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
  1787. }
  1788. else
  1789. {
  1790. /* DMA Abort called due to a transfer error interrupt */
  1791. /* Change state of QSPI */
  1792. hqspi->State = HAL_QSPI_STATE_READY;
  1793. /* Error callback */
  1794. HAL_QSPI_ErrorCallback(hqspi);
  1795. }
  1796. }
  1797. /**
  1798. * @brief Wait for a flag state until timeout.
  1799. * @param hqspi: QSPI handle
  1800. * @param Flag: Flag checked
  1801. * @param State: Value of the flag expected
  1802. * @param tickstart: Start tick value
  1803. * @param Timeout: Duration of the time out
  1804. * @retval HAL status
  1805. */
  1806. static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
  1807. FlagStatus State, uint32_t tickstart, uint32_t Timeout)
  1808. {
  1809. /* Wait until flag is in expected state */
  1810. while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
  1811. {
  1812. /* Check for the Timeout */
  1813. if (Timeout != HAL_MAX_DELAY)
  1814. {
  1815. if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
  1816. {
  1817. hqspi->State = HAL_QSPI_STATE_ERROR;
  1818. hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
  1819. return HAL_ERROR;
  1820. }
  1821. }
  1822. }
  1823. return HAL_OK;
  1824. }
  1825. /**
  1826. * @brief Configure the communication registers.
  1827. * @param hqspi: QSPI handle
  1828. * @param cmd: structure that contains the command configuration information
  1829. * @param FunctionalMode: functional mode to configured
  1830. * This parameter can be one of the following values:
  1831. * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
  1832. * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
  1833. * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
  1834. * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
  1835. * @retval None
  1836. */
  1837. static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
  1838. {
  1839. assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
  1840. if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
  1841. {
  1842. /* Configure QSPI: DLR register with the number of data to read or write */
  1843. WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1));
  1844. }
  1845. if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
  1846. {
  1847. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  1848. {
  1849. /* Configure QSPI: ABR register with alternate bytes value */
  1850. WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
  1851. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1852. {
  1853. /*---- Command with instruction, address and alternate bytes ----*/
  1854. /* Configure QSPI: CCR register with all communications parameters */
  1855. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1856. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
  1857. cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
  1858. cmd->InstructionMode | cmd->Instruction | FunctionalMode));
  1859. if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
  1860. {
  1861. /* Configure QSPI: AR register with address value */
  1862. WRITE_REG(hqspi->Instance->AR, cmd->Address);
  1863. }
  1864. }
  1865. else
  1866. {
  1867. /*---- Command with instruction and alternate bytes ----*/
  1868. /* Configure QSPI: CCR register with all communications parameters */
  1869. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1870. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
  1871. cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
  1872. cmd->Instruction | FunctionalMode));
  1873. }
  1874. }
  1875. else
  1876. {
  1877. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1878. {
  1879. /*---- Command with instruction and address ----*/
  1880. /* Configure QSPI: CCR register with all communications parameters */
  1881. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1882. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
  1883. cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
  1884. cmd->Instruction | FunctionalMode));
  1885. if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
  1886. {
  1887. /* Configure QSPI: AR register with address value */
  1888. WRITE_REG(hqspi->Instance->AR, cmd->Address);
  1889. }
  1890. }
  1891. else
  1892. {
  1893. /*---- Command with only instruction ----*/
  1894. /* Configure QSPI: CCR register with all communications parameters */
  1895. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1896. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
  1897. cmd->AddressMode | cmd->InstructionMode | cmd->Instruction |
  1898. FunctionalMode));
  1899. }
  1900. }
  1901. }
  1902. else
  1903. {
  1904. if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
  1905. {
  1906. /* Configure QSPI: ABR register with alternate bytes value */
  1907. WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
  1908. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1909. {
  1910. /*---- Command with address and alternate bytes ----*/
  1911. /* Configure QSPI: CCR register with all communications parameters */
  1912. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1913. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
  1914. cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
  1915. cmd->InstructionMode | FunctionalMode));
  1916. if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
  1917. {
  1918. /* Configure QSPI: AR register with address value */
  1919. WRITE_REG(hqspi->Instance->AR, cmd->Address);
  1920. }
  1921. }
  1922. else
  1923. {
  1924. /*---- Command with only alternate bytes ----*/
  1925. /* Configure QSPI: CCR register with all communications parameters */
  1926. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1927. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize |
  1928. cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode |
  1929. FunctionalMode));
  1930. }
  1931. }
  1932. else
  1933. {
  1934. if (cmd->AddressMode != QSPI_ADDRESS_NONE)
  1935. {
  1936. /*---- Command with only address ----*/
  1937. /* Configure QSPI: CCR register with all communications parameters */
  1938. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1939. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
  1940. cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
  1941. FunctionalMode));
  1942. if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
  1943. {
  1944. /* Configure QSPI: AR register with address value */
  1945. WRITE_REG(hqspi->Instance->AR, cmd->Address);
  1946. }
  1947. }
  1948. else
  1949. {
  1950. /*---- Command with only data phase ----*/
  1951. if (cmd->DataMode != QSPI_DATA_NONE)
  1952. {
  1953. /* Configure QSPI: CCR register with all communications parameters */
  1954. WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
  1955. cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode |
  1956. cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
  1957. }
  1958. }
  1959. }
  1960. }
  1961. }
  1962. /**
  1963. * @}
  1964. */
  1965. #endif /* HAL_QSPI_MODULE_ENABLED */
  1966. /**
  1967. * @}
  1968. */
  1969. /**
  1970. * @}
  1971. */
  1972. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/