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