1 /**
2 ******************************************************************************
3 * @file stm32h5xx_hal_xspi.c
4 * @author MCD Application Team
5 * @brief XSPI HAL module driver.
6 This file provides firmware functions to manage the following
7 functionalities of the OctoSPI interface (XSPI).
8 + Initialization and de-initialization functions
9 + Hyperbus configuration
10 + Indirect functional mode management
11 + Memory-mapped functional mode management
12 + Auto-polling functional mode management
13 + Interrupts and flags management
14 + DMA channel configuration for indirect functional mode
15 + Errors management and abort functionality
16 + Delay block configuration
17 ******************************************************************************
18 * @attention
19 *
20 * Copyright (c) 2022 STMicroelectronics.
21 * All rights reserved.
22 *
23 * This software is licensed under terms that can be found in the LICENSE file
24 * in the root directory of this software component.
25 * If no LICENSE file comes with this software, it is provided AS-IS.
26 *
27 ******************************************************************************
28 @verbatim
29 ===============================================================================
30 ##### How to use this driver #####
31 ===============================================================================
32 [..]
33 *** Initialization ***
34 ======================
35 [..]
36 As prerequisite, fill in the HAL_XSPI_MspInit() :
37 (+) Enable OctoSPI clocks interface with __HAL_RCC_XSPI_CLK_ENABLE().
38 (+) Reset OctoSPI Peripheral with __HAL_RCC_XSPI_FORCE_RESET() and __HAL_RCC_XSPI_RELEASE_RESET().
39 (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
40 (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
41 (+) If interrupt or DMA mode is used, enable and configure OctoSPI global
42 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
43 (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
44 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
45 link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
46 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
47 [..]
48 Configure the fifo threshold, the memory mode, the memory type, the
49 device size, the CS high time, the free running clock, the clock mode,
50 the wrap size, the clock prescaler, the sample shifting, the hold delay
51 and the CS boundary using the HAL_XSPI_Init() function.
52 [..]
53 When using Hyperbus, configure the RW recovery time, the access time,
54 the write latency and the latency mode using the HAL_XSPI_HyperbusCfg()
55 function.
56
57 *** Indirect functional mode ***
58 ================================
59 [..]
60 In regular mode, configure the command sequence using the HAL_XSPI_Command()
61 or HAL_XSPI_Command_IT() functions :
62 (+) Instruction phase : the mode used and if present the size, the instruction
63 opcode and the DTR mode.
64 (+) Address phase : the mode used and if present the size, the address
65 value and the DTR mode.
66 (+) Alternate-bytes phase : the mode used and if present the size, the
67 alternate bytes values and the DTR mode.
68 (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
69 (+) Data phase : the mode used and if present the number of bytes and the DTR mode.
70 (+) Data strobe (DQS) mode : the activation (or not) of this mode
71 (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
72 (+) IO selection : to access external memory.
73 (+) Operation type : always common configuration.
74 [..]
75 In Hyperbus mode, configure the command sequence using the HAL_XSPI_HyperbusCmd()
76 function :
77 (+) Address space : indicate if the access will be done in register or memory
78 (+) Address size
79 (+) Number of data
80 (+) Data strobe (DQS) mode : the activation (or not) of this mode
81 [..]
82 If no data is required for the command (only for regular mode, not for
83 Hyperbus mode), it is sent directly to the memory :
84 (+) In polling mode, the output of the function is done when the transfer is complete.
85 (+) In interrupt mode, HAL_XSPI_CmdCpltCallback() will be called when the transfer is complete.
86 [..]
87 For the indirect write mode, use HAL_XSPI_Transmit(), HAL_XSPI_Transmit_DMA() or
88 HAL_XSPI_Transmit_IT() after the command configuration :
89 (+) In polling mode, the output of the function is done when the transfer is complete.
90 (+) In interrupt mode, HAL_XSPI_FifoThresholdCallback() will be called when the fifo threshold
91 is reached and HAL_XSPI_TxCpltCallback() will be called when the transfer is complete.
92 (+) In DMA mode, HAL_XSPI_TxHalfCpltCallback() will be called at the half transfer and
93 HAL_XSPI_TxCpltCallback() will be called when the transfer is complete.
94 [..]
95 For the indirect read mode, use HAL_XSPI_Receive(), HAL_XSPI_Receive_DMA() or
96 HAL_XSPI_Receive_IT() after the command configuration :
97 (+) In polling mode, the output of the function is done when the transfer is complete.
98 (+) In interrupt mode, HAL_XSPI_FifoThresholdCallback() will be called when the fifo threshold
99 is reached and HAL_XSPI_RxCpltCallback() will be called when the transfer is complete.
100 (+) In DMA mode, HAL_XSPI_RxHalfCpltCallback() will be called at the half transfer and
101 HAL_XSPI_RxCpltCallback() will be called when the transfer is complete.
102
103 *** Auto-polling functional mode ***
104 ====================================
105 [..]
106 Configure the command sequence by the same way than the indirect mode
107 [..]
108 Configure the auto-polling functional mode using the HAL_XSPI_AutoPolling()
109 or HAL_XSPI_AutoPolling_IT() functions :
110 (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
111 the polling interval and the automatic stop activation.
112 [..]
113 After the configuration :
114 (+) In polling mode, the output of the function is done when the status match is reached. The
115 automatic stop is activated to avoid an infinite loop.
116 (+) In interrupt mode, HAL_XSPI_StatusMatchCallback() will be called each time the status match is reached.
117
118 *** Memory-mapped functional mode ***
119 =====================================
120 [..]
121 Configure the command sequence by the same way than the indirect mode except
122 for the operation type in regular mode :
123 (+) Operation type equals to read configuration : the command configuration
124 applies to read access in memory-mapped mode
125 (+) Operation type equals to write configuration : the command configuration
126 applies to write access in memory-mapped mode
127 (+) Both read and write configuration should be performed before activating
128 memory-mapped mode
129 [..]
130 Configure the memory-mapped functional mode using the HAL_XSPI_MemoryMapped()
131 functions :
132 (+) The timeout activation and the timeout period.
133 [..]
134 After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
135 the address range. HAL_XSPI_TimeOutCallback() will be called when the timeout expires.
136
137 *** Errors management and abort functionality ***
138 =================================================
139 [..]
140 HAL_XSPI_GetError() function gives the error raised during the last operation.
141 [..]
142 HAL_XSPI_Abort() and HAL_XSPI_AbortIT() functions aborts any on-going operation and
143 flushes the fifo :
144 (+) In polling mode, the output of the function is done when the transfer
145 complete bit is set and the busy bit cleared.
146 (+) In interrupt mode, HAL_XSPI_AbortCpltCallback() will be called when
147 the transfer complete bit is set.
148
149 *** Control functions ***
150 =========================
151 [..]
152 HAL_XSPI_GetState() function gives the current state of the HAL XSPI driver.
153 [..]
154 HAL_XSPI_SetTimeout() function configures the timeout value used in the driver.
155 [..]
156 HAL_XSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OctoSPI Peripheral.
157 [..]
158 HAL_XSPI_SetMemoryType() function configures the type of the external memory.
159 [..]
160 HAL_XSPI_SetDeviceSize() function configures the size of the external memory.
161 [..]
162 HAL_XSPI_SetClockPrescaler() function configures the clock prescaler of the OctoSPI Peripheral.
163 [..]
164 HAL_XSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
165
166 *** Delay Block functions ***
167 ==========================================
168 [..]
169 The delay block (DLYB) is used to generate an output clock that is dephased from the input clock.
170 (+) The delay line length can be Configure to one period of the Input clock with HAL_XSPI_DLYB_GetClockPeriod().
171 (+) The phase of the output clock can be programmed directly with HAL_XSPI_DLYB_SetConfig().
172 (+) The phase of the output clock can be got with HAL_XSPI_DLYB_GetConfig().
173 [..]
174
175 *** Callback registration ***
176 =============================================
177 [..]
178 The compilation define USE_HAL_XSPI_REGISTER_CALLBACKS when set to 1
179 allows the user to configure dynamically the driver callbacks.
180
181 [..]
182 Use function HAL_XSPI_RegisterCallback() to register a user callback,
183 it allows to register following callbacks:
184 (+) ErrorCallback : callback when error occurs.
185 (+) AbortCpltCallback : callback when abort is completed.
186 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
187 (+) CmdCpltCallback : callback when a command without data is completed.
188 (+) RxCpltCallback : callback when a reception transfer is completed.
189 (+) TxCpltCallback : callback when a transmission transfer is completed.
190 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
191 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
192 (+) StatusMatchCallback : callback when a status match occurs.
193 (+) TimeOutCallback : callback when the timeout perioed expires.
194 (+) MspInitCallback : XSPI MspInit.
195 (+) MspDeInitCallback : XSPI MspDeInit.
196 [..]
197 This function takes as parameters the HAL peripheral handle, the Callback ID
198 and a pointer to the user callback function.
199
200 [..]
201 Use function HAL_XSPI_UnRegisterCallback() to reset a callback to the default
202 weak (surcharged) function. It allows to reset following callbacks:
203 (+) ErrorCallback : callback when error occurs.
204 (+) AbortCpltCallback : callback when abort is completed.
205 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
206 (+) CmdCpltCallback : callback when a command without data is completed.
207 (+) RxCpltCallback : callback when a reception transfer is completed.
208 (+) TxCpltCallback : callback when a transmission transfer is completed.
209 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
210 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
211 (+) StatusMatchCallback : callback when a status match occurs.
212 (+) TimeOutCallback : callback when the timeout perioed expires.
213 (+) MspInitCallback : XSPI MspInit.
214 (+) MspDeInitCallback : XSPI MspDeInit.
215 [..]
216 This function) takes as parameters the HAL peripheral handle and the Callback ID.
217
218 [..]
219 By default, after the HAL_XSPI_Init() and if the state is HAL_XSPI_STATE_RESET
220 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
221 Exception done for MspInit and MspDeInit callbacks that are respectively
222 reset to the legacy weak (surcharged) functions in the HAL_XSPI_Init()
223 and HAL_XSPI_DeInit() only when these callbacks are null (not registered beforehand).
224 If not, MspInit or MspDeInit are not null, the HAL_XSPI_Init() and HAL_XSPI_DeInit()
225 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
226
227 [..]
228 Callbacks can be registered/unregistered in READY state only.
229 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
230 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
231 during the Init/DeInit.
232 In that case first register the MspInit/MspDeInit user callbacks
233 using HAL_XSPI_RegisterCallback() before calling HAL_XSPI_DeInit()
234 or HAL_XSPI_Init() function.
235
236 [..]
237 When The compilation define USE_HAL_XSPI_REGISTER_CALLBACKS is set to 0 or
238 not defined, the callback registering feature is not available
239 and weak (surcharged) callbacks are used.
240
241 @endverbatim
242 ******************************************************************************
243 */
244
245 /* Includes ------------------------------------------------------------------*/
246 #include "stm32h5xx_hal.h"
247
248 #if defined(HSPI) || defined(HSPI1) || defined(HSPI2)|| defined(OCTOSPI) || defined(OCTOSPI1)|| defined(OCTOSPI2)
249
250 /** @addtogroup STM32H5xx_HAL_Driver
251 * @{
252 */
253
254 /** @defgroup XSPI XSPI
255 * @brief XSPI HAL module driver
256 * @{
257 */
258
259 #ifdef HAL_XSPI_MODULE_ENABLED
260
261 /**
262 @cond 0
263 */
264 /* Private typedef -----------------------------------------------------------*/
265
266 /* Private define ------------------------------------------------------------*/
267 #define XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!< Indirect write mode */
268 #define XSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)XSPI_CR_FMODE_0) /*!< Indirect read mode */
269 #define XSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)XSPI_CR_FMODE_1) /*!< Automatic polling mode */
270 #define XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)XSPI_CR_FMODE) /*!< Memory-mapped mode */
271
272 #define XSPI_CFG_STATE_MASK 0x00000004U
273 #define XSPI_BUSY_STATE_MASK 0x00000008U
274
275 /* Private macro -------------------------------------------------------------*/
276 #define IS_XSPI_FUNCTIONAL_MODE(MODE) (((MODE) == XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
277 ((MODE) == XSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
278 ((MODE) == XSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
279 ((MODE) == XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
280
281 /* Private variables ---------------------------------------------------------*/
282
283 /* Private function prototypes -----------------------------------------------*/
284 static void XSPI_DMACplt(DMA_HandleTypeDef *hdma);
285 static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma);
286 static void XSPI_DMAError(DMA_HandleTypeDef *hdma);
287 static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
288 static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag, FlagStatus State,
289 uint32_t Tickstart, uint32_t Timeout);
290 static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd);
291 /**
292 @endcond
293 */
294
295 /* Exported functions --------------------------------------------------------*/
296
297 /** @defgroup XSPI_Exported_Functions XSPI Exported Functions
298 * @{
299 */
300
301 /** @defgroup XSPI_Exported_Functions_Group1 Initialization/de-initialization functions
302 * @brief Initialization and Configuration functions
303 *
304 @verbatim
305 ===============================================================================
306 ##### Initialization and Configuration functions #####
307 ===============================================================================
308 [..]
309 This subsection provides a set of functions allowing to :
310 (+) Initialize the XSPI.
311 (+) De-initialize the XSPI.
312
313 @endverbatim
314 * @{
315 */
316
317 /**
318 * @brief Initialize the XSPI mode according to the specified parameters
319 * in the XSPI_InitTypeDef and initialize the associated handle.
320 * @param hxspi : XSPI handle
321 * @retval HAL status
322 */
HAL_XSPI_Init(XSPI_HandleTypeDef * hxspi)323 HAL_StatusTypeDef HAL_XSPI_Init(XSPI_HandleTypeDef *hxspi)
324 {
325 HAL_StatusTypeDef status = HAL_OK;
326 uint32_t tickstart = HAL_GetTick();
327
328 /* Check the XSPI handle allocation */
329 if (hxspi == NULL)
330 {
331 status = HAL_ERROR;
332 /* No error code can be set set as the handler is null */
333 }
334 else
335 {
336 /* Check the parameters of the initialization structure */
337 assert_param(IS_XSPI_MEMORY_MODE(hxspi->Init.MemoryMode));
338 assert_param(IS_XSPI_MEMORY_TYPE(hxspi->Init.MemoryType));
339 assert_param(IS_XSPI_MEMORY_SIZE(hxspi->Init.MemorySize));
340 assert_param(IS_XSPI_CS_HIGH_TIME_CYCLE(hxspi->Init.ChipSelectHighTimeCycle));
341 assert_param(IS_XSPI_FREE_RUN_CLK(hxspi->Init.FreeRunningClock));
342 assert_param(IS_XSPI_CLOCK_MODE(hxspi->Init.ClockMode));
343 assert_param(IS_XSPI_WRAP_SIZE(hxspi->Init.WrapSize));
344 assert_param(IS_XSPI_CLK_PRESCALER(hxspi->Init.ClockPrescaler));
345 assert_param(IS_XSPI_SAMPLE_SHIFTING(hxspi->Init.SampleShifting));
346 assert_param(IS_XSPI_DHQC(hxspi->Init.DelayHoldQuarterCycle));
347 assert_param(IS_XSPI_CS_BOUND(hxspi->Init.ChipSelectBoundary));
348 assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(hxspi->Init.FifoThresholdByte));
349 if (IS_OSPI_ALL_INSTANCE(hxspi->Instance))
350 {
351 assert_param(IS_XSPI_DLYB_BYPASS(hxspi->Init.DelayBlockBypass));
352 }
353 /* Initialize error code */
354 hxspi->ErrorCode = HAL_XSPI_ERROR_NONE;
355
356 /* Check if the state is the reset state */
357 if (hxspi->State == HAL_XSPI_STATE_RESET)
358 {
359 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
360 /* Reset Callback pointers in HAL_XSPI_STATE_RESET only */
361 hxspi->ErrorCallback = HAL_XSPI_ErrorCallback;
362 hxspi->AbortCpltCallback = HAL_XSPI_AbortCpltCallback;
363 hxspi->FifoThresholdCallback = HAL_XSPI_FifoThresholdCallback;
364 hxspi->CmdCpltCallback = HAL_XSPI_CmdCpltCallback;
365 hxspi->RxCpltCallback = HAL_XSPI_RxCpltCallback;
366 hxspi->TxCpltCallback = HAL_XSPI_TxCpltCallback;
367 hxspi->RxHalfCpltCallback = HAL_XSPI_RxHalfCpltCallback;
368 hxspi->TxHalfCpltCallback = HAL_XSPI_TxHalfCpltCallback;
369 hxspi->StatusMatchCallback = HAL_XSPI_StatusMatchCallback;
370 hxspi->TimeOutCallback = HAL_XSPI_TimeOutCallback;
371
372 if (hxspi->MspInitCallback == NULL)
373 {
374 hxspi->MspInitCallback = HAL_XSPI_MspInit;
375 }
376
377 /* Init the low level hardware */
378 hxspi->MspInitCallback(hxspi);
379 #else
380 /* Initialization of the low level hardware */
381 HAL_XSPI_MspInit(hxspi);
382 #endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
383
384 /* Configure the default timeout for the XSPI memory access */
385 (void)HAL_XSPI_SetTimeout(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
386
387 /* Configure memory type, device size, chip select high time, free running clock, clock mode */
388 MODIFY_REG(hxspi->Instance->DCR1,
389 (XSPI_DCR1_MTYP | XSPI_DCR1_DEVSIZE | XSPI_DCR1_CSHT | XSPI_DCR1_FRCK | XSPI_DCR1_CKMODE),
390 (hxspi->Init.MemoryType | ((hxspi->Init.MemorySize) << XSPI_DCR1_DEVSIZE_Pos) |
391 ((hxspi->Init.ChipSelectHighTimeCycle - 1U) << XSPI_DCR1_CSHT_Pos) | hxspi->Init.ClockMode));
392
393 /* Configure delay block bypass */
394 if (IS_OSPI_ALL_INSTANCE(hxspi->Instance))
395 {
396 MODIFY_REG(hxspi->Instance->DCR1, OCTOSPI_DCR1_DLYBYP, hxspi->Init.DelayBlockBypass);
397 }
398
399 /* Configure wrap size */
400 MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_WRAPSIZE, hxspi->Init.WrapSize);
401
402 /* Configure chip select boundary */
403 MODIFY_REG(hxspi->Instance->DCR3, XSPI_DCR3_CSBOUND, (hxspi->Init.ChipSelectBoundary << XSPI_DCR3_CSBOUND_Pos));
404
405 /* Configure refresh */
406 hxspi->Instance->DCR4 = hxspi->Init.Refresh;
407
408 /* Configure FIFO threshold */
409 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos));
410
411 /* Wait till busy flag is reset */
412 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
413
414 if (status == HAL_OK)
415 {
416 /* Configure clock prescaler */
417 MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER,
418 ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos));
419
420 /* Configure Dual Memory mode */
421 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_DMM, hxspi->Init.MemoryMode);
422
423 /* Configure sample shifting and delay hold quarter cycle */
424 MODIFY_REG(hxspi->Instance->TCR, (XSPI_TCR_SSHIFT | XSPI_TCR_DHQC),
425 (hxspi->Init.SampleShifting | hxspi->Init.DelayHoldQuarterCycle));
426
427 /* Enable XSPI */
428 HAL_XSPI_ENABLE(hxspi);
429
430 /* Enable free running clock if needed : must be done after XSPI enable */
431 if (hxspi->Init.FreeRunningClock == HAL_XSPI_FREERUNCLK_ENABLE)
432 {
433 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
434 }
435
436 /* Initialize the XSPI state */
437 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
438 {
439 hxspi->State = HAL_XSPI_STATE_HYPERBUS_INIT;
440 }
441 else
442 {
443 hxspi->State = HAL_XSPI_STATE_READY;
444 }
445 }
446 }
447 }
448 return status;
449 }
450
451 /**
452 * @brief Initialize the XSPI MSP.
453 * @param hxspi : XSPI handle
454 * @retval None
455 */
HAL_XSPI_MspInit(XSPI_HandleTypeDef * hxspi)456 __weak void HAL_XSPI_MspInit(XSPI_HandleTypeDef *hxspi)
457 {
458 /* Prevent unused argument(s) compilation warning */
459 UNUSED(hxspi);
460
461 /* NOTE : This function should not be modified, when the callback is needed,
462 the HAL_XSPI_MspInit can be implemented in the user file
463 */
464 }
465
466 /**
467 * @brief De-Initialize the XSPI peripheral.
468 * @param hxspi : XSPI handle
469 * @retval HAL status
470 */
HAL_XSPI_DeInit(XSPI_HandleTypeDef * hxspi)471 HAL_StatusTypeDef HAL_XSPI_DeInit(XSPI_HandleTypeDef *hxspi)
472 {
473 HAL_StatusTypeDef status = HAL_OK;
474
475 /* Check the XSPI handle allocation */
476 if (hxspi == NULL)
477 {
478 status = HAL_ERROR;
479 /* No error code can be set as the handler is null */
480 }
481 else
482 {
483 /* Disable XSPI */
484 HAL_XSPI_DISABLE(hxspi);
485
486 /* Disable free running clock if needed : must be done after XSPI disable */
487 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
488
489 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
490 if (hxspi->MspDeInitCallback == NULL)
491 {
492 hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit;
493 }
494
495 /* De-initialize the low level hardware */
496 hxspi->MspDeInitCallback(hxspi);
497 #else
498 /* De-initialize the low-level hardware */
499 HAL_XSPI_MspDeInit(hxspi);
500 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
501
502 /* Reset the driver state */
503 hxspi->State = HAL_XSPI_STATE_RESET;
504 }
505
506 return status;
507 }
508
509 /**
510 * @brief DeInitialize the XSPI MSP.
511 * @param hxspi : XSPI handle
512 * @retval None
513 */
HAL_XSPI_MspDeInit(XSPI_HandleTypeDef * hxspi)514 __weak void HAL_XSPI_MspDeInit(XSPI_HandleTypeDef *hxspi)
515 {
516 /* Prevent unused argument(s) compilation warning */
517 UNUSED(hxspi);
518
519 /* NOTE : This function should not be modified, when the callback is needed,
520 the HAL_XSPI_MspDeInit can be implemented in the user file
521 */
522 }
523
524 /**
525 * @}
526 */
527
528 /** @defgroup XSPI_Exported_Functions_Group2 Input and Output operation functions
529 * @brief XSPI Transmit/Receive functions
530 *
531 @verbatim
532 ===============================================================================
533 ##### IO operation functions #####
534 ===============================================================================
535 [..]
536 This subsection provides a set of functions allowing to :
537 (+) Handle the interrupts.
538 (+) Handle the command sequence (regular and Hyperbus).
539 (+) Handle the Hyperbus configuration.
540 (+) Transmit data in blocking, interrupt or DMA mode.
541 (+) Receive data in blocking, interrupt or DMA mode.
542 (+) Manage the auto-polling functional mode.
543 (+) Manage the memory-mapped functional mode.
544
545 @endverbatim
546 * @{
547 */
548
549 /**
550 * @brief Handle XSPI interrupt request.
551 * @param hxspi : XSPI handle
552 * @retval None
553 */
HAL_XSPI_IRQHandler(XSPI_HandleTypeDef * hxspi)554 void HAL_XSPI_IRQHandler(XSPI_HandleTypeDef *hxspi)
555 {
556 __IO uint32_t *data_reg = &hxspi->Instance->DR;
557 uint32_t flag = hxspi->Instance->SR;
558 uint32_t itsource = hxspi->Instance->CR;
559 uint32_t currentstate = hxspi->State;
560
561 /* XSPI fifo threshold interrupt occurred -------------------------------*/
562 if (((flag & HAL_XSPI_FLAG_FT) != 0U) && ((itsource & HAL_XSPI_IT_FT) != 0U))
563 {
564 if (currentstate == HAL_XSPI_STATE_BUSY_TX)
565 {
566 /* Write a data in the fifo */
567 *((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr;
568 hxspi->pBuffPtr++;
569 hxspi->XferCount--;
570 }
571 else if (currentstate == HAL_XSPI_STATE_BUSY_RX)
572 {
573 /* Read a data from the fifo */
574 *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg);
575 hxspi->pBuffPtr++;
576 hxspi->XferCount--;
577 }
578 else
579 {
580 /* Nothing to do */
581 }
582
583 if (hxspi->XferCount == 0U)
584 {
585 /* All data have been received or transmitted for the transfer */
586 /* Disable fifo threshold interrupt */
587 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_FT);
588 }
589
590 /* Fifo threshold callback */
591 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
592 hxspi->FifoThresholdCallback(hxspi);
593 #else
594 HAL_XSPI_FifoThresholdCallback(hxspi);
595 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
596 }
597 /* XSPI transfer complete interrupt occurred ----------------------------*/
598 else if (((flag & HAL_XSPI_FLAG_TC) != 0U) && ((itsource & HAL_XSPI_IT_TC) != 0U))
599 {
600 if (currentstate == HAL_XSPI_STATE_BUSY_RX)
601 {
602 if ((hxspi->XferCount > 0U) && ((flag & XSPI_SR_FLEVEL) != 0U))
603 {
604 /* Read the last data received in the fifo */
605 *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg);
606 hxspi->pBuffPtr++;
607 hxspi->XferCount--;
608 }
609 else if (hxspi->XferCount == 0U)
610 {
611 /* Clear flag */
612 hxspi->Instance->FCR = HAL_XSPI_FLAG_TC;
613
614 /* Disable the interrupts */
615 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
616
617 hxspi->State = HAL_XSPI_STATE_READY;
618
619 /* RX complete callback */
620 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
621 hxspi->RxCpltCallback(hxspi);
622 #else
623 HAL_XSPI_RxCpltCallback(hxspi);
624 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
625 }
626 else
627 {
628 /* Nothing to do */
629 }
630 }
631 else
632 {
633 /* Clear flag */
634 hxspi->Instance->FCR = HAL_XSPI_FLAG_TC;
635
636 /* Disable the interrupts */
637 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
638
639 hxspi->State = HAL_XSPI_STATE_READY;
640
641 if (currentstate == HAL_XSPI_STATE_BUSY_TX)
642 {
643 /* TX complete callback */
644 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
645 hxspi->TxCpltCallback(hxspi);
646 #else
647 HAL_XSPI_TxCpltCallback(hxspi);
648 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
649 }
650 else if (currentstate == HAL_XSPI_STATE_BUSY_CMD)
651 {
652 /* Command complete callback */
653 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
654 hxspi->CmdCpltCallback(hxspi);
655 #else
656 HAL_XSPI_CmdCpltCallback(hxspi);
657 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
658 }
659 else if (currentstate == HAL_XSPI_STATE_ABORT)
660 {
661 if (hxspi->ErrorCode == HAL_XSPI_ERROR_NONE)
662 {
663 /* Abort called by the user */
664 /* Abort complete callback */
665 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
666 hxspi->AbortCpltCallback(hxspi);
667 #else
668 HAL_XSPI_AbortCpltCallback(hxspi);
669 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
670 }
671 else
672 {
673 /* Abort due to an error (eg : DMA error) */
674 /* Error callback */
675 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
676 hxspi->ErrorCallback(hxspi);
677 #else
678 HAL_XSPI_ErrorCallback(hxspi);
679 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
680 }
681 }
682 else
683 {
684 /* Nothing to do */
685 }
686 }
687 }
688 /* XSPI status match interrupt occurred ---------------------------------*/
689 else if (((flag & HAL_XSPI_FLAG_SM) != 0U) && ((itsource & HAL_XSPI_IT_SM) != 0U))
690 {
691 /* Clear flag */
692 hxspi->Instance->FCR = HAL_XSPI_FLAG_SM;
693
694 /* Check if automatic poll mode stop is activated */
695 if ((hxspi->Instance->CR & XSPI_CR_APMS) != 0U)
696 {
697 /* Disable the interrupts */
698 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_SM | HAL_XSPI_IT_TE);
699
700 hxspi->State = HAL_XSPI_STATE_READY;
701 }
702
703 /* Status match callback */
704 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
705 hxspi->StatusMatchCallback(hxspi);
706 #else
707 HAL_XSPI_StatusMatchCallback(hxspi);
708 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
709 }
710 /* XSPI transfer error interrupt occurred -------------------------------*/
711 else if (((flag & HAL_XSPI_FLAG_TE) != 0U) && ((itsource & HAL_XSPI_IT_TE) != 0U))
712 {
713 /* Clear flag */
714 hxspi->Instance->FCR = HAL_XSPI_FLAG_TE;
715
716 /* Disable all interrupts */
717 HAL_XSPI_DISABLE_IT(hxspi, (HAL_XSPI_IT_TO | HAL_XSPI_IT_SM | HAL_XSPI_IT_FT | HAL_XSPI_IT_TC | HAL_XSPI_IT_TE));
718
719 /* Set error code */
720 hxspi->ErrorCode = HAL_XSPI_ERROR_TRANSFER;
721
722 /* Check if the DMA is enabled */
723 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
724 {
725 /* Disable the DMA transfer on the XSPI side */
726 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
727
728 /* Disable the DMA transmit on the DMA side */
729 hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt;
730 if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK)
731 {
732 hxspi->State = HAL_XSPI_STATE_READY;
733
734 /* Error callback */
735 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
736 hxspi->ErrorCallback(hxspi);
737 #else
738 HAL_XSPI_ErrorCallback(hxspi);
739 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
740 }
741
742 /* Disable the DMA receive on the DMA side */
743 hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt;
744 if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK)
745 {
746 hxspi->State = HAL_XSPI_STATE_READY;
747
748 /* Error callback */
749 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
750 hxspi->ErrorCallback(hxspi);
751 #else
752 HAL_XSPI_ErrorCallback(hxspi);
753 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
754 }
755 }
756 else
757 {
758 hxspi->State = HAL_XSPI_STATE_READY;
759
760 /* Error callback */
761 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
762 hxspi->ErrorCallback(hxspi);
763 #else
764 HAL_XSPI_ErrorCallback(hxspi);
765 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
766 }
767 }
768 /* XSPI timeout interrupt occurred --------------------------------------*/
769 else if (((flag & HAL_XSPI_FLAG_TO) != 0U) && ((itsource & HAL_XSPI_IT_TO) != 0U))
770 {
771 /* Clear flag */
772 hxspi->Instance->FCR = HAL_XSPI_FLAG_TO;
773
774 /* Timeout callback */
775 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
776 hxspi->TimeOutCallback(hxspi);
777 #else
778 HAL_XSPI_TimeOutCallback(hxspi);
779 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
780 }
781 else
782 {
783 /* Nothing to do */
784 }
785 }
786
787 /**
788 * @brief Set the command configuration.
789 * @param hxspi : XSPI handle
790 * @param pCmd : structure that contains the command configuration information
791 * @param Timeout : Timeout duration
792 * @retval HAL status
793 */
HAL_XSPI_Command(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * const pCmd,uint32_t Timeout)794 HAL_StatusTypeDef HAL_XSPI_Command(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd, uint32_t Timeout)
795 {
796 HAL_StatusTypeDef status;
797 uint32_t state;
798 uint32_t tickstart = HAL_GetTick();
799
800 /* Check the parameters of the command structure */
801 assert_param(IS_XSPI_OPERATION_TYPE(pCmd->OperationType));
802 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
803 {
804 assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect));
805 }
806
807 assert_param(IS_XSPI_INSTRUCTION_MODE(pCmd->InstructionMode));
808 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
809 {
810 assert_param(IS_XSPI_INSTRUCTION_WIDTH(pCmd->InstructionWidth));
811 assert_param(IS_XSPI_INSTRUCTION_DTR_MODE(pCmd->InstructionDTRMode));
812 }
813
814 assert_param(IS_XSPI_ADDRESS_MODE(pCmd->AddressMode));
815 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
816 {
817 assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth));
818 assert_param(IS_XSPI_ADDRESS_DTR_MODE(pCmd->AddressDTRMode));
819 }
820
821 assert_param(IS_XSPI_ALT_BYTES_MODE(pCmd->AlternateBytesMode));
822 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
823 {
824 assert_param(IS_XSPI_ALT_BYTES_WIDTH(pCmd->AlternateBytesWidth));
825 assert_param(IS_XSPI_ALT_BYTES_DTR_MODE(pCmd->AlternateBytesDTRMode));
826 }
827
828 assert_param(IS_XSPI_DATA_MODE(pCmd->DataMode));
829
830 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
831 {
832 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
833 {
834 assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength));
835 }
836 assert_param(IS_XSPI_DATA_DTR_MODE(pCmd->DataDTRMode));
837 assert_param(IS_XSPI_DUMMY_CYCLES(pCmd->DummyCycles));
838 }
839
840 assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode));
841 assert_param(IS_XSPI_SIOO_MODE(pCmd->SIOOMode));
842
843 /* Check the state of the driver */
844 state = hxspi->State;
845 if (((state == HAL_XSPI_STATE_READY) && (hxspi->Init.MemoryType != HAL_XSPI_MEMTYPE_HYPERBUS)) ||
846 ((state == HAL_XSPI_STATE_READ_CMD_CFG) && ((pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG) ||
847 (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG))) ||
848 ((state == HAL_XSPI_STATE_WRITE_CMD_CFG) &&
849 ((pCmd->OperationType == HAL_XSPI_OPTYPE_READ_CFG) ||
850 (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG))))
851 {
852 /* Wait till busy flag is reset */
853 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
854
855 if (status == HAL_OK)
856 {
857 /* Initialize error code */
858 hxspi->ErrorCode = HAL_XSPI_ERROR_NONE;
859
860 /* Configure the registers */
861 status = XSPI_ConfigCmd(hxspi, pCmd);
862
863 if (status == HAL_OK)
864 {
865 if (pCmd->DataMode == HAL_XSPI_DATA_NONE)
866 {
867 /* When there is no data phase, the transfer start as soon as the configuration is done
868 so wait until TC flag is set to go back in idle state */
869 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
870
871 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
872 }
873 else
874 {
875 /* Update the state */
876 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
877 {
878 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
879 }
880 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_READ_CFG)
881 {
882 if (hxspi->State == HAL_XSPI_STATE_WRITE_CMD_CFG)
883 {
884 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
885 }
886 else
887 {
888 hxspi->State = HAL_XSPI_STATE_READ_CMD_CFG;
889 }
890 }
891 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
892 {
893 if (hxspi->State == HAL_XSPI_STATE_READ_CMD_CFG)
894 {
895 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
896 }
897 else
898 {
899 hxspi->State = HAL_XSPI_STATE_WRITE_CMD_CFG;
900 }
901 }
902 else
903 {
904 /* Wrap configuration, no state change */
905 }
906 }
907 }
908 }
909 else
910 {
911 status = HAL_BUSY;
912 }
913 }
914 else
915 {
916 status = HAL_ERROR;
917 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
918 }
919
920 return status;
921 }
922
923 /**
924 * @brief Set the command configuration in interrupt mode.
925 * @param hxspi : XSPI handle
926 * @param pCmd : structure that contains the command configuration information
927 * @note This function is used only in Indirect Read or Write Modes
928 * @retval HAL status
929 */
HAL_XSPI_Command_IT(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * const pCmd)930 HAL_StatusTypeDef HAL_XSPI_Command_IT(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd)
931 {
932 HAL_StatusTypeDef status;
933 uint32_t tickstart = HAL_GetTick();
934
935 /* Check the parameters of the command structure */
936 assert_param(IS_XSPI_OPERATION_TYPE(pCmd->OperationType));
937
938 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
939 {
940 assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect));
941 }
942
943 assert_param(IS_XSPI_INSTRUCTION_MODE(pCmd->InstructionMode));
944 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
945 {
946 assert_param(IS_XSPI_INSTRUCTION_WIDTH(pCmd->InstructionWidth));
947 assert_param(IS_XSPI_INSTRUCTION_DTR_MODE(pCmd->InstructionDTRMode));
948 }
949
950 assert_param(IS_XSPI_ADDRESS_MODE(pCmd->AddressMode));
951 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
952 {
953 assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth));
954 assert_param(IS_XSPI_ADDRESS_DTR_MODE(pCmd->AddressDTRMode));
955 }
956
957 assert_param(IS_XSPI_ALT_BYTES_MODE(pCmd->AlternateBytesMode));
958 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
959 {
960 assert_param(IS_XSPI_ALT_BYTES_WIDTH(pCmd->AlternateBytesWidth));
961 assert_param(IS_XSPI_ALT_BYTES_DTR_MODE(pCmd->AlternateBytesDTRMode));
962 }
963
964 assert_param(IS_XSPI_DATA_MODE(pCmd->DataMode));
965
966 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
967 {
968 assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength));
969 assert_param(IS_XSPI_DATA_DTR_MODE(pCmd->DataDTRMode));
970 assert_param(IS_XSPI_DUMMY_CYCLES(pCmd->DummyCycles));
971 }
972
973 assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode));
974 assert_param(IS_XSPI_SIOO_MODE(pCmd->SIOOMode));
975
976 /* Check the state of the driver */
977 if ((hxspi->State == HAL_XSPI_STATE_READY) && (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) &&
978 (pCmd->DataMode == HAL_XSPI_DATA_NONE) && (hxspi->Init.MemoryType != HAL_XSPI_MEMTYPE_HYPERBUS))
979 {
980 /* Wait till busy flag is reset */
981 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
982
983 if (status == HAL_OK)
984 {
985 /* Initialize error code */
986 hxspi->ErrorCode = HAL_XSPI_ERROR_NONE;
987
988 /* Clear flags related to interrupt */
989 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
990
991 /* Configure the registers */
992 status = XSPI_ConfigCmd(hxspi, pCmd);
993
994 if (status == HAL_OK)
995 {
996 /* Update the state */
997 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
998
999 /* Enable the transfer complete and transfer error interrupts */
1000 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_TE);
1001 }
1002 }
1003 }
1004 else
1005 {
1006 status = HAL_ERROR;
1007 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1008 }
1009
1010 return status;
1011 }
1012
1013 /**
1014 * @brief Configure the Hyperbus parameters.
1015 * @param hxspi : XSPI handle
1016 * @param pCfg : Pointer to Structure containing the Hyperbus configuration
1017 * @param Timeout : Timeout duration
1018 * @retval HAL status
1019 */
HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef * hxspi,XSPI_HyperbusCfgTypeDef * const pCfg,uint32_t Timeout)1020 HAL_StatusTypeDef HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCfgTypeDef *const pCfg,
1021 uint32_t Timeout)
1022 {
1023 HAL_StatusTypeDef status;
1024 uint32_t state;
1025 uint32_t tickstart = HAL_GetTick();
1026
1027 /* Check the parameters of the hyperbus configuration structure */
1028 assert_param(IS_XSPI_RW_RECOVERY_TIME_CYCLE(pCfg->RWRecoveryTimeCycle));
1029 assert_param(IS_XSPI_ACCESS_TIME_CYCLE(pCfg->AccessTimeCycle));
1030 assert_param(IS_XSPI_WRITE_ZERO_LATENCY(pCfg->WriteZeroLatency));
1031 assert_param(IS_XSPI_LATENCY_MODE(pCfg->LatencyMode));
1032
1033 /* Check the state of the driver */
1034 state = hxspi->State;
1035 if ((state == HAL_XSPI_STATE_HYPERBUS_INIT) || (state == HAL_XSPI_STATE_READY))
1036 {
1037 /* Wait till busy flag is reset */
1038 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1039
1040 if (status == HAL_OK)
1041 {
1042 /* Configure Hyperbus configuration Latency register */
1043 WRITE_REG(hxspi->Instance->HLCR, ((pCfg->RWRecoveryTimeCycle << XSPI_HLCR_TRWR_Pos) |
1044 (pCfg->AccessTimeCycle << XSPI_HLCR_TACC_Pos) |
1045 pCfg->WriteZeroLatency | pCfg->LatencyMode));
1046
1047 /* Update the state */
1048 hxspi->State = HAL_XSPI_STATE_READY;
1049 }
1050 else
1051 {
1052 status = HAL_BUSY;
1053 }
1054 }
1055 else
1056 {
1057 status = HAL_ERROR;
1058 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1059 }
1060
1061 return status;
1062 }
1063
1064 /**
1065 * @brief Set the Hyperbus command configuration.
1066 * @param hxspi : XSPI handle
1067 * @param pCmd : Structure containing the Hyperbus command
1068 * @param Timeout : Timeout duration
1069 * @retval HAL status
1070 */
HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef * hxspi,XSPI_HyperbusCmdTypeDef * const pCmd,uint32_t Timeout)1071 HAL_StatusTypeDef HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCmdTypeDef *const pCmd,
1072 uint32_t Timeout)
1073 {
1074 HAL_StatusTypeDef status;
1075 uint32_t tickstart = HAL_GetTick();
1076
1077 /* Check the parameters of the hyperbus command structure */
1078 assert_param(IS_XSPI_ADDRESS_SPACE(pCmd->AddressSpace));
1079 assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth));
1080 assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength));
1081 assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode));
1082
1083 /* Check the state of the driver */
1084 if ((hxspi->State == HAL_XSPI_STATE_READY) && (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS))
1085 {
1086 /* Wait till busy flag is reset */
1087 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1088
1089 if (status == HAL_OK)
1090 {
1091 /* Re-initialize the value of the functional mode */
1092 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U);
1093
1094 /* Configure the address space in the DCR1 register */
1095 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP_0, pCmd->AddressSpace);
1096
1097 /* Configure the CCR and WCCR registers with the address size and the following configuration :
1098 - DQS signal enabled (used as RWDS)
1099 - DTR mode enabled on address and data */
1100 /* - address and data on 8 lines */
1101 WRITE_REG(hxspi->Instance->CCR, (pCmd->DQSMode | XSPI_CCR_DDTR | XSPI_CCR_DMODE_2 |
1102 pCmd->AddressWidth | XSPI_CCR_ADDTR | XSPI_CCR_ADMODE_2));
1103 WRITE_REG(hxspi->Instance->WCCR, (pCmd->DQSMode | XSPI_WCCR_DDTR | XSPI_WCCR_DMODE_2 |
1104 pCmd->AddressWidth | XSPI_WCCR_ADDTR | XSPI_WCCR_ADMODE_2));
1105
1106 /* Configure the DLR register with the number of data */
1107 WRITE_REG(hxspi->Instance->DLR, (pCmd->DataLength - 1U));
1108
1109 /* Configure the AR register with the address value */
1110 WRITE_REG(hxspi->Instance->AR, pCmd->Address);
1111
1112 /* Update the state */
1113 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
1114 }
1115 else
1116 {
1117 status = HAL_BUSY;
1118 }
1119 }
1120 else
1121 {
1122 status = HAL_ERROR;
1123 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1124 }
1125
1126 return status;
1127 }
1128
1129 /**
1130 * @brief Transmit an amount of data in blocking mode.
1131 * @param hxspi : XSPI handle
1132 * @param pData : pointer to data buffer
1133 * @param Timeout : Timeout duration
1134 * @note This function is used only in Indirect Write Mode
1135 * @retval HAL status
1136 */
HAL_XSPI_Transmit(XSPI_HandleTypeDef * hxspi,uint8_t * const pData,uint32_t Timeout)1137 HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout)
1138 {
1139 HAL_StatusTypeDef status;
1140 uint32_t tickstart = HAL_GetTick();
1141 __IO uint32_t *data_reg = &hxspi->Instance->DR;
1142
1143 /* Check the data pointer allocation */
1144 if (pData == NULL)
1145 {
1146 status = HAL_ERROR;
1147 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1148 }
1149 else
1150 {
1151 /* Check the state */
1152 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1153 {
1154 /* Configure counters and size */
1155 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1156 hxspi->XferSize = hxspi->XferCount;
1157 hxspi->pBuffPtr = pData;
1158
1159 /* Configure CR register with functional mode as indirect write */
1160 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1161
1162 do
1163 {
1164 /* Wait till fifo threshold flag is set to send data */
1165 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_FT, SET, tickstart, Timeout);
1166
1167 if (status != HAL_OK)
1168 {
1169 break;
1170 }
1171
1172 *((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr;
1173 hxspi->pBuffPtr++;
1174 hxspi->XferCount--;
1175 } while (hxspi->XferCount > 0U);
1176
1177 if (status == HAL_OK)
1178 {
1179 /* Wait till transfer complete flag is set to go back in idle state */
1180 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
1181
1182 if (status == HAL_OK)
1183 {
1184 /* Clear transfer complete flag */
1185 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
1186
1187 hxspi->State = HAL_XSPI_STATE_READY;
1188 }
1189 }
1190 }
1191 else
1192 {
1193 status = HAL_ERROR;
1194 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1195 }
1196 }
1197
1198 return status;
1199 }
1200
1201 /**
1202 * @brief Receive an amount of data in blocking mode.
1203 * @param hxspi : XSPI handle
1204 * @param pData : pointer to data buffer
1205 * @param Timeout : Timeout duration
1206 * @note This function is used only in Indirect Read Mode
1207 * @retval HAL status
1208 */
HAL_XSPI_Receive(XSPI_HandleTypeDef * hxspi,uint8_t * const pData,uint32_t Timeout)1209 HAL_StatusTypeDef HAL_XSPI_Receive(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout)
1210 {
1211 HAL_StatusTypeDef status;
1212 uint32_t tickstart = HAL_GetTick();
1213 __IO uint32_t *data_reg = &hxspi->Instance->DR;
1214 uint32_t addr_reg = hxspi->Instance->AR;
1215 uint32_t ir_reg = hxspi->Instance->IR;
1216
1217 /* Check the data pointer allocation */
1218 if (pData == NULL)
1219 {
1220 status = HAL_ERROR;
1221 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1222 }
1223 else
1224 {
1225 /* Check the state */
1226 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1227 {
1228 /* Configure counters and size */
1229 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1230 hxspi->XferSize = hxspi->XferCount;
1231 hxspi->pBuffPtr = pData;
1232
1233 /* Configure CR register with functional mode as indirect read */
1234 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1235
1236 /* Trig the transfer by re-writing address or instruction register */
1237 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1238 {
1239 WRITE_REG(hxspi->Instance->AR, addr_reg);
1240 }
1241 else
1242 {
1243 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1244 {
1245 WRITE_REG(hxspi->Instance->AR, addr_reg);
1246 }
1247 else
1248 {
1249 WRITE_REG(hxspi->Instance->IR, ir_reg);
1250 }
1251 }
1252
1253 do
1254 {
1255 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1256 status = XSPI_WaitFlagStateUntilTimeout(hxspi, (HAL_XSPI_FLAG_FT | HAL_XSPI_FLAG_TC), SET, tickstart, Timeout);
1257
1258 if (status != HAL_OK)
1259 {
1260 break;
1261 }
1262
1263 *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg);
1264 hxspi->pBuffPtr++;
1265 hxspi->XferCount--;
1266 } while (hxspi->XferCount > 0U);
1267
1268 if (status == HAL_OK)
1269 {
1270 /* Wait till transfer complete flag is set to go back in idle state */
1271 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
1272
1273 if (status == HAL_OK)
1274 {
1275 /* Clear transfer complete flag */
1276 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
1277
1278 hxspi->State = HAL_XSPI_STATE_READY;
1279 }
1280 }
1281 }
1282 else
1283 {
1284 status = HAL_ERROR;
1285 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1286 }
1287 }
1288
1289 return status;
1290 }
1291
1292 /**
1293 * @brief Send an amount of data in non-blocking mode with interrupt.
1294 * @param hxspi : XSPI handle
1295 * @param pData : pointer to data buffer
1296 * @note This function is used only in Indirect Write Mode
1297 * @retval HAL status
1298 */
HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1299 HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1300 {
1301 HAL_StatusTypeDef status = HAL_OK;
1302
1303 /* Check the data pointer allocation */
1304 if (pData == NULL)
1305 {
1306 status = HAL_ERROR;
1307 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1308 }
1309 else
1310 {
1311 /* Check the state */
1312 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1313 {
1314 /* Configure counters and size */
1315 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1316 hxspi->XferSize = hxspi->XferCount;
1317 hxspi->pBuffPtr = pData;
1318
1319 /* Configure CR register with functional mode as indirect write */
1320 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1321
1322 /* Clear flags related to interrupt */
1323 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1324
1325 /* Update the state */
1326 hxspi->State = HAL_XSPI_STATE_BUSY_TX;
1327
1328 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1329 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
1330 }
1331 else
1332 {
1333 status = HAL_ERROR;
1334 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1335 }
1336 }
1337
1338 return status;
1339 }
1340
1341 /**
1342 * @brief Receive an amount of data in non-blocking mode with interrupt.
1343 * @param hxspi : XSPI handle
1344 * @param pData : pointer to data buffer
1345 * @note This function is used only in Indirect Read Mode
1346 * @retval HAL status
1347 */
HAL_XSPI_Receive_IT(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1348 HAL_StatusTypeDef HAL_XSPI_Receive_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1349 {
1350 HAL_StatusTypeDef status = HAL_OK;
1351 uint32_t addr_reg = hxspi->Instance->AR;
1352 uint32_t ir_reg = hxspi->Instance->IR;
1353
1354 /* Check the data pointer allocation */
1355 if (pData == NULL)
1356 {
1357 status = HAL_ERROR;
1358 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1359 }
1360 else
1361 {
1362 /* Check the state */
1363 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1364 {
1365 /* Configure counters and size */
1366 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1367 hxspi->XferSize = hxspi->XferCount;
1368 hxspi->pBuffPtr = pData;
1369
1370 /* Configure CR register with functional mode as indirect read */
1371 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1372
1373 /* Clear flags related to interrupt */
1374 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1375
1376 /* Update the state */
1377 hxspi->State = HAL_XSPI_STATE_BUSY_RX;
1378
1379 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1380 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
1381
1382 /* Trig the transfer by re-writing address or instruction register */
1383 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1384 {
1385 WRITE_REG(hxspi->Instance->AR, addr_reg);
1386 }
1387 else
1388 {
1389 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1390 {
1391 WRITE_REG(hxspi->Instance->AR, addr_reg);
1392 }
1393 else
1394 {
1395 WRITE_REG(hxspi->Instance->IR, ir_reg);
1396 }
1397 }
1398 }
1399 else
1400 {
1401 status = HAL_ERROR;
1402 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1403 }
1404 }
1405
1406 return status;
1407 }
1408
1409 /**
1410 * @brief Send an amount of data in non-blocking mode with DMA.
1411 * @param hxspi : XSPI handle
1412 * @param pData : pointer to data buffer
1413 * @note This function is used only in Indirect Write Mode
1414 * @note If DMA peripheral access is configured as halfword, the number
1415 * of data and the fifo threshold should be aligned on halfword
1416 * @note If DMA peripheral access is configured as word, the number
1417 * of data and the fifo threshold should be aligned on word
1418 * @retval HAL status
1419 */
HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1420 HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1421 {
1422 HAL_StatusTypeDef status = HAL_OK;
1423 uint32_t data_size = hxspi->Instance->DLR + 1U;
1424 DMA_QListTypeDef *p_queue = {NULL};
1425 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1426
1427 /* Check the data pointer allocation */
1428 if (pData == NULL)
1429 {
1430 status = HAL_ERROR;
1431 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1432 }
1433 else
1434 {
1435 /* Check the state */
1436 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1437 {
1438 if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1439 {
1440 p_queue = hxspi->hdmatx->LinkedListQueue;
1441 if ((p_queue != NULL) && (p_queue->Head != NULL))
1442 {
1443 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1444 }
1445 else
1446 {
1447 /* Set Error Code function status */
1448 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1449
1450 /* Return function status */
1451 status = HAL_ERROR;
1452 }
1453 }
1454 else
1455 {
1456 data_width = hxspi->hdmatx->Init.DestDataWidth;
1457 }
1458 /* Configure counters and size */
1459 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1460 {
1461 hxspi->XferCount = data_size;
1462 }
1463 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1464 {
1465 if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U))
1466 {
1467 /* The number of data or the fifo threshold is not aligned on halfword
1468 => no transfer possible with DMA peripheral access configured as halfword */
1469 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1470 status = HAL_ERROR;
1471 }
1472 else
1473 {
1474 hxspi->XferCount = data_size;
1475 }
1476 }
1477 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1478 {
1479 if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U))
1480 {
1481 /* The number of data or the fifo threshold is not aligned on word
1482 => no transfer possible with DMA peripheral access configured as word */
1483 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1484 status = HAL_ERROR;
1485 }
1486 else
1487 {
1488 hxspi->XferCount = data_size;
1489 }
1490 }
1491 else
1492 {
1493 /* Nothing to do */
1494 }
1495
1496 if (status == HAL_OK)
1497 {
1498 hxspi->XferSize = hxspi->XferCount;
1499 hxspi->pBuffPtr = pData;
1500
1501 /* Configure CR register with functional mode as indirect write */
1502 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1503
1504 /* Clear flags related to interrupt */
1505 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1506
1507 /* Update the state */
1508 hxspi->State = HAL_XSPI_STATE_BUSY_TX;
1509
1510 /* Set the DMA transfer complete callback */
1511 hxspi->hdmatx->XferCpltCallback = XSPI_DMACplt;
1512
1513 /* Set the DMA Half transfer complete callback */
1514 hxspi->hdmatx->XferHalfCpltCallback = XSPI_DMAHalfCplt;
1515
1516 /* Set the DMA error callback */
1517 hxspi->hdmatx->XferErrorCallback = XSPI_DMAError;
1518
1519 /* Clear the DMA abort callback */
1520 hxspi->hdmatx->XferAbortCallback = NULL;
1521
1522 /* Enable the transmit DMA Channel */
1523 if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1524 {
1525 if (hxspi->hdmatx->LinkedListQueue != NULL)
1526 {
1527 /* Enable the DMA channel */
1528 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1529 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_INCREMENTED | DMA_DINC_FIXED));
1530 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1531 DMA_CTR2_DREQ, DMA_MEMORY_TO_PERIPH);
1532 /* Set DMA data size*/
1533 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize;
1534 /* Set DMA source address */
1535 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
1536 /* Set DMA destination address */
1537 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR;
1538
1539 status = HAL_DMAEx_List_Start_IT(hxspi->hdmatx);
1540 }
1541 else
1542 {
1543 /* Set Error Code */
1544 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1545
1546 hxspi->State = HAL_XSPI_STATE_READY;
1547
1548 /* Return function status */
1549 status = HAL_ERROR;
1550 }
1551 }
1552 else
1553 {
1554 if ((hxspi->hdmatx->Init.Direction == DMA_MEMORY_TO_PERIPH) &&
1555 (hxspi->hdmatx->Init.SrcInc == DMA_SINC_INCREMENTED) && (hxspi->hdmatx->Init.DestInc == DMA_DINC_FIXED))
1556 {
1557 status = HAL_DMA_Start_IT(hxspi->hdmatx, (uint32_t)pData, (uint32_t)&hxspi->Instance->DR, hxspi->XferSize);
1558 }
1559 else
1560 {
1561 /* no transmit possible with DMA peripheral, invalid configuration */
1562 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1563 status = HAL_ERROR;
1564 }
1565 }
1566 if (status == HAL_OK)
1567 {
1568 /* Enable the transfer error interrupt */
1569 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE);
1570
1571 /* Enable the DMA transfer by setting the DMAEN bit */
1572 SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
1573 }
1574 else
1575 {
1576 status = HAL_ERROR;
1577 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1578 hxspi->State = HAL_XSPI_STATE_READY;
1579 }
1580 }
1581 }
1582 else
1583 {
1584 status = HAL_ERROR;
1585 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1586 }
1587 }
1588
1589 return status;
1590 }
1591
1592 /**
1593 * @brief Receive an amount of data in non-blocking mode with DMA.
1594 * @param hxspi : XSPI handle
1595 * @param pData : pointer to data buffer.
1596 * @note This function is used only in Indirect Read Mode
1597 * @note If DMA peripheral access is configured as halfword, the number
1598 * of data and the fifo threshold should be aligned on halfword
1599 * @note If DMA peripheral access is configured as word, the number
1600 * of data and the fifo threshold should be aligned on word
1601 * @retval HAL status
1602 */
HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1603 HAL_StatusTypeDef HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1604 {
1605 HAL_StatusTypeDef status = HAL_OK;
1606 uint32_t data_size = hxspi->Instance->DLR + 1U;
1607 uint32_t addr_reg = hxspi->Instance->AR;
1608 uint32_t ir_reg = hxspi->Instance->IR;
1609 DMA_QListTypeDef *p_queue = {NULL};
1610 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1611
1612 /* Check the data pointer allocation */
1613 if (pData == NULL)
1614 {
1615 status = HAL_ERROR;
1616 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1617 }
1618 else
1619 {
1620 /* Check the state */
1621 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1622 {
1623 if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1624 {
1625 p_queue = hxspi->hdmarx->LinkedListQueue;
1626 if ((p_queue != NULL) && (p_queue->Head != NULL))
1627 {
1628 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1629 }
1630 else
1631 {
1632 /* Set Error Code */
1633 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1634
1635 /* Return function status */
1636 status = HAL_ERROR;
1637 }
1638 }
1639 else
1640 {
1641 data_width = hxspi->hdmarx->Init.DestDataWidth;
1642 }
1643
1644 /* Configure counters and size */
1645 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1646 {
1647 hxspi->XferCount = data_size;
1648 }
1649 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1650 {
1651 if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U))
1652 {
1653 /* The number of data or the fifo threshold is not aligned on halfword
1654 => no transfer possible with DMA peripheral access configured as halfword */
1655 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1656 status = HAL_ERROR;
1657 }
1658 else
1659 {
1660 hxspi->XferCount = data_size;
1661 }
1662 }
1663 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1664 {
1665 if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U))
1666 {
1667 /* The number of data or the fifo threshold is not aligned on word
1668 => no transfer possible with DMA peripheral access configured as word */
1669 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1670 status = HAL_ERROR;
1671 }
1672 else
1673 {
1674 hxspi->XferCount = data_size;
1675 }
1676 }
1677 else
1678 {
1679 /* Nothing to do */
1680 }
1681
1682 if (status == HAL_OK)
1683 {
1684 hxspi->XferSize = hxspi->XferCount;
1685 hxspi->pBuffPtr = pData;
1686
1687 /* Configure CR register with functional mode as indirect read */
1688 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1689
1690 /* Clear flags related to interrupt */
1691 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1692
1693 /* Update the state */
1694 hxspi->State = HAL_XSPI_STATE_BUSY_RX;
1695
1696 /* Set the DMA transfer complete callback */
1697 hxspi->hdmarx->XferCpltCallback = XSPI_DMACplt;
1698
1699 /* Set the DMA Half transfer complete callback */
1700 hxspi->hdmarx->XferHalfCpltCallback = XSPI_DMAHalfCplt;
1701
1702 /* Set the DMA error callback */
1703 hxspi->hdmarx->XferErrorCallback = XSPI_DMAError;
1704
1705 /* Clear the DMA abort callback */
1706 hxspi->hdmarx->XferAbortCallback = NULL;
1707
1708 /* Enable the receive DMA Channel */
1709 if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1710 {
1711 if (hxspi->hdmarx->LinkedListQueue != NULL)
1712 {
1713 /* Enable the DMA channel */
1714 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1715 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_FIXED | DMA_DINC_INCREMENTED));
1716 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1717 DMA_CTR2_DREQ, DMA_PERIPH_TO_MEMORY);
1718 /* Set DMA data size */
1719 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize;
1720 /* Set DMA source address */
1721 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR;
1722 /* Set DMA destination address */
1723 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
1724
1725 status = HAL_DMAEx_List_Start_IT(hxspi->hdmarx);
1726 }
1727 else
1728 {
1729 /* Set Error Code */
1730 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1731
1732 hxspi->State = HAL_XSPI_STATE_READY;
1733
1734 /* Return function status */
1735 status = HAL_ERROR;
1736 }
1737 }
1738 else
1739 {
1740 if ((hxspi->hdmarx->Init.Direction == DMA_PERIPH_TO_MEMORY) && (hxspi->hdmarx->Init.SrcInc == DMA_SINC_FIXED)
1741 && (hxspi->hdmarx->Init.DestInc == DMA_DINC_INCREMENTED))
1742 {
1743 status = HAL_DMA_Start_IT(hxspi->hdmarx, (uint32_t)&hxspi->Instance->DR, (uint32_t)pData, hxspi->XferSize);
1744 }
1745 else
1746 {
1747 /* no receive possible with DMA peripheral, invalid configuration */
1748 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1749 status = HAL_ERROR;
1750 }
1751 }
1752 if (status == HAL_OK)
1753 {
1754 /* Enable the transfer error interrupt */
1755 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE);
1756
1757 /* Trig the transfer by re-writing address or instruction register */
1758 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1759 {
1760 WRITE_REG(hxspi->Instance->AR, addr_reg);
1761 }
1762 else
1763 {
1764 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1765 {
1766 WRITE_REG(hxspi->Instance->AR, addr_reg);
1767 }
1768 else
1769 {
1770 WRITE_REG(hxspi->Instance->IR, ir_reg);
1771 }
1772 }
1773
1774 /* Enable the DMA transfer by setting the DMAEN bit */
1775 SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
1776 }
1777 else
1778 {
1779 status = HAL_ERROR;
1780 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1781 hxspi->State = HAL_XSPI_STATE_READY;
1782 }
1783 }
1784 }
1785 else
1786 {
1787 status = HAL_ERROR;
1788 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1789 }
1790 }
1791
1792 return status;
1793 }
1794
1795 /**
1796 * @brief Configure the XSPI Automatic Polling Mode in blocking mode.
1797 * @param hxspi : XSPI handle
1798 * @param pCfg : Pointer to structure that contains the polling configuration information.
1799 * @param Timeout : Timeout duration
1800 * @note This function is used only in Automatic Polling Mode
1801 * @retval HAL status
1802 */
HAL_XSPI_AutoPolling(XSPI_HandleTypeDef * hxspi,XSPI_AutoPollingTypeDef * const pCfg,uint32_t Timeout)1803 HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg,
1804 uint32_t Timeout)
1805 {
1806 HAL_StatusTypeDef status;
1807 uint32_t tickstart = HAL_GetTick();
1808 uint32_t addr_reg = hxspi->Instance->AR;
1809 uint32_t ir_reg = hxspi->Instance->IR;
1810 #ifdef USE_FULL_ASSERT
1811 uint32_t dlr_reg = hxspi->Instance->DLR;
1812 #endif /* USE_FULL_ASSERT */
1813
1814 /* Check the parameters of the autopolling configuration structure */
1815 assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode));
1816 assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop));
1817 assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime));
1818 assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1819
1820 /* Check the state */
1821 if ((hxspi->State == HAL_XSPI_STATE_CMD_CFG) && (pCfg->AutomaticStop == HAL_XSPI_AUTOMATIC_STOP_ENABLE))
1822 {
1823 /* Wait till busy flag is reset */
1824 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1825
1826 if (status == HAL_OK)
1827 {
1828 /* Configure registers */
1829 WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue);
1830 WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask);
1831 WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime);
1832 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE),
1833 (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1834
1835 /* Trig the transfer by re-writing address or instruction register */
1836 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1837 {
1838 WRITE_REG(hxspi->Instance->AR, addr_reg);
1839 }
1840 else
1841 {
1842 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1843 {
1844 WRITE_REG(hxspi->Instance->AR, addr_reg);
1845 }
1846 else
1847 {
1848 WRITE_REG(hxspi->Instance->IR, ir_reg);
1849 }
1850 }
1851
1852 /* Wait till status match flag is set to go back in idle state */
1853 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_SM, SET, tickstart, Timeout);
1854
1855 if (status == HAL_OK)
1856 {
1857 /* Clear status match flag */
1858 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_SM);
1859
1860 hxspi->State = HAL_XSPI_STATE_READY;
1861 }
1862 }
1863 else
1864 {
1865 status = HAL_BUSY;
1866 }
1867 }
1868 else
1869 {
1870 status = HAL_ERROR;
1871 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1872 }
1873
1874 return status;
1875 }
1876
1877 /**
1878 * @brief Configure the XSPI Automatic Polling Mode in non-blocking mode.
1879 * @param hxspi : XSPI handle
1880 * @param pCfg : Pointer to structure that contains the polling configuration information.
1881 * @note This function is used only in Automatic Polling Mode
1882 * @retval HAL status
1883 */
HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef * hxspi,XSPI_AutoPollingTypeDef * const pCfg)1884 HAL_StatusTypeDef HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg)
1885 {
1886 HAL_StatusTypeDef status;
1887 uint32_t tickstart = HAL_GetTick();
1888 uint32_t addr_reg = hxspi->Instance->AR;
1889 uint32_t ir_reg = hxspi->Instance->IR;
1890 #ifdef USE_FULL_ASSERT
1891 uint32_t dlr_reg = hxspi->Instance->DLR;
1892 #endif /* USE_FULL_ASSERT */
1893
1894 /* Check the parameters of the autopolling configuration structure */
1895 assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode));
1896 assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop));
1897 assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime));
1898 assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1899
1900 /* Check the state */
1901 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1902 {
1903 /* Wait till busy flag is reset */
1904 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
1905
1906 if (status == HAL_OK)
1907 {
1908 /* Configure registers */
1909 WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue);
1910 WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask);
1911 WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime);
1912 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE),
1913 (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1914
1915 /* Clear flags related to interrupt */
1916 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_SM);
1917
1918 hxspi->State = HAL_XSPI_STATE_BUSY_AUTO_POLLING;
1919
1920 /* Enable the status match and transfer error interrupts */
1921 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_SM | HAL_XSPI_IT_TE);
1922
1923 /* Trig the transfer by re-writing address or instruction register */
1924 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1925 {
1926 WRITE_REG(hxspi->Instance->AR, addr_reg);
1927 }
1928 else
1929 {
1930 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1931 {
1932 WRITE_REG(hxspi->Instance->AR, addr_reg);
1933 }
1934 else
1935 {
1936 WRITE_REG(hxspi->Instance->IR, ir_reg);
1937 }
1938 }
1939 }
1940 }
1941 else
1942 {
1943 status = HAL_ERROR;
1944 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1945 }
1946
1947 return status;
1948 }
1949
1950 /**
1951 * @brief Configure the Memory Mapped mode.
1952 * @param hxspi : XSPI handle
1953 * @param pCfg : Pointer to structure that contains the memory mapped configuration information.
1954 * @note This function is used only in Memory mapped Mode
1955 * @retval HAL status
1956 */
HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef * hxspi,XSPI_MemoryMappedTypeDef * const pCfg)1957 HAL_StatusTypeDef HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef *hxspi, XSPI_MemoryMappedTypeDef *const pCfg)
1958 {
1959 HAL_StatusTypeDef status;
1960 uint32_t tickstart = HAL_GetTick();
1961
1962 /* Check the parameters of the memory-mapped configuration structure */
1963 assert_param(IS_XSPI_TIMEOUT_ACTIVATION(pCfg->TimeOutActivation));
1964
1965 /* Check the state */
1966 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1967 {
1968 /* Wait till busy flag is reset */
1969 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
1970
1971 if (status == HAL_OK)
1972 {
1973 hxspi->State = HAL_XSPI_STATE_BUSY_MEM_MAPPED;
1974
1975 if (pCfg->TimeOutActivation == HAL_XSPI_TIMEOUT_COUNTER_ENABLE)
1976 {
1977 assert_param(IS_XSPI_TIMEOUT_PERIOD(pCfg->TimeoutPeriodClock));
1978
1979 /* Configure register */
1980 WRITE_REG(hxspi->Instance->LPTR, pCfg->TimeoutPeriodClock);
1981
1982 /* Clear flags related to interrupt */
1983 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TO);
1984
1985 /* Enable the timeout interrupt */
1986 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TO);
1987 }
1988
1989 /* Configure CR register with functional mode as memory-mapped */
1990 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_TCEN | XSPI_CR_FMODE),
1991 (pCfg->TimeOutActivation | XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1992 }
1993 }
1994 else
1995 {
1996 status = HAL_ERROR;
1997 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1998 }
1999
2000 return status;
2001 }
2002
2003 /**
2004 * @brief Transfer Error callback.
2005 * @param hxspi : XSPI handle
2006 * @retval None
2007 */
HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef * hxspi)2008 __weak void HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef *hxspi)
2009 {
2010 /* Prevent unused argument(s) compilation warning */
2011 UNUSED(hxspi);
2012
2013 /* NOTE : This function should not be modified, when the callback is needed,
2014 the HAL_XSPI_ErrorCallback could be implemented in the user file
2015 */
2016 }
2017
2018 /**
2019 * @brief Abort completed callback.
2020 * @param hxspi : XSPI handle
2021 * @retval None
2022 */
HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef * hxspi)2023 __weak void HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef *hxspi)
2024 {
2025 /* Prevent unused argument(s) compilation warning */
2026 UNUSED(hxspi);
2027
2028 /* NOTE: This function should not be modified, when the callback is needed,
2029 the HAL_XSPI_AbortCpltCallback could be implemented in the user file
2030 */
2031 }
2032
2033 /**
2034 * @brief FIFO Threshold callback.
2035 * @param hxspi : XSPI handle
2036 * @retval None
2037 */
HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef * hxspi)2038 __weak void HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef *hxspi)
2039 {
2040 /* Prevent unused argument(s) compilation warning */
2041 UNUSED(hxspi);
2042
2043 /* NOTE : This function should not be modified, when the callback is needed,
2044 the HAL_XSPI_FIFOThresholdCallback could be implemented in the user file
2045 */
2046 }
2047
2048 /**
2049 * @brief Command completed callback.
2050 * @param hxspi : XSPI handle
2051 * @retval None
2052 */
HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef * hxspi)2053 __weak void HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef *hxspi)
2054 {
2055 /* Prevent unused argument(s) compilation warning */
2056 UNUSED(hxspi);
2057
2058 /* NOTE: This function should not be modified, when the callback is needed,
2059 the HAL_XSPI_CmdCpltCallback could be implemented in the user file
2060 */
2061 }
2062
2063 /**
2064 * @brief Rx Transfer completed callback.
2065 * @param hxspi : XSPI handle
2066 * @retval None
2067 */
HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef * hxspi)2068 __weak void HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef *hxspi)
2069 {
2070 /* Prevent unused argument(s) compilation warning */
2071 UNUSED(hxspi);
2072
2073 /* NOTE: This function should not be modified, when the callback is needed,
2074 the HAL_XSPI_RxCpltCallback could be implemented in the user file
2075 */
2076 }
2077
2078 /**
2079 * @brief Tx Transfer completed callback.
2080 * @param hxspi : XSPI handle
2081 * @retval None
2082 */
HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef * hxspi)2083 __weak void HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef *hxspi)
2084 {
2085 /* Prevent unused argument(s) compilation warning */
2086 UNUSED(hxspi);
2087
2088 /* NOTE: This function should not be modified, when the callback is needed,
2089 the HAL_XSPI_TxCpltCallback could be implemented in the user file
2090 */
2091 }
2092
2093 /**
2094 * @brief Rx Half Transfer completed callback.
2095 * @param hxspi : XSPI handle
2096 * @retval None
2097 */
HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef * hxspi)2098 __weak void HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef *hxspi)
2099 {
2100 /* Prevent unused argument(s) compilation warning */
2101 UNUSED(hxspi);
2102
2103 /* NOTE: This function should not be modified, when the callback is needed,
2104 the HAL_XSPI_RxHalfCpltCallback could be implemented in the user file
2105 */
2106 }
2107
2108 /**
2109 * @brief Tx Half Transfer completed callback.
2110 * @param hxspi : XSPI handle
2111 * @retval None
2112 */
HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef * hxspi)2113 __weak void HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef *hxspi)
2114 {
2115 /* Prevent unused argument(s) compilation warning */
2116 UNUSED(hxspi);
2117
2118 /* NOTE: This function should not be modified, when the callback is needed,
2119 the HAL_XSPI_TxHalfCpltCallback could be implemented in the user file
2120 */
2121 }
2122
2123 /**
2124 * @brief Status Match callback.
2125 * @param hxspi : XSPI handle
2126 * @retval None
2127 */
HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef * hxspi)2128 __weak void HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef *hxspi)
2129 {
2130 /* Prevent unused argument(s) compilation warning */
2131 UNUSED(hxspi);
2132
2133 /* NOTE : This function should not be modified, when the callback is needed,
2134 the HAL_XSPI_StatusMatchCallback could be implemented in the user file
2135 */
2136 }
2137
2138 /**
2139 * @brief Timeout callback.
2140 * @param hxspi : XSPI handle
2141 * @retval None
2142 */
HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef * hxspi)2143 __weak void HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef *hxspi)
2144 {
2145 /* Prevent unused argument(s) compilation warning */
2146 UNUSED(hxspi);
2147
2148 /* NOTE : This function should not be modified, when the callback is needed,
2149 the HAL_XSPI_TimeOutCallback could be implemented in the user file
2150 */
2151 }
2152
2153 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2154 /**
2155 * @brief Register a User XSPI Callback
2156 * To be used instead of the weak (surcharged) predefined callback
2157 * @param hxspi : XSPI handle
2158 * @param CallbackID : ID of the callback to be registered
2159 * This parameter can be one of the following values:
2160 * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID
2161 * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID
2162 * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID
2163 * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID
2164 * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID
2165 * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID
2166 * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID
2167 * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID
2168 * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID
2169 * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID
2170 * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID
2171 * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID
2172 * @param pCallback : pointer to the Callback function
2173 * @retval status
2174 */
HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef * hxspi,HAL_XSPI_CallbackIDTypeDef CallbackID,pXSPI_CallbackTypeDef pCallback)2175 HAL_StatusTypeDef HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID,
2176 pXSPI_CallbackTypeDef pCallback)
2177 {
2178 HAL_StatusTypeDef status = HAL_OK;
2179
2180 if (pCallback == NULL)
2181 {
2182 /* Update the error code */
2183 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2184 return HAL_ERROR;
2185 }
2186
2187 if (hxspi->State == HAL_XSPI_STATE_READY)
2188 {
2189 switch (CallbackID)
2190 {
2191 case HAL_XSPI_ERROR_CB_ID :
2192 hxspi->ErrorCallback = pCallback;
2193 break;
2194 case HAL_XSPI_ABORT_CB_ID :
2195 hxspi->AbortCpltCallback = pCallback;
2196 break;
2197 case HAL_XSPI_FIFO_THRESHOLD_CB_ID :
2198 hxspi->FifoThresholdCallback = pCallback;
2199 break;
2200 case HAL_XSPI_CMD_CPLT_CB_ID :
2201 hxspi->CmdCpltCallback = pCallback;
2202 break;
2203 case HAL_XSPI_RX_CPLT_CB_ID :
2204 hxspi->RxCpltCallback = pCallback;
2205 break;
2206 case HAL_XSPI_TX_CPLT_CB_ID :
2207 hxspi->TxCpltCallback = pCallback;
2208 break;
2209 case HAL_XSPI_RX_HALF_CPLT_CB_ID :
2210 hxspi->RxHalfCpltCallback = pCallback;
2211 break;
2212 case HAL_XSPI_TX_HALF_CPLT_CB_ID :
2213 hxspi->TxHalfCpltCallback = pCallback;
2214 break;
2215 case HAL_XSPI_STATUS_MATCH_CB_ID :
2216 hxspi->StatusMatchCallback = pCallback;
2217 break;
2218 case HAL_XSPI_TIMEOUT_CB_ID :
2219 hxspi->TimeOutCallback = pCallback;
2220 break;
2221 case HAL_XSPI_MSP_INIT_CB_ID :
2222 hxspi->MspInitCallback = pCallback;
2223 break;
2224 case HAL_XSPI_MSP_DEINIT_CB_ID :
2225 hxspi->MspDeInitCallback = pCallback;
2226 break;
2227 default :
2228 /* Update the error code */
2229 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2230 /* update return status */
2231 status = HAL_ERROR;
2232 break;
2233 }
2234 }
2235 else if (hxspi->State == HAL_XSPI_STATE_RESET)
2236 {
2237 switch (CallbackID)
2238 {
2239 case HAL_XSPI_MSP_INIT_CB_ID :
2240 hxspi->MspInitCallback = pCallback;
2241 break;
2242 case HAL_XSPI_MSP_DEINIT_CB_ID :
2243 hxspi->MspDeInitCallback = pCallback;
2244 break;
2245 default :
2246 /* Update the error code */
2247 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2248 /* update return status */
2249 status = HAL_ERROR;
2250 break;
2251 }
2252 }
2253 else
2254 {
2255 /* Update the error code */
2256 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2257 /* update return status */
2258 status = HAL_ERROR;
2259 }
2260
2261 return status;
2262 }
2263
2264 /**
2265 * @brief Unregister a User XSPI Callback
2266 * XSPI Callback is redirected to the weak (surcharged) predefined callback
2267 * @param hxspi : XSPI handle
2268 * @param CallbackID : ID of the callback to be unregistered
2269 * This parameter can be one of the following values:
2270 * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID
2271 * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID
2272 * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID
2273 * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID
2274 * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID
2275 * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID
2276 * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID
2277 * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID
2278 * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID
2279 * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID
2280 * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID
2281 * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID
2282 * @retval status
2283 */
HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef * hxspi,HAL_XSPI_CallbackIDTypeDef CallbackID)2284 HAL_StatusTypeDef HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID)
2285 {
2286 HAL_StatusTypeDef status = HAL_OK;
2287
2288 if (hxspi->State == HAL_XSPI_STATE_READY)
2289 {
2290 switch (CallbackID)
2291 {
2292 case HAL_XSPI_ERROR_CB_ID :
2293 hxspi->ErrorCallback = HAL_XSPI_ErrorCallback;
2294 break;
2295 case HAL_XSPI_ABORT_CB_ID :
2296 hxspi->AbortCpltCallback = HAL_XSPI_AbortCpltCallback;
2297 break;
2298 case HAL_XSPI_FIFO_THRESHOLD_CB_ID :
2299 hxspi->FifoThresholdCallback = HAL_XSPI_FifoThresholdCallback;
2300 break;
2301 case HAL_XSPI_CMD_CPLT_CB_ID :
2302 hxspi->CmdCpltCallback = HAL_XSPI_CmdCpltCallback;
2303 break;
2304 case HAL_XSPI_RX_CPLT_CB_ID :
2305 hxspi->RxCpltCallback = HAL_XSPI_RxCpltCallback;
2306 break;
2307 case HAL_XSPI_TX_CPLT_CB_ID :
2308 hxspi->TxCpltCallback = HAL_XSPI_TxCpltCallback;
2309 break;
2310 case HAL_XSPI_RX_HALF_CPLT_CB_ID :
2311 hxspi->RxHalfCpltCallback = HAL_XSPI_RxHalfCpltCallback;
2312 break;
2313 case HAL_XSPI_TX_HALF_CPLT_CB_ID :
2314 hxspi->TxHalfCpltCallback = HAL_XSPI_TxHalfCpltCallback;
2315 break;
2316 case HAL_XSPI_STATUS_MATCH_CB_ID :
2317 hxspi->StatusMatchCallback = HAL_XSPI_StatusMatchCallback;
2318 break;
2319 case HAL_XSPI_TIMEOUT_CB_ID :
2320 hxspi->TimeOutCallback = HAL_XSPI_TimeOutCallback;
2321 break;
2322 case HAL_XSPI_MSP_INIT_CB_ID :
2323 hxspi->MspInitCallback = HAL_XSPI_MspInit;
2324 break;
2325 case HAL_XSPI_MSP_DEINIT_CB_ID :
2326 hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit;
2327 break;
2328 default :
2329 /* Update the error code */
2330 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2331 /* update return status */
2332 status = HAL_ERROR;
2333 break;
2334 }
2335 }
2336 else if (hxspi->State == HAL_XSPI_STATE_RESET)
2337 {
2338 switch (CallbackID)
2339 {
2340 case HAL_XSPI_MSP_INIT_CB_ID :
2341 hxspi->MspInitCallback = HAL_XSPI_MspInit;
2342 break;
2343 case HAL_XSPI_MSP_DEINIT_CB_ID :
2344 hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit;
2345 break;
2346 default :
2347 /* Update the error code */
2348 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2349 /* update return status */
2350 status = HAL_ERROR;
2351 break;
2352 }
2353 }
2354 else
2355 {
2356 /* Update the error code */
2357 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2358 /* update return status */
2359 status = HAL_ERROR;
2360 }
2361
2362 return status;
2363 }
2364 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2365
2366 /**
2367 * @}
2368 */
2369
2370 /** @defgroup XSPI_Exported_Functions_Group3 Peripheral Control and State functions
2371 * @brief XSPI control and State functions
2372 *
2373 @verbatim
2374 ===============================================================================
2375 ##### Peripheral Control and State functions #####
2376 ===============================================================================
2377 [..]
2378 This subsection provides a set of functions allowing to :
2379 (+) Check in run-time the state of the driver.
2380 (+) Check the error code set during last operation.
2381 (+) Abort any operation.
2382 (+) Manage the Fifo threshold.
2383 (+) Configure the timeout duration used in the driver.
2384
2385 @endverbatim
2386 * @{
2387 */
2388
2389 /**
2390 * @brief Abort the current transmission.
2391 * @param hxspi : XSPI handle
2392 * @retval HAL status
2393 */
HAL_XSPI_Abort(XSPI_HandleTypeDef * hxspi)2394 HAL_StatusTypeDef HAL_XSPI_Abort(XSPI_HandleTypeDef *hxspi)
2395 {
2396 HAL_StatusTypeDef status = HAL_OK;
2397 uint32_t state;
2398 uint32_t tickstart = HAL_GetTick();
2399
2400 /* Check if the state is in one of the busy or configured states */
2401 state = hxspi->State;
2402 if (((state & XSPI_BUSY_STATE_MASK) != 0U) || ((state & XSPI_CFG_STATE_MASK) != 0U))
2403 {
2404 /* Check if the DMA is enabled */
2405 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2406 {
2407 /* Disable the DMA transfer on the XSPI side */
2408 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2409
2410 /* Disable the DMA transmit on the DMA side */
2411 status = HAL_DMA_Abort(hxspi->hdmatx);
2412 if (status != HAL_OK)
2413 {
2414 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2415 }
2416
2417 /* Disable the DMA receive on the DMA side */
2418 status = HAL_DMA_Abort(hxspi->hdmarx);
2419 if (status != HAL_OK)
2420 {
2421 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2422 }
2423 }
2424
2425 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2426 {
2427 /* Perform an abort of the XSPI */
2428 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2429
2430 /* Wait until the transfer complete flag is set to go back in idle state */
2431 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, hxspi->Timeout);
2432
2433 if (status == HAL_OK)
2434 {
2435 /* Clear transfer complete flag */
2436 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2437
2438 /* Wait until the busy flag is reset to go back in idle state */
2439 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
2440
2441 if (status == HAL_OK)
2442 {
2443 hxspi->State = HAL_XSPI_STATE_READY;
2444 }
2445 }
2446 }
2447 else
2448 {
2449 hxspi->State = HAL_XSPI_STATE_READY;
2450 }
2451 }
2452 else
2453 {
2454 status = HAL_ERROR;
2455 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2456 }
2457
2458 return status;
2459 }
2460
2461 /**
2462 * @brief Abort the current transmission (non-blocking function)
2463 * @param hxspi : XSPI handle
2464 * @retval HAL status
2465 */
HAL_XSPI_Abort_IT(XSPI_HandleTypeDef * hxspi)2466 HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi)
2467 {
2468 HAL_StatusTypeDef status = HAL_OK;
2469 uint32_t state;
2470
2471 /* Check if the state is in one of the busy or configured states */
2472 state = hxspi->State;
2473 if (((state & XSPI_BUSY_STATE_MASK) != 0U) || ((state & XSPI_CFG_STATE_MASK) != 0U))
2474 {
2475 /* Disable all interrupts */
2476 HAL_XSPI_DISABLE_IT(hxspi, (HAL_XSPI_IT_TO | HAL_XSPI_IT_SM | HAL_XSPI_IT_FT | HAL_XSPI_IT_TC | HAL_XSPI_IT_TE));
2477
2478 hxspi->State = HAL_XSPI_STATE_ABORT;
2479
2480 /* Check if the DMA is enabled */
2481 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2482 {
2483 /* Disable the DMA transfer on the XSPI side */
2484 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2485
2486 /* Disable the DMA transmit on the DMA side */
2487 hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt;
2488 if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK)
2489 {
2490 hxspi->State = HAL_XSPI_STATE_READY;
2491
2492 /* Abort callback */
2493 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2494 hxspi->AbortCpltCallback(hxspi);
2495 #else
2496 HAL_XSPI_AbortCpltCallback(hxspi);
2497 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2498 }
2499
2500 /* Disable the DMA receive on the DMA side */
2501 hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt;
2502 if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK)
2503 {
2504 hxspi->State = HAL_XSPI_STATE_READY;
2505
2506 /* Abort callback */
2507 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2508 hxspi->AbortCpltCallback(hxspi);
2509 #else
2510 HAL_XSPI_AbortCpltCallback(hxspi);
2511 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2512 }
2513 }
2514 else
2515 {
2516 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2517 {
2518 /* Clear transfer complete flag */
2519 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2520
2521 /* Enable the transfer complete interrupts */
2522 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2523
2524 /* Perform an abort of the XSPI */
2525 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2526 }
2527 else
2528 {
2529 hxspi->State = HAL_XSPI_STATE_READY;
2530
2531 /* Abort callback */
2532 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2533 hxspi->AbortCpltCallback(hxspi);
2534 #else
2535 HAL_XSPI_AbortCpltCallback(hxspi);
2536 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2537 }
2538 }
2539 }
2540 else
2541 {
2542 status = HAL_ERROR;
2543 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2544 }
2545
2546 return status;
2547 }
2548
2549 /** @brief Set XSPI Fifo threshold.
2550 * @param hxspi : XSPI handle.
2551 * @param Threshold : Threshold of the Fifo.
2552 * @retval HAL status
2553 */
HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef * hxspi,uint32_t Threshold)2554 HAL_StatusTypeDef HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef *hxspi, uint32_t Threshold)
2555 {
2556 HAL_StatusTypeDef status = HAL_OK;
2557
2558 assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(Threshold));
2559
2560 /* Check the state */
2561 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2562 {
2563 /* Synchronize initialization structure with the new fifo threshold value */
2564 hxspi->Init.FifoThresholdByte = Threshold;
2565
2566 /* Configure new fifo threshold */
2567 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos));
2568
2569 }
2570 else
2571 {
2572 status = HAL_ERROR;
2573 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2574 }
2575
2576 return status;
2577 }
2578
2579 /** @brief Get XSPI Fifo threshold.
2580 * @param hxspi : XSPI handle.
2581 * @retval Fifo threshold
2582 */
HAL_XSPI_GetFifoThreshold(XSPI_HandleTypeDef * hxspi)2583 uint32_t HAL_XSPI_GetFifoThreshold(XSPI_HandleTypeDef *hxspi)
2584 {
2585 return ((READ_BIT(hxspi->Instance->CR, XSPI_CR_FTHRES) >> XSPI_CR_FTHRES_Pos) + 1U);
2586 }
2587
2588 /** @brief Set XSPI Memory Type.
2589 * @param hxspi : XSPI handle.
2590 * @param Type : Memory Type.
2591 * @retval HAL status
2592 */
HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef * hxspi,uint32_t Type)2593 HAL_StatusTypeDef HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef *hxspi, uint32_t Type)
2594 {
2595 HAL_StatusTypeDef status = HAL_OK;
2596
2597 assert_param(IS_XSPI_MEMORY_TYPE(Type));
2598
2599 /* Check the state */
2600 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2601 {
2602 /* Synchronize initialization structure with the new memory type value */
2603 hxspi->Init.MemoryType = Type;
2604
2605 /* Configure new memory type */
2606 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP, hxspi->Init.MemoryType);
2607 }
2608 else
2609 {
2610 status = HAL_ERROR;
2611 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2612 }
2613
2614 return status;
2615 }
2616
2617 /** @brief Set XSPI Device Size.
2618 * @param hxspi : XSPI handle.
2619 * @param Size : Device Size.
2620 * @retval HAL status
2621 */
HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef * hxspi,uint32_t Size)2622 HAL_StatusTypeDef HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef *hxspi, uint32_t Size)
2623 {
2624 HAL_StatusTypeDef status = HAL_OK;
2625
2626 assert_param(IS_XSPI_MEMORY_SIZE(Size));
2627
2628 /* Check the state */
2629 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2630 {
2631 /* Synchronize initialization structure with the new device size value */
2632 hxspi->Init.MemorySize = Size;
2633
2634 /* Configure new device size */
2635 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_DEVSIZE,
2636 (hxspi->Init.MemorySize << XSPI_DCR1_DEVSIZE_Pos));
2637 }
2638 else
2639 {
2640 status = HAL_ERROR;
2641 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2642 }
2643
2644 return status;
2645 }
2646
2647 /** @brief Set XSPI Clock prescaler.
2648 * @param hxspi : XSPI handle.
2649 * @param Prescaler : Clock prescaler.
2650 * @retval HAL status
2651 */
HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef * hxspi,uint32_t Prescaler)2652 HAL_StatusTypeDef HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef *hxspi, uint32_t Prescaler)
2653 {
2654 HAL_StatusTypeDef status = HAL_OK;
2655 assert_param(IS_XSPI_CLK_PRESCALER(Prescaler));
2656
2657 /* Check the state */
2658 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2659 {
2660 /* Synchronize initialization structure with the new clock prescaler value */
2661 hxspi->Init.ClockPrescaler = Prescaler;
2662
2663 /* Configure clock prescaler */
2664 MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER,
2665 ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos));
2666 }
2667 else
2668 {
2669 status = HAL_ERROR;
2670 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2671 }
2672
2673 return status;
2674 }
2675
2676 /** @brief Set XSPI timeout.
2677 * @param hxspi : XSPI handle.
2678 * @param Timeout : Timeout for the memory access.
2679 * @retval HAL state
2680 */
HAL_XSPI_SetTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Timeout)2681 HAL_StatusTypeDef HAL_XSPI_SetTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Timeout)
2682 {
2683 hxspi->Timeout = Timeout;
2684 return HAL_OK;
2685 }
2686
2687 /**
2688 * @brief Return the XSPI error code.
2689 * @param hxspi : XSPI handle
2690 * @retval XSPI Error Code
2691 */
HAL_XSPI_GetError(XSPI_HandleTypeDef * hxspi)2692 uint32_t HAL_XSPI_GetError(XSPI_HandleTypeDef *hxspi)
2693 {
2694 return hxspi->ErrorCode;
2695 }
2696
2697 /**
2698 * @brief Return the XSPI handle state.
2699 * @param hxspi : XSPI handle
2700 * @retval HAL state
2701 */
HAL_XSPI_GetState(XSPI_HandleTypeDef * hxspi)2702 uint32_t HAL_XSPI_GetState(XSPI_HandleTypeDef *hxspi)
2703 {
2704 /* Return XSPI handle state */
2705 return hxspi->State;
2706 }
2707
2708 /**
2709 * @}
2710 */
2711
2712 /** @defgroup XSPI_Exported_Functions_Group4 Delay Block function
2713 * @brief Delay block function
2714 *
2715 @verbatim
2716 ===============================================================================
2717 ##### Delay Block function #####
2718 ===============================================================================
2719 [..]
2720 This subsection provides a set of functions allowing to :
2721 (+) Configure the delay block.
2722
2723 @endverbatim
2724 * @{
2725 */
2726
2727 /**
2728 * @brief Set the Delay Block configuration.
2729 * @param hxspi : XSPI handle.
2730 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2731 * @retval HAL status.
2732 */
HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2733 HAL_StatusTypeDef HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2734 {
2735 HAL_StatusTypeDef status = HAL_ERROR;
2736
2737 /* Enable XSPI Free Running Clock (mandatory) */
2738 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2739
2740 /* Update XSPI state */
2741 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
2742
2743 if (hxspi->Instance == OCTOSPI1)
2744 {
2745 /* Enable the DelayBlock */
2746 LL_DLYB_Enable(DLYB_OCTOSPI1);
2747
2748 /* Set the Delay Block configuration */
2749 LL_DLYB_SetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
2750 status = HAL_OK;
2751 }
2752 else
2753 {
2754 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2755 }
2756
2757 /* Abort the current XSPI operation if exist */
2758 (void)HAL_XSPI_Abort(hxspi);
2759
2760 /* Disable Free Running Clock */
2761 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2762
2763 return status;
2764 }
2765
2766 /**
2767 * @brief Get the Delay Block configuration.
2768 * @param hxspi : XSPI handle.
2769 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2770 * @retval HAL status.
2771 */
HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2772 HAL_StatusTypeDef HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2773 {
2774 HAL_StatusTypeDef status = HAL_ERROR;
2775
2776 if (hxspi->Instance == OCTOSPI1)
2777 {
2778 LL_DLYB_GetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
2779 status = HAL_OK;
2780 }
2781 else
2782 {
2783 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2784 }
2785
2786 return status;
2787 }
2788
2789 /**
2790 * @brief Get the Delay line length value.
2791 * @param hxspi : XSPI handle.
2792 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2793 * @retval HAL status.
2794 */
HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2795 HAL_StatusTypeDef HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2796 {
2797 HAL_StatusTypeDef status = HAL_ERROR;
2798
2799 /* Enable XSPI Free Running Clock (mandatory) */
2800 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2801
2802 /* Update XSPI state */
2803 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
2804
2805 if (hxspi->Instance == OCTOSPI1)
2806 {
2807 /* Enable the DelayBlock */
2808 LL_DLYB_Enable(DLYB_OCTOSPI1);
2809
2810 /* try to detect Period */
2811 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI1, pdlyb_cfg) == (uint32_t)SUCCESS)
2812 {
2813 status = HAL_OK;
2814 }
2815
2816 /* Disable the DelayBlock */
2817 LL_DLYB_Disable(DLYB_OCTOSPI1);
2818 }
2819 else
2820 {
2821 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2822 }
2823
2824 /* Abort the current XSPI operation if exist */
2825 (void)HAL_XSPI_Abort(hxspi);
2826
2827 /* Disable Free Running Clock */
2828 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2829
2830 return status;
2831 }
2832
2833 /**
2834 @cond 0
2835 */
2836 /**
2837 * @brief DMA XSPI process complete callback.
2838 * @param hdma : DMA handle
2839 * @retval None
2840 */
XSPI_DMACplt(DMA_HandleTypeDef * hdma)2841 static void XSPI_DMACplt(DMA_HandleTypeDef *hdma)
2842 {
2843 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2844 hxspi->XferCount = 0;
2845
2846 /* Disable the DMA transfer on the XSPI side */
2847 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2848
2849 /* Disable the DMA channel */
2850 __HAL_DMA_DISABLE(hdma);
2851
2852 /* Enable the XSPI transfer complete Interrupt */
2853 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2854 }
2855
2856 /**
2857 * @brief DMA XSPI process half complete callback.
2858 * @param hdma : DMA handle
2859 * @retval None
2860 */
XSPI_DMAHalfCplt(DMA_HandleTypeDef * hdma)2861 static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
2862 {
2863 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2864 hxspi->XferCount = (hxspi->XferCount >> 1);
2865
2866 if (hxspi->State == HAL_XSPI_STATE_BUSY_RX)
2867 {
2868 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2869 hxspi->RxHalfCpltCallback(hxspi);
2870 #else
2871 HAL_XSPI_RxHalfCpltCallback(hxspi);
2872 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2873 }
2874 else
2875 {
2876 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2877 hxspi->TxHalfCpltCallback(hxspi);
2878 #else
2879 HAL_XSPI_TxHalfCpltCallback(hxspi);
2880 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2881 }
2882 }
2883
2884 /**
2885 * @brief DMA XSPI communication error callback.
2886 * @param hdma : DMA handle
2887 * @retval None
2888 */
XSPI_DMAError(DMA_HandleTypeDef * hdma)2889 static void XSPI_DMAError(DMA_HandleTypeDef *hdma)
2890 {
2891 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2892 hxspi->XferCount = 0;
2893 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2894
2895 /* Disable the DMA transfer on the XSPI side */
2896 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2897
2898 /* Abort the XSPI */
2899 if (HAL_XSPI_Abort_IT(hxspi) != HAL_OK)
2900 {
2901 /* Disable the interrupts */
2902 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
2903
2904 hxspi->State = HAL_XSPI_STATE_READY;
2905
2906 /* Error callback */
2907 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2908 hxspi->ErrorCallback(hxspi);
2909 #else
2910 HAL_XSPI_ErrorCallback(hxspi);
2911 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2912 }
2913 }
2914
2915 /**
2916 * @brief DMA XSPI abort complete callback.
2917 * @param hdma : DMA handle
2918 * @retval None
2919 */
XSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)2920 static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2921 {
2922 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2923 hxspi->XferCount = 0;
2924
2925 /* Check the state */
2926 if (hxspi->State == HAL_XSPI_STATE_ABORT)
2927 {
2928 /* DMA abort called by XSPI abort */
2929 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2930 {
2931 /* Clear transfer complete flag */
2932 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2933
2934 /* Enable the transfer complete interrupts */
2935 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2936
2937 /* Perform an abort of the XSPI */
2938 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2939 }
2940 else
2941 {
2942 hxspi->State = HAL_XSPI_STATE_READY;
2943
2944 /* Abort callback */
2945 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2946 hxspi->AbortCpltCallback(hxspi);
2947 #else
2948 HAL_XSPI_AbortCpltCallback(hxspi);
2949 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2950 }
2951 }
2952 else
2953 {
2954 /* DMA abort called due to a transfer error interrupt */
2955 hxspi->State = HAL_XSPI_STATE_READY;
2956
2957 /* Error callback */
2958 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2959 hxspi->ErrorCallback(hxspi);
2960 #else
2961 HAL_XSPI_ErrorCallback(hxspi);
2962 #endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2963 }
2964 }
2965
2966 /**
2967 * @brief Wait for a flag state until timeout.
2968 * @param hxspi : XSPI handle
2969 * @param Flag : Flag checked
2970 * @param State : Value of the flag expected
2971 * @param Timeout : Duration of the timeout
2972 * @param Tickstart : Tick start value
2973 * @retval HAL status
2974 */
XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2975 static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag,
2976 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2977 {
2978 /* Wait until flag is in expected state */
2979 while ((HAL_XSPI_GET_FLAG(hxspi, Flag)) != State)
2980 {
2981 /* Check for the Timeout */
2982 if (Timeout != HAL_MAX_DELAY)
2983 {
2984 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2985 {
2986 hxspi->State = HAL_XSPI_STATE_ERROR;
2987 hxspi->ErrorCode |= HAL_XSPI_ERROR_TIMEOUT;
2988
2989 return HAL_TIMEOUT;
2990 }
2991 }
2992 }
2993 return HAL_OK;
2994 }
2995
2996 /**
2997 * @brief Configure the registers for the regular command mode.
2998 * @param hxspi : XSPI handle
2999 * @param pCmd : structure that contains the command configuration information
3000 * @retval HAL status
3001 */
XSPI_ConfigCmd(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * pCmd)3002 static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *pCmd)
3003 {
3004 HAL_StatusTypeDef status = HAL_OK;
3005 __IO uint32_t *ccr_reg;
3006 __IO uint32_t *tcr_reg;
3007 __IO uint32_t *ir_reg;
3008 __IO uint32_t *abr_reg;
3009
3010 /* Re-initialize the value of the functional mode */
3011 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U);
3012
3013 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
3014 {
3015 assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect));
3016 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_MSEL, pCmd->IOSelect);
3017 }
3018
3019 if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
3020 {
3021 ccr_reg = &(hxspi->Instance->WCCR);
3022 tcr_reg = &(hxspi->Instance->WTCR);
3023 ir_reg = &(hxspi->Instance->WIR);
3024 abr_reg = &(hxspi->Instance->WABR);
3025 }
3026 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG)
3027 {
3028 ccr_reg = &(hxspi->Instance->WPCCR);
3029 tcr_reg = &(hxspi->Instance->WPTCR);
3030 ir_reg = &(hxspi->Instance->WPIR);
3031 abr_reg = &(hxspi->Instance->WPABR);
3032 }
3033 else
3034 {
3035 ccr_reg = &(hxspi->Instance->CCR);
3036 tcr_reg = &(hxspi->Instance->TCR);
3037 ir_reg = &(hxspi->Instance->IR);
3038 abr_reg = &(hxspi->Instance->ABR);
3039 }
3040
3041 /* Configure the CCR register with DQS and SIOO modes */
3042 *ccr_reg = (pCmd->DQSMode | pCmd->SIOOMode);
3043
3044 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
3045 {
3046 /* Configure the ABR register with alternate bytes value */
3047 *abr_reg = pCmd->AlternateBytes;
3048
3049 /* Configure the CCR register with alternate bytes communication parameters */
3050 MODIFY_REG((*ccr_reg), (XSPI_CCR_ABMODE | XSPI_CCR_ABDTR | XSPI_CCR_ABSIZE),
3051 (pCmd->AlternateBytesMode | pCmd->AlternateBytesDTRMode | pCmd->AlternateBytesWidth));
3052 }
3053
3054 /* Configure the TCR register with the number of dummy cycles */
3055 MODIFY_REG((*tcr_reg), XSPI_TCR_DCYC, pCmd->DummyCycles);
3056
3057 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3058 {
3059 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
3060 {
3061 /* Configure the DLR register with the number of data */
3062 hxspi->Instance->DLR = (pCmd->DataLength - 1U);
3063 }
3064 }
3065
3066 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
3067 {
3068 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3069 {
3070 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3071 {
3072 /* ---- Command with instruction, address and data ---- */
3073
3074 /* Configure the CCR register with all communication parameters */
3075 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3076 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3077 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3078 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3079 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3080 pCmd->DataMode | pCmd->DataDTRMode));
3081 }
3082 else
3083 {
3084 /* ---- Command with instruction and address ---- */
3085
3086 /* Configure the CCR register with all communication parameters */
3087 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3088 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3089 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3090 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
3091
3092 /* The DHQC bit is linked with DDTR bit which should be activated */
3093 if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) &&
3094 (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE))
3095 {
3096 MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE);
3097 }
3098 }
3099 /* Configure the IR register with the instruction value */
3100 *ir_reg = pCmd->Instruction;
3101
3102 /* Configure the AR register with the address value */
3103 hxspi->Instance->AR = pCmd->Address;
3104 }
3105 else
3106 {
3107 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3108 {
3109 /* ---- Command with instruction and data ---- */
3110
3111 /* Configure the CCR register with all communication parameters */
3112 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3113 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3114 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3115 pCmd->DataMode | pCmd->DataDTRMode));
3116 }
3117 else
3118 {
3119 /* ---- Command with only instruction ---- */
3120
3121 /* Configure the CCR register with all communication parameters */
3122 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE),
3123 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth));
3124
3125 /* The DHQC bit is linked with DDTR bit which should be activated */
3126 if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) &&
3127 (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE))
3128 {
3129 MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE);
3130 }
3131 }
3132
3133 /* Configure the IR register with the instruction value */
3134 *ir_reg = pCmd->Instruction;
3135
3136 }
3137 }
3138 else
3139 {
3140 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3141 {
3142 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3143 {
3144 /* ---- Command with address and data ---- */
3145
3146 /* Configure the CCR register with all communication parameters */
3147 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3148 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3149 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3150 pCmd->DataMode | pCmd->DataDTRMode));
3151 }
3152 else
3153 {
3154 /* ---- Command with only address ---- */
3155
3156 /* Configure the CCR register with all communication parameters */
3157 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3158 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
3159 }
3160
3161 /* Configure the AR register with the instruction value */
3162 hxspi->Instance->AR = pCmd->Address;
3163 }
3164 else
3165 {
3166 /* ---- Invalid command configuration (no instruction, no address) ---- */
3167 status = HAL_ERROR;
3168 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3169 }
3170 }
3171
3172 return status;
3173 }
3174
3175 /**
3176 @endcond
3177 */
3178
3179 /**
3180 * @}
3181 */
3182
3183 #endif /* HAL_XSPI_MODULE_ENABLED */
3184
3185 /**
3186 * @}
3187 */
3188
3189 /**
3190 * @}
3191 */
3192
3193 #endif /* HSPI || HSPI1 || HSPI2 || OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3194