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) 2023 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 (overridden) 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 (overridden) functions.
221 Exception done for MspInit and MspDeInit callbacks that are respectively
222 reset to the legacy weak (overridden) 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 (overridden) 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 BUSY flag is reset to go back in idle state */
869 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
870
871 /* Clear TC flag */
872 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
873 }
874 else
875 {
876 /* Update the state */
877 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
878 {
879 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
880 }
881 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_READ_CFG)
882 {
883 if (hxspi->State == HAL_XSPI_STATE_WRITE_CMD_CFG)
884 {
885 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
886 }
887 else
888 {
889 hxspi->State = HAL_XSPI_STATE_READ_CMD_CFG;
890 }
891 }
892 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
893 {
894 if (hxspi->State == HAL_XSPI_STATE_READ_CMD_CFG)
895 {
896 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
897 }
898 else
899 {
900 hxspi->State = HAL_XSPI_STATE_WRITE_CMD_CFG;
901 }
902 }
903 else
904 {
905 /* Wrap configuration, no state change */
906 }
907 }
908 }
909 }
910 else
911 {
912 status = HAL_BUSY;
913 }
914 }
915 else
916 {
917 status = HAL_ERROR;
918 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
919 }
920
921 return status;
922 }
923
924 /**
925 * @brief Set the command configuration in interrupt mode.
926 * @param hxspi : XSPI handle
927 * @param pCmd : structure that contains the command configuration information
928 * @note This function is used only in Indirect Read or Write Modes
929 * @retval HAL status
930 */
HAL_XSPI_Command_IT(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * const pCmd)931 HAL_StatusTypeDef HAL_XSPI_Command_IT(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd)
932 {
933 HAL_StatusTypeDef status;
934 uint32_t tickstart = HAL_GetTick();
935
936 /* Check the parameters of the command structure */
937 assert_param(IS_XSPI_OPERATION_TYPE(pCmd->OperationType));
938
939 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
940 {
941 assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect));
942 }
943
944 assert_param(IS_XSPI_INSTRUCTION_MODE(pCmd->InstructionMode));
945 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
946 {
947 assert_param(IS_XSPI_INSTRUCTION_WIDTH(pCmd->InstructionWidth));
948 assert_param(IS_XSPI_INSTRUCTION_DTR_MODE(pCmd->InstructionDTRMode));
949 }
950
951 assert_param(IS_XSPI_ADDRESS_MODE(pCmd->AddressMode));
952 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
953 {
954 assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth));
955 assert_param(IS_XSPI_ADDRESS_DTR_MODE(pCmd->AddressDTRMode));
956 }
957
958 assert_param(IS_XSPI_ALT_BYTES_MODE(pCmd->AlternateBytesMode));
959 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
960 {
961 assert_param(IS_XSPI_ALT_BYTES_WIDTH(pCmd->AlternateBytesWidth));
962 assert_param(IS_XSPI_ALT_BYTES_DTR_MODE(pCmd->AlternateBytesDTRMode));
963 }
964
965 assert_param(IS_XSPI_DATA_MODE(pCmd->DataMode));
966
967 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
968 {
969 assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength));
970 assert_param(IS_XSPI_DATA_DTR_MODE(pCmd->DataDTRMode));
971 assert_param(IS_XSPI_DUMMY_CYCLES(pCmd->DummyCycles));
972 }
973
974 assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode));
975 assert_param(IS_XSPI_SIOO_MODE(pCmd->SIOOMode));
976
977 /* Check the state of the driver */
978 if ((hxspi->State == HAL_XSPI_STATE_READY) && (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) &&
979 (pCmd->DataMode == HAL_XSPI_DATA_NONE) && (hxspi->Init.MemoryType != HAL_XSPI_MEMTYPE_HYPERBUS))
980 {
981 /* Wait till busy flag is reset */
982 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
983
984 if (status == HAL_OK)
985 {
986 /* Initialize error code */
987 hxspi->ErrorCode = HAL_XSPI_ERROR_NONE;
988
989 /* Clear flags related to interrupt */
990 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
991
992 /* Configure the registers */
993 status = XSPI_ConfigCmd(hxspi, pCmd);
994
995 if (status == HAL_OK)
996 {
997 /* Update the state */
998 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
999
1000 /* Enable the transfer complete and transfer error interrupts */
1001 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_TE);
1002 }
1003 }
1004 }
1005 else
1006 {
1007 status = HAL_ERROR;
1008 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1009 }
1010
1011 return status;
1012 }
1013
1014 /**
1015 * @brief Configure the Hyperbus parameters.
1016 * @param hxspi : XSPI handle
1017 * @param pCfg : Pointer to Structure containing the Hyperbus configuration
1018 * @param Timeout : Timeout duration
1019 * @retval HAL status
1020 */
HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef * hxspi,XSPI_HyperbusCfgTypeDef * const pCfg,uint32_t Timeout)1021 HAL_StatusTypeDef HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCfgTypeDef *const pCfg,
1022 uint32_t Timeout)
1023 {
1024 HAL_StatusTypeDef status;
1025 uint32_t state;
1026 uint32_t tickstart = HAL_GetTick();
1027
1028 /* Check the parameters of the hyperbus configuration structure */
1029 assert_param(IS_XSPI_RW_RECOVERY_TIME_CYCLE(pCfg->RWRecoveryTimeCycle));
1030 assert_param(IS_XSPI_ACCESS_TIME_CYCLE(pCfg->AccessTimeCycle));
1031 assert_param(IS_XSPI_WRITE_ZERO_LATENCY(pCfg->WriteZeroLatency));
1032 assert_param(IS_XSPI_LATENCY_MODE(pCfg->LatencyMode));
1033
1034 /* Check the state of the driver */
1035 state = hxspi->State;
1036 if ((state == HAL_XSPI_STATE_HYPERBUS_INIT) || (state == HAL_XSPI_STATE_READY))
1037 {
1038 /* Wait till busy flag is reset */
1039 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1040
1041 if (status == HAL_OK)
1042 {
1043 /* Configure Hyperbus configuration Latency register */
1044 WRITE_REG(hxspi->Instance->HLCR, ((pCfg->RWRecoveryTimeCycle << XSPI_HLCR_TRWR_Pos) |
1045 (pCfg->AccessTimeCycle << XSPI_HLCR_TACC_Pos) |
1046 pCfg->WriteZeroLatency | pCfg->LatencyMode));
1047
1048 /* Update the state */
1049 hxspi->State = HAL_XSPI_STATE_READY;
1050 }
1051 else
1052 {
1053 status = HAL_BUSY;
1054 }
1055 }
1056 else
1057 {
1058 status = HAL_ERROR;
1059 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1060 }
1061
1062 return status;
1063 }
1064
1065 /**
1066 * @brief Set the Hyperbus command configuration.
1067 * @param hxspi : XSPI handle
1068 * @param pCmd : Structure containing the Hyperbus command
1069 * @param Timeout : Timeout duration
1070 * @retval HAL status
1071 */
HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef * hxspi,XSPI_HyperbusCmdTypeDef * const pCmd,uint32_t Timeout)1072 HAL_StatusTypeDef HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCmdTypeDef *const pCmd,
1073 uint32_t Timeout)
1074 {
1075 HAL_StatusTypeDef status;
1076 uint32_t tickstart = HAL_GetTick();
1077
1078 /* Check the parameters of the hyperbus command structure */
1079 assert_param(IS_XSPI_ADDRESS_SPACE(pCmd->AddressSpace));
1080 assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth));
1081 assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength));
1082 assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode));
1083
1084 /* Check the state of the driver */
1085 if ((hxspi->State == HAL_XSPI_STATE_READY) && (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS))
1086 {
1087 /* Wait till busy flag is reset */
1088 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1089
1090 if (status == HAL_OK)
1091 {
1092 /* Re-initialize the value of the functional mode */
1093 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U);
1094
1095 /* Configure the address space in the DCR1 register */
1096 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP_0, pCmd->AddressSpace);
1097
1098 /* Configure the CCR and WCCR registers with the address size and the following configuration :
1099 - DQS signal enabled (used as RWDS)
1100 - DTR mode enabled on address and data */
1101 /* - address and data on 8 lines */
1102 WRITE_REG(hxspi->Instance->CCR, (pCmd->DQSMode | XSPI_CCR_DDTR | XSPI_CCR_DMODE_2 |
1103 pCmd->AddressWidth | XSPI_CCR_ADDTR | XSPI_CCR_ADMODE_2));
1104 WRITE_REG(hxspi->Instance->WCCR, (pCmd->DQSMode | XSPI_WCCR_DDTR | XSPI_WCCR_DMODE_2 |
1105 pCmd->AddressWidth | XSPI_WCCR_ADDTR | XSPI_WCCR_ADMODE_2));
1106
1107 /* Configure the DLR register with the number of data */
1108 WRITE_REG(hxspi->Instance->DLR, (pCmd->DataLength - 1U));
1109
1110 /* Configure the AR register with the address value */
1111 WRITE_REG(hxspi->Instance->AR, pCmd->Address);
1112
1113 /* Update the state */
1114 hxspi->State = HAL_XSPI_STATE_CMD_CFG;
1115 }
1116 else
1117 {
1118 status = HAL_BUSY;
1119 }
1120 }
1121 else
1122 {
1123 status = HAL_ERROR;
1124 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1125 }
1126
1127 return status;
1128 }
1129
1130 /**
1131 * @brief Transmit an amount of data in blocking mode.
1132 * @param hxspi : XSPI handle
1133 * @param pData : pointer to data buffer
1134 * @param Timeout : Timeout duration
1135 * @note This function is used only in Indirect Write Mode
1136 * @retval HAL status
1137 */
HAL_XSPI_Transmit(XSPI_HandleTypeDef * hxspi,const uint8_t * pData,uint32_t Timeout)1138 HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, const uint8_t *pData, uint32_t Timeout)
1139 {
1140 HAL_StatusTypeDef status;
1141 uint32_t tickstart = HAL_GetTick();
1142 __IO uint32_t *data_reg = &hxspi->Instance->DR;
1143
1144 /* Check the data pointer allocation */
1145 if (pData == NULL)
1146 {
1147 status = HAL_ERROR;
1148 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1149 }
1150 else
1151 {
1152 /* Check the state */
1153 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1154 {
1155 /* Configure counters and size */
1156 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1157 hxspi->XferSize = hxspi->XferCount;
1158 hxspi->pBuffPtr = (uint8_t *)pData;
1159
1160 /* Configure CR register with functional mode as indirect write */
1161 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1162
1163 do
1164 {
1165 /* Wait till fifo threshold flag is set to send data */
1166 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_FT, SET, tickstart, Timeout);
1167
1168 if (status != HAL_OK)
1169 {
1170 break;
1171 }
1172
1173 *((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr;
1174 hxspi->pBuffPtr++;
1175 hxspi->XferCount--;
1176 } while (hxspi->XferCount > 0U);
1177
1178 if (status == HAL_OK)
1179 {
1180 /* Wait till transfer complete flag is set to go back in idle state */
1181 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
1182
1183 if (status == HAL_OK)
1184 {
1185 /* Clear transfer complete flag */
1186 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
1187
1188 hxspi->State = HAL_XSPI_STATE_READY;
1189 }
1190 }
1191 }
1192 else
1193 {
1194 status = HAL_ERROR;
1195 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1196 }
1197 }
1198
1199 return status;
1200 }
1201
1202 /**
1203 * @brief Receive an amount of data in blocking mode.
1204 * @param hxspi : XSPI handle
1205 * @param pData : pointer to data buffer
1206 * @param Timeout : Timeout duration
1207 * @note This function is used only in Indirect Read Mode
1208 * @retval HAL status
1209 */
HAL_XSPI_Receive(XSPI_HandleTypeDef * hxspi,uint8_t * const pData,uint32_t Timeout)1210 HAL_StatusTypeDef HAL_XSPI_Receive(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout)
1211 {
1212 HAL_StatusTypeDef status;
1213 uint32_t tickstart = HAL_GetTick();
1214 __IO uint32_t *data_reg = &hxspi->Instance->DR;
1215 uint32_t addr_reg = hxspi->Instance->AR;
1216 uint32_t ir_reg = hxspi->Instance->IR;
1217
1218 /* Check the data pointer allocation */
1219 if (pData == NULL)
1220 {
1221 status = HAL_ERROR;
1222 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1223 }
1224 else
1225 {
1226 /* Check the state */
1227 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1228 {
1229 /* Configure counters and size */
1230 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1231 hxspi->XferSize = hxspi->XferCount;
1232 hxspi->pBuffPtr = pData;
1233
1234 /* Configure CR register with functional mode as indirect read */
1235 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1236
1237 /* Trig the transfer by re-writing address or instruction register */
1238 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1239 {
1240 WRITE_REG(hxspi->Instance->AR, addr_reg);
1241 }
1242 else
1243 {
1244 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1245 {
1246 WRITE_REG(hxspi->Instance->AR, addr_reg);
1247 }
1248 else
1249 {
1250 WRITE_REG(hxspi->Instance->IR, ir_reg);
1251 }
1252 }
1253
1254 do
1255 {
1256 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1257 status = XSPI_WaitFlagStateUntilTimeout(hxspi, (HAL_XSPI_FLAG_FT | HAL_XSPI_FLAG_TC), SET, tickstart, Timeout);
1258
1259 if (status != HAL_OK)
1260 {
1261 break;
1262 }
1263
1264 *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg);
1265 hxspi->pBuffPtr++;
1266 hxspi->XferCount--;
1267 } while (hxspi->XferCount > 0U);
1268
1269 if (status == HAL_OK)
1270 {
1271 /* Wait till transfer complete flag is set to go back in idle state */
1272 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
1273
1274 if (status == HAL_OK)
1275 {
1276 /* Clear transfer complete flag */
1277 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
1278
1279 hxspi->State = HAL_XSPI_STATE_READY;
1280 }
1281 }
1282 }
1283 else
1284 {
1285 status = HAL_ERROR;
1286 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1287 }
1288 }
1289
1290 return status;
1291 }
1292
1293 /**
1294 * @brief Send an amount of data in non-blocking mode with interrupt.
1295 * @param hxspi : XSPI handle
1296 * @param pData : pointer to data buffer
1297 * @note This function is used only in Indirect Write Mode
1298 * @retval HAL status
1299 */
HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef * hxspi,const uint8_t * pData)1300 HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, const uint8_t *pData)
1301 {
1302 HAL_StatusTypeDef status = HAL_OK;
1303
1304 /* Check the data pointer allocation */
1305 if (pData == NULL)
1306 {
1307 status = HAL_ERROR;
1308 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1309 }
1310 else
1311 {
1312 /* Check the state */
1313 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1314 {
1315 /* Configure counters and size */
1316 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1317 hxspi->XferSize = hxspi->XferCount;
1318 hxspi->pBuffPtr = (uint8_t *)pData;
1319
1320 /* Configure CR register with functional mode as indirect write */
1321 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1322
1323 /* Clear flags related to interrupt */
1324 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1325
1326 /* Update the state */
1327 hxspi->State = HAL_XSPI_STATE_BUSY_TX;
1328
1329 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1330 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
1331 }
1332 else
1333 {
1334 status = HAL_ERROR;
1335 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1336 }
1337 }
1338
1339 return status;
1340 }
1341
1342 /**
1343 * @brief Receive an amount of data in non-blocking mode with interrupt.
1344 * @param hxspi : XSPI handle
1345 * @param pData : pointer to data buffer
1346 * @note This function is used only in Indirect Read Mode
1347 * @retval HAL status
1348 */
HAL_XSPI_Receive_IT(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1349 HAL_StatusTypeDef HAL_XSPI_Receive_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1350 {
1351 HAL_StatusTypeDef status = HAL_OK;
1352 uint32_t addr_reg = hxspi->Instance->AR;
1353 uint32_t ir_reg = hxspi->Instance->IR;
1354
1355 /* Check the data pointer allocation */
1356 if (pData == NULL)
1357 {
1358 status = HAL_ERROR;
1359 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1360 }
1361 else
1362 {
1363 /* Check the state */
1364 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1365 {
1366 /* Configure counters and size */
1367 hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U;
1368 hxspi->XferSize = hxspi->XferCount;
1369 hxspi->pBuffPtr = pData;
1370
1371 /* Configure CR register with functional mode as indirect read */
1372 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1373
1374 /* Clear flags related to interrupt */
1375 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1376
1377 /* Update the state */
1378 hxspi->State = HAL_XSPI_STATE_BUSY_RX;
1379
1380 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1381 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
1382
1383 /* Trig the transfer by re-writing address or instruction register */
1384 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1385 {
1386 WRITE_REG(hxspi->Instance->AR, addr_reg);
1387 }
1388 else
1389 {
1390 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1391 {
1392 WRITE_REG(hxspi->Instance->AR, addr_reg);
1393 }
1394 else
1395 {
1396 WRITE_REG(hxspi->Instance->IR, ir_reg);
1397 }
1398 }
1399 }
1400 else
1401 {
1402 status = HAL_ERROR;
1403 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1404 }
1405 }
1406
1407 return status;
1408 }
1409
1410 /**
1411 * @brief Send an amount of data in non-blocking mode with DMA.
1412 * @param hxspi : XSPI handle
1413 * @param pData : pointer to data buffer
1414 * @note This function is used only in Indirect Write Mode
1415 * @note If DMA peripheral access is configured as halfword, the number
1416 * of data and the fifo threshold should be aligned on halfword
1417 * @note If DMA peripheral access is configured as word, the number
1418 * of data and the fifo threshold should be aligned on word
1419 * @retval HAL status
1420 */
HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef * hxspi,const uint8_t * pData)1421 HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, const uint8_t *pData)
1422 {
1423 HAL_StatusTypeDef status = HAL_OK;
1424 uint32_t data_size = hxspi->Instance->DLR + 1U;
1425 DMA_QListTypeDef *p_queue = {NULL};
1426 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1427
1428 /* Check the data pointer allocation */
1429 if (pData == NULL)
1430 {
1431 status = HAL_ERROR;
1432 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1433 }
1434 else
1435 {
1436 /* Check the state */
1437 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1438 {
1439 if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1440 {
1441 p_queue = hxspi->hdmatx->LinkedListQueue;
1442 if ((p_queue != NULL) && (p_queue->Head != NULL))
1443 {
1444 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1445 }
1446 else
1447 {
1448 /* Set Error Code function status */
1449 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1450
1451 /* Return function status */
1452 status = HAL_ERROR;
1453 }
1454 }
1455 else
1456 {
1457 data_width = hxspi->hdmatx->Init.DestDataWidth;
1458 }
1459 /* Configure counters and size */
1460 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1461 {
1462 hxspi->XferCount = data_size;
1463 }
1464 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1465 {
1466 if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U))
1467 {
1468 /* The number of data or the fifo threshold is not aligned on halfword
1469 => no transfer possible with DMA peripheral access configured as halfword */
1470 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1471 status = HAL_ERROR;
1472 }
1473 else
1474 {
1475 hxspi->XferCount = data_size;
1476 }
1477 }
1478 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1479 {
1480 if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U))
1481 {
1482 /* The number of data or the fifo threshold is not aligned on word
1483 => no transfer possible with DMA peripheral access configured as word */
1484 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1485 status = HAL_ERROR;
1486 }
1487 else
1488 {
1489 hxspi->XferCount = data_size;
1490 }
1491 }
1492 else
1493 {
1494 /* Nothing to do */
1495 }
1496
1497 if (status == HAL_OK)
1498 {
1499 hxspi->XferSize = hxspi->XferCount;
1500 hxspi->pBuffPtr = (uint8_t *)pData;
1501
1502 /* Configure CR register with functional mode as indirect write */
1503 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1504
1505 /* Clear flags related to interrupt */
1506 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1507
1508 /* Update the state */
1509 hxspi->State = HAL_XSPI_STATE_BUSY_TX;
1510
1511 /* Set the DMA transfer complete callback */
1512 hxspi->hdmatx->XferCpltCallback = XSPI_DMACplt;
1513
1514 /* Set the DMA Half transfer complete callback */
1515 hxspi->hdmatx->XferHalfCpltCallback = XSPI_DMAHalfCplt;
1516
1517 /* Set the DMA error callback */
1518 hxspi->hdmatx->XferErrorCallback = XSPI_DMAError;
1519
1520 /* Clear the DMA abort callback */
1521 hxspi->hdmatx->XferAbortCallback = NULL;
1522
1523 /* Enable the transmit DMA Channel */
1524 if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1525 {
1526 if (hxspi->hdmatx->LinkedListQueue != NULL)
1527 {
1528 /* Enable the DMA channel */
1529 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1530 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_INCREMENTED | DMA_DINC_FIXED));
1531 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1532 DMA_CTR2_DREQ, DMA_MEMORY_TO_PERIPH);
1533 /* Set DMA data size*/
1534 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize;
1535 /* Set DMA source address */
1536 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
1537 /* Set DMA destination address */
1538 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR;
1539
1540 status = HAL_DMAEx_List_Start_IT(hxspi->hdmatx);
1541 }
1542 else
1543 {
1544 /* Set Error Code */
1545 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1546
1547 hxspi->State = HAL_XSPI_STATE_READY;
1548
1549 /* Return function status */
1550 status = HAL_ERROR;
1551 }
1552 }
1553 else
1554 {
1555 if ((hxspi->hdmatx->Init.Direction == DMA_MEMORY_TO_PERIPH) &&
1556 (hxspi->hdmatx->Init.SrcInc == DMA_SINC_INCREMENTED) && (hxspi->hdmatx->Init.DestInc == DMA_DINC_FIXED))
1557 {
1558 status = HAL_DMA_Start_IT(hxspi->hdmatx, (uint32_t)pData, (uint32_t)&hxspi->Instance->DR, hxspi->XferSize);
1559 }
1560 else
1561 {
1562 /* no transmit possible with DMA peripheral, invalid configuration */
1563 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1564 status = HAL_ERROR;
1565 }
1566 }
1567 if (status == HAL_OK)
1568 {
1569 /* Enable the transfer error interrupt */
1570 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE);
1571
1572 /* Enable the DMA transfer by setting the DMAEN bit */
1573 SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
1574 }
1575 else
1576 {
1577 status = HAL_ERROR;
1578 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1579 hxspi->State = HAL_XSPI_STATE_READY;
1580 }
1581 }
1582 }
1583 else
1584 {
1585 status = HAL_ERROR;
1586 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1587 }
1588 }
1589
1590 return status;
1591 }
1592
1593 /**
1594 * @brief Receive an amount of data in non-blocking mode with DMA.
1595 * @param hxspi : XSPI handle
1596 * @param pData : pointer to data buffer.
1597 * @note This function is used only in Indirect Read Mode
1598 * @note If DMA peripheral access is configured as halfword, the number
1599 * of data and the fifo threshold should be aligned on halfword
1600 * @note If DMA peripheral access is configured as word, the number
1601 * of data and the fifo threshold should be aligned on word
1602 * @retval HAL status
1603 */
HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef * hxspi,uint8_t * const pData)1604 HAL_StatusTypeDef HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData)
1605 {
1606 HAL_StatusTypeDef status = HAL_OK;
1607 uint32_t data_size = hxspi->Instance->DLR + 1U;
1608 uint32_t addr_reg = hxspi->Instance->AR;
1609 uint32_t ir_reg = hxspi->Instance->IR;
1610 DMA_QListTypeDef *p_queue = {NULL};
1611 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1612
1613 /* Check the data pointer allocation */
1614 if (pData == NULL)
1615 {
1616 status = HAL_ERROR;
1617 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1618 }
1619 else
1620 {
1621 /* Check the state */
1622 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1623 {
1624 if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1625 {
1626 p_queue = hxspi->hdmarx->LinkedListQueue;
1627 if ((p_queue != NULL) && (p_queue->Head != NULL))
1628 {
1629 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1630 }
1631 else
1632 {
1633 /* Set Error Code */
1634 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1635
1636 /* Return function status */
1637 status = HAL_ERROR;
1638 }
1639 }
1640 else
1641 {
1642 data_width = hxspi->hdmarx->Init.DestDataWidth;
1643 }
1644
1645 /* Configure counters and size */
1646 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1647 {
1648 hxspi->XferCount = data_size;
1649 }
1650 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1651 {
1652 if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U))
1653 {
1654 /* The number of data or the fifo threshold is not aligned on halfword
1655 => no transfer possible with DMA peripheral access configured as halfword */
1656 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1657 status = HAL_ERROR;
1658 }
1659 else
1660 {
1661 hxspi->XferCount = data_size;
1662 }
1663 }
1664 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1665 {
1666 if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U))
1667 {
1668 /* The number of data or the fifo threshold is not aligned on word
1669 => no transfer possible with DMA peripheral access configured as word */
1670 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1671 status = HAL_ERROR;
1672 }
1673 else
1674 {
1675 hxspi->XferCount = data_size;
1676 }
1677 }
1678 else
1679 {
1680 /* Nothing to do */
1681 }
1682
1683 if (status == HAL_OK)
1684 {
1685 hxspi->XferSize = hxspi->XferCount;
1686 hxspi->pBuffPtr = pData;
1687
1688 /* Configure CR register with functional mode as indirect read */
1689 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1690
1691 /* Clear flags related to interrupt */
1692 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC);
1693
1694 /* Update the state */
1695 hxspi->State = HAL_XSPI_STATE_BUSY_RX;
1696
1697 /* Set the DMA transfer complete callback */
1698 hxspi->hdmarx->XferCpltCallback = XSPI_DMACplt;
1699
1700 /* Set the DMA Half transfer complete callback */
1701 hxspi->hdmarx->XferHalfCpltCallback = XSPI_DMAHalfCplt;
1702
1703 /* Set the DMA error callback */
1704 hxspi->hdmarx->XferErrorCallback = XSPI_DMAError;
1705
1706 /* Clear the DMA abort callback */
1707 hxspi->hdmarx->XferAbortCallback = NULL;
1708
1709 /* Enable the receive DMA Channel */
1710 if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1711 {
1712 if (hxspi->hdmarx->LinkedListQueue != NULL)
1713 {
1714 /* Enable the DMA channel */
1715 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1716 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_FIXED | DMA_DINC_INCREMENTED));
1717 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1718 DMA_CTR2_DREQ, DMA_PERIPH_TO_MEMORY);
1719 /* Set DMA data size */
1720 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize;
1721 /* Set DMA source address */
1722 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR;
1723 /* Set DMA destination address */
1724 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
1725
1726 status = HAL_DMAEx_List_Start_IT(hxspi->hdmarx);
1727 }
1728 else
1729 {
1730 /* Set Error Code */
1731 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1732
1733 hxspi->State = HAL_XSPI_STATE_READY;
1734
1735 /* Return function status */
1736 status = HAL_ERROR;
1737 }
1738 }
1739 else
1740 {
1741 if ((hxspi->hdmarx->Init.Direction == DMA_PERIPH_TO_MEMORY) && (hxspi->hdmarx->Init.SrcInc == DMA_SINC_FIXED)
1742 && (hxspi->hdmarx->Init.DestInc == DMA_DINC_INCREMENTED))
1743 {
1744 status = HAL_DMA_Start_IT(hxspi->hdmarx, (uint32_t)&hxspi->Instance->DR, (uint32_t)pData, hxspi->XferSize);
1745 }
1746 else
1747 {
1748 /* no receive possible with DMA peripheral, invalid configuration */
1749 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
1750 status = HAL_ERROR;
1751 }
1752 }
1753 if (status == HAL_OK)
1754 {
1755 /* Enable the transfer error interrupt */
1756 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE);
1757
1758 /* Trig the transfer by re-writing address or instruction register */
1759 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1760 {
1761 WRITE_REG(hxspi->Instance->AR, addr_reg);
1762 }
1763 else
1764 {
1765 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1766 {
1767 WRITE_REG(hxspi->Instance->AR, addr_reg);
1768 }
1769 else
1770 {
1771 WRITE_REG(hxspi->Instance->IR, ir_reg);
1772 }
1773 }
1774
1775 /* Enable the DMA transfer by setting the DMAEN bit */
1776 SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
1777 }
1778 else
1779 {
1780 status = HAL_ERROR;
1781 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
1782 hxspi->State = HAL_XSPI_STATE_READY;
1783 }
1784 }
1785 }
1786 else
1787 {
1788 status = HAL_ERROR;
1789 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1790 }
1791 }
1792
1793 return status;
1794 }
1795
1796 /**
1797 * @brief Configure the XSPI Automatic Polling Mode in blocking mode.
1798 * @param hxspi : XSPI handle
1799 * @param pCfg : Pointer to structure that contains the polling configuration information.
1800 * @param Timeout : Timeout duration
1801 * @note This function is used only in Automatic Polling Mode
1802 * @retval HAL status
1803 */
HAL_XSPI_AutoPolling(XSPI_HandleTypeDef * hxspi,XSPI_AutoPollingTypeDef * const pCfg,uint32_t Timeout)1804 HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg,
1805 uint32_t Timeout)
1806 {
1807 HAL_StatusTypeDef status;
1808 uint32_t tickstart = HAL_GetTick();
1809 uint32_t addr_reg = hxspi->Instance->AR;
1810 uint32_t ir_reg = hxspi->Instance->IR;
1811 #ifdef USE_FULL_ASSERT
1812 uint32_t dlr_reg = hxspi->Instance->DLR;
1813 #endif /* USE_FULL_ASSERT */
1814
1815 /* Check the parameters of the autopolling configuration structure */
1816 assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode));
1817 assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop));
1818 assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime));
1819 assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1820
1821 /* Check the state */
1822 if ((hxspi->State == HAL_XSPI_STATE_CMD_CFG) && (pCfg->AutomaticStop == HAL_XSPI_AUTOMATIC_STOP_ENABLE))
1823 {
1824 /* Wait till busy flag is reset */
1825 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1826
1827 if (status == HAL_OK)
1828 {
1829 /* Configure registers */
1830 WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue);
1831 WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask);
1832 WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime);
1833 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE),
1834 (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1835
1836 /* Trig the transfer by re-writing address or instruction register */
1837 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1838 {
1839 WRITE_REG(hxspi->Instance->AR, addr_reg);
1840 }
1841 else
1842 {
1843 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1844 {
1845 WRITE_REG(hxspi->Instance->AR, addr_reg);
1846 }
1847 else
1848 {
1849 WRITE_REG(hxspi->Instance->IR, ir_reg);
1850 }
1851 }
1852
1853 /* Wait till status match flag is set to go back in idle state */
1854 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_SM, SET, tickstart, Timeout);
1855
1856 if (status == HAL_OK)
1857 {
1858 /* Clear status match flag */
1859 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_SM);
1860
1861 hxspi->State = HAL_XSPI_STATE_READY;
1862 }
1863 }
1864 else
1865 {
1866 status = HAL_BUSY;
1867 }
1868 }
1869 else
1870 {
1871 status = HAL_ERROR;
1872 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1873 }
1874
1875 return status;
1876 }
1877
1878 /**
1879 * @brief Configure the XSPI Automatic Polling Mode in non-blocking mode.
1880 * @param hxspi : XSPI handle
1881 * @param pCfg : Pointer to structure that contains the polling configuration information.
1882 * @note This function is used only in Automatic Polling Mode
1883 * @retval HAL status
1884 */
HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef * hxspi,XSPI_AutoPollingTypeDef * const pCfg)1885 HAL_StatusTypeDef HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg)
1886 {
1887 HAL_StatusTypeDef status;
1888 uint32_t tickstart = HAL_GetTick();
1889 uint32_t addr_reg = hxspi->Instance->AR;
1890 uint32_t ir_reg = hxspi->Instance->IR;
1891 #ifdef USE_FULL_ASSERT
1892 uint32_t dlr_reg = hxspi->Instance->DLR;
1893 #endif /* USE_FULL_ASSERT */
1894
1895 /* Check the parameters of the autopolling configuration structure */
1896 assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode));
1897 assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop));
1898 assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime));
1899 assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1900
1901 /* Check the state */
1902 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1903 {
1904 /* Wait till busy flag is reset */
1905 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
1906
1907 if (status == HAL_OK)
1908 {
1909 /* Configure registers */
1910 WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue);
1911 WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask);
1912 WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime);
1913 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE),
1914 (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1915
1916 /* Clear flags related to interrupt */
1917 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_SM);
1918
1919 hxspi->State = HAL_XSPI_STATE_BUSY_AUTO_POLLING;
1920
1921 /* Enable the status match and transfer error interrupts */
1922 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_SM | HAL_XSPI_IT_TE);
1923
1924 /* Trig the transfer by re-writing address or instruction register */
1925 if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)
1926 {
1927 WRITE_REG(hxspi->Instance->AR, addr_reg);
1928 }
1929 else
1930 {
1931 if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE)
1932 {
1933 WRITE_REG(hxspi->Instance->AR, addr_reg);
1934 }
1935 else
1936 {
1937 WRITE_REG(hxspi->Instance->IR, ir_reg);
1938 }
1939 }
1940 }
1941 }
1942 else
1943 {
1944 status = HAL_ERROR;
1945 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1946 }
1947
1948 return status;
1949 }
1950
1951 /**
1952 * @brief Configure the Memory Mapped mode.
1953 * @param hxspi : XSPI handle
1954 * @param pCfg : Pointer to structure that contains the memory mapped configuration information.
1955 * @note This function is used only in Memory mapped Mode
1956 * @retval HAL status
1957 */
HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef * hxspi,XSPI_MemoryMappedTypeDef * const pCfg)1958 HAL_StatusTypeDef HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef *hxspi, XSPI_MemoryMappedTypeDef *const pCfg)
1959 {
1960 HAL_StatusTypeDef status;
1961 uint32_t tickstart = HAL_GetTick();
1962
1963 /* Check the parameters of the memory-mapped configuration structure */
1964 assert_param(IS_XSPI_TIMEOUT_ACTIVATION(pCfg->TimeOutActivation));
1965
1966 /* Check the state */
1967 if (hxspi->State == HAL_XSPI_STATE_CMD_CFG)
1968 {
1969 /* Wait till busy flag is reset */
1970 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
1971
1972 if (status == HAL_OK)
1973 {
1974 hxspi->State = HAL_XSPI_STATE_BUSY_MEM_MAPPED;
1975
1976 if (pCfg->TimeOutActivation == HAL_XSPI_TIMEOUT_COUNTER_ENABLE)
1977 {
1978 assert_param(IS_XSPI_TIMEOUT_PERIOD(pCfg->TimeoutPeriodClock));
1979
1980 /* Configure register */
1981 WRITE_REG(hxspi->Instance->LPTR, pCfg->TimeoutPeriodClock);
1982
1983 /* Clear flags related to interrupt */
1984 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TO);
1985
1986 /* Enable the timeout interrupt */
1987 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TO);
1988 }
1989
1990 /* Configure CR register with functional mode as memory-mapped */
1991 MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_TCEN | XSPI_CR_FMODE),
1992 (pCfg->TimeOutActivation | XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1993 }
1994 }
1995 else
1996 {
1997 status = HAL_ERROR;
1998 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
1999 }
2000
2001 return status;
2002 }
2003
2004 /**
2005 * @brief Transfer Error callback.
2006 * @param hxspi : XSPI handle
2007 * @retval None
2008 */
HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef * hxspi)2009 __weak void HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef *hxspi)
2010 {
2011 /* Prevent unused argument(s) compilation warning */
2012 UNUSED(hxspi);
2013
2014 /* NOTE : This function should not be modified, when the callback is needed,
2015 the HAL_XSPI_ErrorCallback could be implemented in the user file
2016 */
2017 }
2018
2019 /**
2020 * @brief Abort completed callback.
2021 * @param hxspi : XSPI handle
2022 * @retval None
2023 */
HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef * hxspi)2024 __weak void HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef *hxspi)
2025 {
2026 /* Prevent unused argument(s) compilation warning */
2027 UNUSED(hxspi);
2028
2029 /* NOTE: This function should not be modified, when the callback is needed,
2030 the HAL_XSPI_AbortCpltCallback could be implemented in the user file
2031 */
2032 }
2033
2034 /**
2035 * @brief FIFO Threshold callback.
2036 * @param hxspi : XSPI handle
2037 * @retval None
2038 */
HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef * hxspi)2039 __weak void HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef *hxspi)
2040 {
2041 /* Prevent unused argument(s) compilation warning */
2042 UNUSED(hxspi);
2043
2044 /* NOTE : This function should not be modified, when the callback is needed,
2045 the HAL_XSPI_FIFOThresholdCallback could be implemented in the user file
2046 */
2047 }
2048
2049 /**
2050 * @brief Command completed callback.
2051 * @param hxspi : XSPI handle
2052 * @retval None
2053 */
HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef * hxspi)2054 __weak void HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef *hxspi)
2055 {
2056 /* Prevent unused argument(s) compilation warning */
2057 UNUSED(hxspi);
2058
2059 /* NOTE: This function should not be modified, when the callback is needed,
2060 the HAL_XSPI_CmdCpltCallback could be implemented in the user file
2061 */
2062 }
2063
2064 /**
2065 * @brief Rx Transfer completed callback.
2066 * @param hxspi : XSPI handle
2067 * @retval None
2068 */
HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef * hxspi)2069 __weak void HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef *hxspi)
2070 {
2071 /* Prevent unused argument(s) compilation warning */
2072 UNUSED(hxspi);
2073
2074 /* NOTE: This function should not be modified, when the callback is needed,
2075 the HAL_XSPI_RxCpltCallback could be implemented in the user file
2076 */
2077 }
2078
2079 /**
2080 * @brief Tx Transfer completed callback.
2081 * @param hxspi : XSPI handle
2082 * @retval None
2083 */
HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef * hxspi)2084 __weak void HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef *hxspi)
2085 {
2086 /* Prevent unused argument(s) compilation warning */
2087 UNUSED(hxspi);
2088
2089 /* NOTE: This function should not be modified, when the callback is needed,
2090 the HAL_XSPI_TxCpltCallback could be implemented in the user file
2091 */
2092 }
2093
2094 /**
2095 * @brief Rx Half Transfer completed callback.
2096 * @param hxspi : XSPI handle
2097 * @retval None
2098 */
HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef * hxspi)2099 __weak void HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef *hxspi)
2100 {
2101 /* Prevent unused argument(s) compilation warning */
2102 UNUSED(hxspi);
2103
2104 /* NOTE: This function should not be modified, when the callback is needed,
2105 the HAL_XSPI_RxHalfCpltCallback could be implemented in the user file
2106 */
2107 }
2108
2109 /**
2110 * @brief Tx Half Transfer completed callback.
2111 * @param hxspi : XSPI handle
2112 * @retval None
2113 */
HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef * hxspi)2114 __weak void HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef *hxspi)
2115 {
2116 /* Prevent unused argument(s) compilation warning */
2117 UNUSED(hxspi);
2118
2119 /* NOTE: This function should not be modified, when the callback is needed,
2120 the HAL_XSPI_TxHalfCpltCallback could be implemented in the user file
2121 */
2122 }
2123
2124 /**
2125 * @brief Status Match callback.
2126 * @param hxspi : XSPI handle
2127 * @retval None
2128 */
HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef * hxspi)2129 __weak void HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef *hxspi)
2130 {
2131 /* Prevent unused argument(s) compilation warning */
2132 UNUSED(hxspi);
2133
2134 /* NOTE : This function should not be modified, when the callback is needed,
2135 the HAL_XSPI_StatusMatchCallback could be implemented in the user file
2136 */
2137 }
2138
2139 /**
2140 * @brief Timeout callback.
2141 * @param hxspi : XSPI handle
2142 * @retval None
2143 */
HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef * hxspi)2144 __weak void HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef *hxspi)
2145 {
2146 /* Prevent unused argument(s) compilation warning */
2147 UNUSED(hxspi);
2148
2149 /* NOTE : This function should not be modified, when the callback is needed,
2150 the HAL_XSPI_TimeOutCallback could be implemented in the user file
2151 */
2152 }
2153
2154 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2155 /**
2156 * @brief Register a User XSPI Callback
2157 * To be used to override the weak predefined callback
2158 * @param hxspi : XSPI handle
2159 * @param CallbackID : ID of the callback to be registered
2160 * This parameter can be one of the following values:
2161 * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID
2162 * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID
2163 * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID
2164 * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID
2165 * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID
2166 * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID
2167 * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID
2168 * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID
2169 * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID
2170 * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID
2171 * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID
2172 * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID
2173 * @param pCallback : pointer to the Callback function
2174 * @retval status
2175 */
HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef * hxspi,HAL_XSPI_CallbackIDTypeDef CallbackID,pXSPI_CallbackTypeDef pCallback)2176 HAL_StatusTypeDef HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID,
2177 pXSPI_CallbackTypeDef pCallback)
2178 {
2179 HAL_StatusTypeDef status = HAL_OK;
2180
2181 if (pCallback == NULL)
2182 {
2183 /* Update the error code */
2184 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2185 return HAL_ERROR;
2186 }
2187
2188 if (hxspi->State == HAL_XSPI_STATE_READY)
2189 {
2190 switch (CallbackID)
2191 {
2192 case HAL_XSPI_ERROR_CB_ID :
2193 hxspi->ErrorCallback = pCallback;
2194 break;
2195 case HAL_XSPI_ABORT_CB_ID :
2196 hxspi->AbortCpltCallback = pCallback;
2197 break;
2198 case HAL_XSPI_FIFO_THRESHOLD_CB_ID :
2199 hxspi->FifoThresholdCallback = pCallback;
2200 break;
2201 case HAL_XSPI_CMD_CPLT_CB_ID :
2202 hxspi->CmdCpltCallback = pCallback;
2203 break;
2204 case HAL_XSPI_RX_CPLT_CB_ID :
2205 hxspi->RxCpltCallback = pCallback;
2206 break;
2207 case HAL_XSPI_TX_CPLT_CB_ID :
2208 hxspi->TxCpltCallback = pCallback;
2209 break;
2210 case HAL_XSPI_RX_HALF_CPLT_CB_ID :
2211 hxspi->RxHalfCpltCallback = pCallback;
2212 break;
2213 case HAL_XSPI_TX_HALF_CPLT_CB_ID :
2214 hxspi->TxHalfCpltCallback = pCallback;
2215 break;
2216 case HAL_XSPI_STATUS_MATCH_CB_ID :
2217 hxspi->StatusMatchCallback = pCallback;
2218 break;
2219 case HAL_XSPI_TIMEOUT_CB_ID :
2220 hxspi->TimeOutCallback = pCallback;
2221 break;
2222 case HAL_XSPI_MSP_INIT_CB_ID :
2223 hxspi->MspInitCallback = pCallback;
2224 break;
2225 case HAL_XSPI_MSP_DEINIT_CB_ID :
2226 hxspi->MspDeInitCallback = pCallback;
2227 break;
2228 default :
2229 /* Update the error code */
2230 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2231 /* update return status */
2232 status = HAL_ERROR;
2233 break;
2234 }
2235 }
2236 else if (hxspi->State == HAL_XSPI_STATE_RESET)
2237 {
2238 switch (CallbackID)
2239 {
2240 case HAL_XSPI_MSP_INIT_CB_ID :
2241 hxspi->MspInitCallback = pCallback;
2242 break;
2243 case HAL_XSPI_MSP_DEINIT_CB_ID :
2244 hxspi->MspDeInitCallback = pCallback;
2245 break;
2246 default :
2247 /* Update the error code */
2248 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2249 /* update return status */
2250 status = HAL_ERROR;
2251 break;
2252 }
2253 }
2254 else
2255 {
2256 /* Update the error code */
2257 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2258 /* update return status */
2259 status = HAL_ERROR;
2260 }
2261
2262 return status;
2263 }
2264
2265 /**
2266 * @brief Unregister a User XSPI Callback
2267 * XSPI Callback is redirected to the weak predefined callback
2268 * @param hxspi : XSPI handle
2269 * @param CallbackID : ID of the callback to be unregistered
2270 * This parameter can be one of the following values:
2271 * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID
2272 * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID
2273 * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID
2274 * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID
2275 * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID
2276 * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID
2277 * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID
2278 * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID
2279 * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID
2280 * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID
2281 * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID
2282 * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID
2283 * @retval status
2284 */
HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef * hxspi,HAL_XSPI_CallbackIDTypeDef CallbackID)2285 HAL_StatusTypeDef HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID)
2286 {
2287 HAL_StatusTypeDef status = HAL_OK;
2288
2289 if (hxspi->State == HAL_XSPI_STATE_READY)
2290 {
2291 switch (CallbackID)
2292 {
2293 case HAL_XSPI_ERROR_CB_ID :
2294 hxspi->ErrorCallback = HAL_XSPI_ErrorCallback;
2295 break;
2296 case HAL_XSPI_ABORT_CB_ID :
2297 hxspi->AbortCpltCallback = HAL_XSPI_AbortCpltCallback;
2298 break;
2299 case HAL_XSPI_FIFO_THRESHOLD_CB_ID :
2300 hxspi->FifoThresholdCallback = HAL_XSPI_FifoThresholdCallback;
2301 break;
2302 case HAL_XSPI_CMD_CPLT_CB_ID :
2303 hxspi->CmdCpltCallback = HAL_XSPI_CmdCpltCallback;
2304 break;
2305 case HAL_XSPI_RX_CPLT_CB_ID :
2306 hxspi->RxCpltCallback = HAL_XSPI_RxCpltCallback;
2307 break;
2308 case HAL_XSPI_TX_CPLT_CB_ID :
2309 hxspi->TxCpltCallback = HAL_XSPI_TxCpltCallback;
2310 break;
2311 case HAL_XSPI_RX_HALF_CPLT_CB_ID :
2312 hxspi->RxHalfCpltCallback = HAL_XSPI_RxHalfCpltCallback;
2313 break;
2314 case HAL_XSPI_TX_HALF_CPLT_CB_ID :
2315 hxspi->TxHalfCpltCallback = HAL_XSPI_TxHalfCpltCallback;
2316 break;
2317 case HAL_XSPI_STATUS_MATCH_CB_ID :
2318 hxspi->StatusMatchCallback = HAL_XSPI_StatusMatchCallback;
2319 break;
2320 case HAL_XSPI_TIMEOUT_CB_ID :
2321 hxspi->TimeOutCallback = HAL_XSPI_TimeOutCallback;
2322 break;
2323 case HAL_XSPI_MSP_INIT_CB_ID :
2324 hxspi->MspInitCallback = HAL_XSPI_MspInit;
2325 break;
2326 case HAL_XSPI_MSP_DEINIT_CB_ID :
2327 hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit;
2328 break;
2329 default :
2330 /* Update the error code */
2331 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2332 /* update return status */
2333 status = HAL_ERROR;
2334 break;
2335 }
2336 }
2337 else if (hxspi->State == HAL_XSPI_STATE_RESET)
2338 {
2339 switch (CallbackID)
2340 {
2341 case HAL_XSPI_MSP_INIT_CB_ID :
2342 hxspi->MspInitCallback = HAL_XSPI_MspInit;
2343 break;
2344 case HAL_XSPI_MSP_DEINIT_CB_ID :
2345 hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit;
2346 break;
2347 default :
2348 /* Update the error code */
2349 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2350 /* update return status */
2351 status = HAL_ERROR;
2352 break;
2353 }
2354 }
2355 else
2356 {
2357 /* Update the error code */
2358 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK;
2359 /* update return status */
2360 status = HAL_ERROR;
2361 }
2362
2363 return status;
2364 }
2365 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2366
2367 /**
2368 * @}
2369 */
2370
2371 /** @defgroup XSPI_Exported_Functions_Group3 Peripheral Control and State functions
2372 * @brief XSPI control and State functions
2373 *
2374 @verbatim
2375 ===============================================================================
2376 ##### Peripheral Control and State functions #####
2377 ===============================================================================
2378 [..]
2379 This subsection provides a set of functions allowing to :
2380 (+) Check in run-time the state of the driver.
2381 (+) Check the error code set during last operation.
2382 (+) Abort any operation.
2383 (+) Manage the Fifo threshold.
2384 (+) Configure the timeout duration used in the driver.
2385
2386 @endverbatim
2387 * @{
2388 */
2389
2390 /**
2391 * @brief Abort the current operation, return to the indirect mode.
2392 * @param hxspi : XSPI handle
2393 * @retval HAL status
2394 */
HAL_XSPI_Abort(XSPI_HandleTypeDef * hxspi)2395 HAL_StatusTypeDef HAL_XSPI_Abort(XSPI_HandleTypeDef *hxspi)
2396 {
2397 HAL_StatusTypeDef status = HAL_OK;
2398 uint32_t tickstart = HAL_GetTick();
2399
2400 /* Check if the state is not in reset state */
2401 if (hxspi->State != HAL_XSPI_STATE_RESET)
2402 {
2403 /* Check if the DMA is enabled */
2404 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2405 {
2406 /* Disable the DMA transfer on the XSPI side */
2407 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2408
2409 /* Disable the DMA transmit on the DMA side */
2410 status = HAL_DMA_Abort(hxspi->hdmatx);
2411 if (status != HAL_OK)
2412 {
2413 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2414 }
2415
2416 /* Disable the DMA receive on the DMA side */
2417 status = HAL_DMA_Abort(hxspi->hdmarx);
2418 if (status != HAL_OK)
2419 {
2420 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2421 }
2422 }
2423
2424 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2425 {
2426 /* Perform an abort of the XSPI */
2427 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2428
2429 /* Wait until the transfer complete flag is set to go back in idle state */
2430 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, hxspi->Timeout);
2431
2432 if (status == HAL_OK)
2433 {
2434 /* Clear transfer complete flag */
2435 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2436
2437 /* Wait until the busy flag is reset to go back in idle state */
2438 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
2439
2440 if (status == HAL_OK)
2441 {
2442 /* Return to indirect mode */
2443 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2444
2445 hxspi->State = HAL_XSPI_STATE_READY;
2446 }
2447 }
2448 }
2449 else
2450 {
2451 /* Return to indirect mode */
2452 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2453
2454 hxspi->State = HAL_XSPI_STATE_READY;
2455 }
2456 }
2457 else
2458 {
2459 status = HAL_ERROR;
2460 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2461 }
2462
2463 return status;
2464 }
2465
2466 /**
2467 * @brief Abort the current operation, return to the indirect mode. (non-blocking function)
2468 * @param hxspi : XSPI handle
2469 * @retval HAL status
2470 */
HAL_XSPI_Abort_IT(XSPI_HandleTypeDef * hxspi)2471 HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi)
2472 {
2473 HAL_StatusTypeDef status = HAL_OK;
2474
2475 /* Check if the state is not in reset state */
2476 if (hxspi->State != HAL_XSPI_STATE_RESET)
2477 {
2478 /* Disable all interrupts */
2479 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));
2480
2481 hxspi->State = HAL_XSPI_STATE_ABORT;
2482
2483 /* Check if the DMA is enabled */
2484 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2485 {
2486 /* Disable the DMA transfer on the XSPI side */
2487 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2488
2489 /* Disable the DMA transmit on the DMA side */
2490 hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt;
2491 if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK)
2492 {
2493 hxspi->State = HAL_XSPI_STATE_READY;
2494
2495 /* Abort callback */
2496 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2497 hxspi->AbortCpltCallback(hxspi);
2498 #else
2499 HAL_XSPI_AbortCpltCallback(hxspi);
2500 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2501 }
2502
2503 /* Disable the DMA receive on the DMA side */
2504 hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt;
2505 if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK)
2506 {
2507 hxspi->State = HAL_XSPI_STATE_READY;
2508
2509 /* Abort callback */
2510 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2511 hxspi->AbortCpltCallback(hxspi);
2512 #else
2513 HAL_XSPI_AbortCpltCallback(hxspi);
2514 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2515 }
2516 }
2517 else
2518 {
2519 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2520 {
2521 /* Clear transfer complete flag */
2522 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2523
2524 /* Enable the transfer complete interrupts */
2525 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2526
2527 /* Perform an abort of the XSPI */
2528 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2529
2530 /* Return to indirect mode */
2531 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2532 }
2533 else
2534 {
2535 /* Return to indirect mode */
2536 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2537
2538 hxspi->State = HAL_XSPI_STATE_READY;
2539
2540 /* Abort callback */
2541 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2542 hxspi->AbortCpltCallback(hxspi);
2543 #else
2544 HAL_XSPI_AbortCpltCallback(hxspi);
2545 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2546 }
2547 }
2548 }
2549 else
2550 {
2551 status = HAL_ERROR;
2552 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2553 }
2554
2555 return status;
2556 }
2557
2558 /** @brief Set XSPI Fifo threshold.
2559 * @param hxspi : XSPI handle.
2560 * @param Threshold : Threshold of the Fifo.
2561 * @retval HAL status
2562 */
HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef * hxspi,uint32_t Threshold)2563 HAL_StatusTypeDef HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef *hxspi, uint32_t Threshold)
2564 {
2565 HAL_StatusTypeDef status = HAL_OK;
2566
2567 assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(Threshold));
2568
2569 /* Check the state */
2570 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2571 {
2572 /* Synchronize initialization structure with the new fifo threshold value */
2573 hxspi->Init.FifoThresholdByte = Threshold;
2574
2575 /* Configure new fifo threshold */
2576 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos));
2577
2578 }
2579 else
2580 {
2581 status = HAL_ERROR;
2582 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2583 }
2584
2585 return status;
2586 }
2587
2588 /** @brief Get XSPI Fifo threshold.
2589 * @param hxspi : XSPI handle.
2590 * @retval Fifo threshold
2591 */
HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef * hxspi)2592 uint32_t HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef *hxspi)
2593 {
2594 return ((READ_BIT(hxspi->Instance->CR, XSPI_CR_FTHRES) >> XSPI_CR_FTHRES_Pos) + 1U);
2595 }
2596
2597 /** @brief Set XSPI Memory Type.
2598 * @param hxspi : XSPI handle.
2599 * @param Type : Memory Type.
2600 * @retval HAL status
2601 */
HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef * hxspi,uint32_t Type)2602 HAL_StatusTypeDef HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef *hxspi, uint32_t Type)
2603 {
2604 HAL_StatusTypeDef status = HAL_OK;
2605
2606 assert_param(IS_XSPI_MEMORY_TYPE(Type));
2607
2608 /* Check the state */
2609 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2610 {
2611 /* Synchronize initialization structure with the new memory type value */
2612 hxspi->Init.MemoryType = Type;
2613
2614 /* Configure new memory type */
2615 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP, hxspi->Init.MemoryType);
2616 }
2617 else
2618 {
2619 status = HAL_ERROR;
2620 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2621 }
2622
2623 return status;
2624 }
2625
2626 /** @brief Set XSPI Device Size.
2627 * @param hxspi : XSPI handle.
2628 * @param Size : Device Size.
2629 * @retval HAL status
2630 */
HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef * hxspi,uint32_t Size)2631 HAL_StatusTypeDef HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef *hxspi, uint32_t Size)
2632 {
2633 HAL_StatusTypeDef status = HAL_OK;
2634
2635 assert_param(IS_XSPI_MEMORY_SIZE(Size));
2636
2637 /* Check the state */
2638 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2639 {
2640 /* Synchronize initialization structure with the new device size value */
2641 hxspi->Init.MemorySize = Size;
2642
2643 /* Configure new device size */
2644 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_DEVSIZE,
2645 (hxspi->Init.MemorySize << XSPI_DCR1_DEVSIZE_Pos));
2646 }
2647 else
2648 {
2649 status = HAL_ERROR;
2650 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2651 }
2652
2653 return status;
2654 }
2655
2656 /** @brief Set XSPI Clock prescaler.
2657 * @param hxspi : XSPI handle.
2658 * @param Prescaler : Clock prescaler.
2659 * @retval HAL status
2660 */
HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef * hxspi,uint32_t Prescaler)2661 HAL_StatusTypeDef HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef *hxspi, uint32_t Prescaler)
2662 {
2663 HAL_StatusTypeDef status = HAL_OK;
2664 assert_param(IS_XSPI_CLK_PRESCALER(Prescaler));
2665
2666 /* Check the state */
2667 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2668 {
2669 /* Synchronize initialization structure with the new clock prescaler value */
2670 hxspi->Init.ClockPrescaler = Prescaler;
2671
2672 /* Configure clock prescaler */
2673 MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER,
2674 ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos));
2675 }
2676 else
2677 {
2678 status = HAL_ERROR;
2679 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2680 }
2681
2682 return status;
2683 }
2684
2685 /** @brief Set XSPI timeout.
2686 * @param hxspi : XSPI handle.
2687 * @param Timeout : Timeout for the memory access.
2688 * @retval HAL state
2689 */
HAL_XSPI_SetTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Timeout)2690 HAL_StatusTypeDef HAL_XSPI_SetTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Timeout)
2691 {
2692 hxspi->Timeout = Timeout;
2693 return HAL_OK;
2694 }
2695
2696 /**
2697 * @brief Return the XSPI error code.
2698 * @param hxspi : XSPI handle
2699 * @retval XSPI Error Code
2700 */
HAL_XSPI_GetError(const XSPI_HandleTypeDef * hxspi)2701 uint32_t HAL_XSPI_GetError(const XSPI_HandleTypeDef *hxspi)
2702 {
2703 return hxspi->ErrorCode;
2704 }
2705
2706 /**
2707 * @brief Return the XSPI handle state.
2708 * @param hxspi : XSPI handle
2709 * @retval HAL state
2710 */
HAL_XSPI_GetState(const XSPI_HandleTypeDef * hxspi)2711 uint32_t HAL_XSPI_GetState(const XSPI_HandleTypeDef *hxspi)
2712 {
2713 /* Return XSPI handle state */
2714 return hxspi->State;
2715 }
2716
2717 /**
2718 * @}
2719 */
2720
2721 /** @defgroup XSPI_Exported_Functions_Group4 Delay Block function
2722 * @brief Delay block function
2723 *
2724 @verbatim
2725 ===============================================================================
2726 ##### Delay Block function #####
2727 ===============================================================================
2728 [..]
2729 This subsection provides a set of functions allowing to :
2730 (+) Configure the delay block.
2731
2732 @endverbatim
2733 * @{
2734 */
2735
2736 /**
2737 * @brief Set the Delay Block configuration.
2738 * @param hxspi : XSPI handle.
2739 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2740 * @retval HAL status.
2741 */
HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2742 HAL_StatusTypeDef HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2743 {
2744 HAL_StatusTypeDef status = HAL_ERROR;
2745
2746 /* Enable XSPI Free Running Clock (mandatory) */
2747 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2748
2749 /* Update XSPI state */
2750 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
2751
2752 if (hxspi->Instance == OCTOSPI1)
2753 {
2754 /* Enable the DelayBlock */
2755 LL_DLYB_Enable(DLYB_OCTOSPI1);
2756
2757 /* Set the Delay Block configuration */
2758 LL_DLYB_SetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
2759 status = HAL_OK;
2760 }
2761 else
2762 {
2763 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2764 }
2765
2766 /* Abort the current XSPI operation if exist */
2767 (void)HAL_XSPI_Abort(hxspi);
2768
2769 /* Disable Free Running Clock */
2770 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2771
2772 return status;
2773 }
2774
2775 /**
2776 * @brief Get the Delay Block configuration.
2777 * @param hxspi : XSPI handle.
2778 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2779 * @retval HAL status.
2780 */
HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2781 HAL_StatusTypeDef HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2782 {
2783 HAL_StatusTypeDef status = HAL_ERROR;
2784
2785 if (hxspi->Instance == OCTOSPI1)
2786 {
2787 LL_DLYB_GetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
2788 status = HAL_OK;
2789 }
2790 else
2791 {
2792 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2793 }
2794
2795 return status;
2796 }
2797
2798 /**
2799 * @brief Get the Delay line length value.
2800 * @param hxspi : XSPI handle.
2801 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
2802 * @retval HAL status.
2803 */
HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)2804 HAL_StatusTypeDef HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
2805 {
2806 HAL_StatusTypeDef status = HAL_ERROR;
2807
2808 /* Enable XSPI Free Running Clock (mandatory) */
2809 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2810
2811 /* Update XSPI state */
2812 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
2813
2814 if (hxspi->Instance == OCTOSPI1)
2815 {
2816 /* Enable the DelayBlock */
2817 LL_DLYB_Enable(DLYB_OCTOSPI1);
2818
2819 /* try to detect Period */
2820 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI1, pdlyb_cfg) == (uint32_t)SUCCESS)
2821 {
2822 status = HAL_OK;
2823 }
2824
2825 /* Disable the DelayBlock */
2826 LL_DLYB_Disable(DLYB_OCTOSPI1);
2827 }
2828 else
2829 {
2830 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2831 }
2832
2833 /* Abort the current XSPI operation if exist */
2834 (void)HAL_XSPI_Abort(hxspi);
2835
2836 /* Disable Free Running Clock */
2837 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
2838
2839 return status;
2840 }
2841
2842 /**
2843 @cond 0
2844 */
2845 /**
2846 * @brief DMA XSPI process complete callback.
2847 * @param hdma : DMA handle
2848 * @retval None
2849 */
XSPI_DMACplt(DMA_HandleTypeDef * hdma)2850 static void XSPI_DMACplt(DMA_HandleTypeDef *hdma)
2851 {
2852 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2853 hxspi->XferCount = 0;
2854
2855 /* Disable the DMA transfer on the XSPI side */
2856 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2857
2858 /* Enable the XSPI transfer complete Interrupt */
2859 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2860 }
2861
2862 /**
2863 * @brief DMA XSPI process half complete callback.
2864 * @param hdma : DMA handle
2865 * @retval None
2866 */
XSPI_DMAHalfCplt(DMA_HandleTypeDef * hdma)2867 static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
2868 {
2869 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2870 hxspi->XferCount = (hxspi->XferCount >> 1);
2871
2872 if (hxspi->State == HAL_XSPI_STATE_BUSY_RX)
2873 {
2874 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2875 hxspi->RxHalfCpltCallback(hxspi);
2876 #else
2877 HAL_XSPI_RxHalfCpltCallback(hxspi);
2878 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2879 }
2880 else
2881 {
2882 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2883 hxspi->TxHalfCpltCallback(hxspi);
2884 #else
2885 HAL_XSPI_TxHalfCpltCallback(hxspi);
2886 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2887 }
2888 }
2889
2890 /**
2891 * @brief DMA XSPI communication error callback.
2892 * @param hdma : DMA handle
2893 * @retval None
2894 */
XSPI_DMAError(DMA_HandleTypeDef * hdma)2895 static void XSPI_DMAError(DMA_HandleTypeDef *hdma)
2896 {
2897 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2898 hxspi->XferCount = 0;
2899 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2900
2901 /* Disable the DMA transfer on the XSPI side */
2902 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2903
2904 /* Abort the XSPI */
2905 if (HAL_XSPI_Abort_IT(hxspi) != HAL_OK)
2906 {
2907 /* Disable the interrupts */
2908 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
2909
2910 hxspi->State = HAL_XSPI_STATE_READY;
2911
2912 /* Error callback */
2913 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2914 hxspi->ErrorCallback(hxspi);
2915 #else
2916 HAL_XSPI_ErrorCallback(hxspi);
2917 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2918 }
2919 }
2920
2921 /**
2922 * @brief DMA XSPI abort complete callback.
2923 * @param hdma : DMA handle
2924 * @retval None
2925 */
XSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)2926 static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2927 {
2928 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
2929 hxspi->XferCount = 0;
2930
2931 /* Check the state */
2932 if (hxspi->State == HAL_XSPI_STATE_ABORT)
2933 {
2934 /* DMA abort called by XSPI abort */
2935 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2936 {
2937 /* Clear transfer complete flag */
2938 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2939
2940 /* Enable the transfer complete interrupts */
2941 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2942
2943 /* Perform an abort of the XSPI */
2944 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2945 }
2946 else
2947 {
2948 hxspi->State = HAL_XSPI_STATE_READY;
2949
2950 /* Abort callback */
2951 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2952 hxspi->AbortCpltCallback(hxspi);
2953 #else
2954 HAL_XSPI_AbortCpltCallback(hxspi);
2955 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2956 }
2957 }
2958 else
2959 {
2960 /* DMA abort called due to a transfer error interrupt */
2961 hxspi->State = HAL_XSPI_STATE_READY;
2962
2963 /* Error callback */
2964 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2965 hxspi->ErrorCallback(hxspi);
2966 #else
2967 HAL_XSPI_ErrorCallback(hxspi);
2968 #endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2969 }
2970 }
2971
2972 /**
2973 * @brief Wait for a flag state until timeout.
2974 * @param hxspi : XSPI handle
2975 * @param Flag : Flag checked
2976 * @param State : Value of the flag expected
2977 * @param Timeout : Duration of the timeout
2978 * @param Tickstart : Tick start value
2979 * @retval HAL status
2980 */
XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2981 static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag,
2982 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2983 {
2984 /* Wait until flag is in expected state */
2985 while ((HAL_XSPI_GET_FLAG(hxspi, Flag)) != State)
2986 {
2987 /* Check for the Timeout */
2988 if (Timeout != HAL_MAX_DELAY)
2989 {
2990 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2991 {
2992 hxspi->State = HAL_XSPI_STATE_READY;
2993 hxspi->ErrorCode |= HAL_XSPI_ERROR_TIMEOUT;
2994
2995 return HAL_TIMEOUT;
2996 }
2997 }
2998 }
2999 return HAL_OK;
3000 }
3001
3002 /**
3003 * @brief Configure the registers for the regular command mode.
3004 * @param hxspi : XSPI handle
3005 * @param pCmd : structure that contains the command configuration information
3006 * @retval HAL status
3007 */
XSPI_ConfigCmd(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * pCmd)3008 static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *pCmd)
3009 {
3010 HAL_StatusTypeDef status = HAL_OK;
3011 __IO uint32_t *ccr_reg;
3012 __IO uint32_t *tcr_reg;
3013 __IO uint32_t *ir_reg;
3014 __IO uint32_t *abr_reg;
3015
3016 /* Re-initialize the value of the functional mode */
3017 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U);
3018
3019 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
3020 {
3021 assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect));
3022 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_MSEL, pCmd->IOSelect);
3023 }
3024
3025 if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
3026 {
3027 ccr_reg = &(hxspi->Instance->WCCR);
3028 tcr_reg = &(hxspi->Instance->WTCR);
3029 ir_reg = &(hxspi->Instance->WIR);
3030 abr_reg = &(hxspi->Instance->WABR);
3031 }
3032 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG)
3033 {
3034 ccr_reg = &(hxspi->Instance->WPCCR);
3035 tcr_reg = &(hxspi->Instance->WPTCR);
3036 ir_reg = &(hxspi->Instance->WPIR);
3037 abr_reg = &(hxspi->Instance->WPABR);
3038 }
3039 else
3040 {
3041 ccr_reg = &(hxspi->Instance->CCR);
3042 tcr_reg = &(hxspi->Instance->TCR);
3043 ir_reg = &(hxspi->Instance->IR);
3044 abr_reg = &(hxspi->Instance->ABR);
3045 }
3046
3047 /* Configure the CCR register with DQS and SIOO modes */
3048 *ccr_reg = (pCmd->DQSMode | pCmd->SIOOMode);
3049
3050 /* Workaround for Erratasheet: Memory-mapped write error response when DQS output is disabled */
3051 if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
3052 {
3053 /* When doing memory-mapped writes, set the DQSE bit of the OCTOSPI_WCCR register,
3054 even for memories that have no DQS pin. */
3055 SET_BIT((*ccr_reg), XSPI_CCR_DQSE);
3056 }
3057
3058 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
3059 {
3060 /* Configure the ABR register with alternate bytes value */
3061 *abr_reg = pCmd->AlternateBytes;
3062
3063 /* Configure the CCR register with alternate bytes communication parameters */
3064 MODIFY_REG((*ccr_reg), (XSPI_CCR_ABMODE | XSPI_CCR_ABDTR | XSPI_CCR_ABSIZE),
3065 (pCmd->AlternateBytesMode | pCmd->AlternateBytesDTRMode | pCmd->AlternateBytesWidth));
3066 }
3067
3068 /* Configure the TCR register with the number of dummy cycles */
3069 MODIFY_REG((*tcr_reg), XSPI_TCR_DCYC, pCmd->DummyCycles);
3070
3071 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3072 {
3073 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
3074 {
3075 /* Configure the DLR register with the number of data */
3076 hxspi->Instance->DLR = (pCmd->DataLength - 1U);
3077 }
3078 }
3079
3080 /* Configure SSHIFT register to handle SDR/DTR data transfer */
3081 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3082 {
3083 if (pCmd->DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)
3084 {
3085 /* Deactivate sample shifting when receiving data in DTR mode (DDTR=1) */
3086 CLEAR_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT);
3087 }
3088 else if (hxspi->Init.SampleShifting == HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE)
3089 {
3090 /* Configure sample shifting */
3091 SET_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT);
3092 }
3093 else
3094 {
3095 /* Do nothing */
3096 }
3097 }
3098
3099 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
3100 {
3101 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3102 {
3103 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3104 {
3105 /* ---- Command with instruction, address and data ---- */
3106
3107 /* Configure the CCR register with all communication parameters */
3108 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3109 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3110 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3111 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3112 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3113 pCmd->DataMode | pCmd->DataDTRMode));
3114 }
3115 else
3116 {
3117 /* ---- Command with instruction and address ---- */
3118
3119 /* Configure the CCR register with all communication parameters */
3120 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3121 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3122 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3123 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
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 /* Configure the IR register with the instruction value */
3133 *ir_reg = pCmd->Instruction;
3134
3135 /* Configure the AR register with the address value */
3136 hxspi->Instance->AR = pCmd->Address;
3137 }
3138 else
3139 {
3140 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3141 {
3142 /* ---- Command with instruction and data ---- */
3143
3144 /* Configure the CCR register with all communication parameters */
3145 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3146 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3147 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3148 pCmd->DataMode | pCmd->DataDTRMode));
3149 }
3150 else
3151 {
3152 /* ---- Command with only instruction ---- */
3153
3154 /* Configure the CCR register with all communication parameters */
3155 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE),
3156 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth));
3157
3158 /* The DHQC bit is linked with DDTR bit which should be activated */
3159 if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) &&
3160 (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE))
3161 {
3162 MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE);
3163 }
3164 }
3165
3166 /* Configure the IR register with the instruction value */
3167 *ir_reg = pCmd->Instruction;
3168
3169 }
3170 }
3171 else
3172 {
3173 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3174 {
3175 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3176 {
3177 /* ---- Command with address and data ---- */
3178
3179 /* Configure the CCR register with all communication parameters */
3180 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3181 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3182 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3183 pCmd->DataMode | pCmd->DataDTRMode));
3184 }
3185 else
3186 {
3187 /* ---- Command with only address ---- */
3188
3189 /* Configure the CCR register with all communication parameters */
3190 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3191 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
3192 }
3193
3194 /* Configure the AR register with the instruction value */
3195 hxspi->Instance->AR = pCmd->Address;
3196 }
3197 else
3198 {
3199 /* ---- Invalid command configuration (no instruction, no address) ---- */
3200 status = HAL_ERROR;
3201 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3202 }
3203 }
3204
3205 return status;
3206 }
3207
3208 /**
3209 @endcond
3210 */
3211
3212 /**
3213 * @}
3214 */
3215
3216 #endif /* HAL_XSPI_MODULE_ENABLED */
3217
3218 /**
3219 * @}
3220 */
3221
3222 /**
3223 * @}
3224 */
3225
3226 #endif /* HSPI || HSPI1 || HSPI2 || OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3227