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