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.
 
 
 

2346 lines
76 KiB

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