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