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