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,const uint8_t * pData,uint32_t Timeout)1285 HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, const uint8_t *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 = (uint8_t *)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,const uint8_t * pData)1447 HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, const uint8_t *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 = (uint8_t *)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,const uint8_t * pData)1568 HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, const uint8_t *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 = (uint8_t *)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 operation, return to the indirect mode.
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 tickstart = HAL_GetTick();
2546
2547 /* Check if the state is not in reset state */
2548 if (hxspi->State != HAL_XSPI_STATE_RESET)
2549 {
2550 /* Check if the DMA is enabled */
2551 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2552 {
2553 /* Disable the DMA transfer on the XSPI side */
2554 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2555
2556 /* Disable the DMA transmit on the DMA side */
2557 status = HAL_DMA_Abort(hxspi->hdmatx);
2558 if (status != HAL_OK)
2559 {
2560 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2561 }
2562
2563 /* Disable the DMA receive on the DMA side */
2564 status = HAL_DMA_Abort(hxspi->hdmarx);
2565 if (status != HAL_OK)
2566 {
2567 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
2568 }
2569 }
2570
2571 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2572 {
2573 /* Perform an abort of the XSPI */
2574 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2575
2576 /* Wait until the transfer complete flag is set to go back in idle state */
2577 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, hxspi->Timeout);
2578
2579 if (status == HAL_OK)
2580 {
2581 /* Clear transfer complete flag */
2582 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2583
2584 /* Wait until the busy flag is reset to go back in idle state */
2585 status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout);
2586
2587 if (status == HAL_OK)
2588 {
2589 /* Return to indirect mode */
2590 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2591
2592 hxspi->State = HAL_XSPI_STATE_READY;
2593 }
2594 }
2595 }
2596 else
2597 {
2598 /* Return to indirect mode */
2599 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2600
2601 hxspi->State = HAL_XSPI_STATE_READY;
2602 }
2603 }
2604 else
2605 {
2606 status = HAL_ERROR;
2607 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2608 }
2609
2610 return status;
2611 }
2612
2613 /**
2614 * @brief Abort the current operation, return to the indirect mode. (non-blocking function)
2615 * @param hxspi : XSPI handle
2616 * @retval HAL status
2617 */
HAL_XSPI_Abort_IT(XSPI_HandleTypeDef * hxspi)2618 HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi)
2619 {
2620 HAL_StatusTypeDef status = HAL_OK;
2621
2622 /* Check if the state is not in reset state */
2623 if (hxspi->State != HAL_XSPI_STATE_RESET)
2624 {
2625 /* Disable all interrupts */
2626 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));
2627
2628 hxspi->State = HAL_XSPI_STATE_ABORT;
2629
2630 /* Check if the DMA is enabled */
2631 if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U)
2632 {
2633 /* Disable the DMA transfer on the XSPI side */
2634 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
2635
2636 /* Disable the DMA transmit on the DMA side */
2637 hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt;
2638 if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK)
2639 {
2640 hxspi->State = HAL_XSPI_STATE_READY;
2641
2642 /* Abort callback */
2643 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2644 hxspi->AbortCpltCallback(hxspi);
2645 #else
2646 HAL_XSPI_AbortCpltCallback(hxspi);
2647 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2648 }
2649
2650 /* Disable the DMA receive on the DMA side */
2651 hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt;
2652 if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK)
2653 {
2654 hxspi->State = HAL_XSPI_STATE_READY;
2655
2656 /* Abort callback */
2657 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2658 hxspi->AbortCpltCallback(hxspi);
2659 #else
2660 HAL_XSPI_AbortCpltCallback(hxspi);
2661 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2662 }
2663 }
2664 else
2665 {
2666 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
2667 {
2668 /* Clear transfer complete flag */
2669 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
2670
2671 /* Enable the transfer complete interrupts */
2672 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
2673
2674 /* Perform an abort of the XSPI */
2675 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
2676
2677 /* Return to indirect mode */
2678 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2679 }
2680 else
2681 {
2682 /* Return to indirect mode */
2683 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE);
2684
2685 hxspi->State = HAL_XSPI_STATE_READY;
2686
2687 /* Abort callback */
2688 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
2689 hxspi->AbortCpltCallback(hxspi);
2690 #else
2691 HAL_XSPI_AbortCpltCallback(hxspi);
2692 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
2693 }
2694 }
2695 }
2696 else
2697 {
2698 status = HAL_ERROR;
2699 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2700 }
2701
2702 return status;
2703 }
2704
2705 /** @brief Set XSPI Fifo threshold.
2706 * @param hxspi : XSPI handle.
2707 * @param Threshold : Threshold of the Fifo.
2708 * @retval HAL status
2709 */
HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef * hxspi,uint32_t Threshold)2710 HAL_StatusTypeDef HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef *hxspi, uint32_t Threshold)
2711 {
2712 HAL_StatusTypeDef status = HAL_OK;
2713
2714 if (IS_OSPI_ALL_INSTANCE(hxspi->Instance))
2715 {
2716 assert_param(IS_OCTOSPI_FIFO_THRESHOLD_BYTE(Threshold));
2717 }
2718 #if defined(HSPI1)
2719 else if (IS_HSPI_ALL_INSTANCE(hxspi->Instance))
2720 {
2721 assert_param(IS_HSPI_FIFO_THRESHOLD_BYTE(Threshold));
2722 }
2723 #endif /* HSPI1 */
2724 else
2725 {
2726 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2727 return HAL_ERROR;
2728 }
2729
2730 /* Check the state */
2731 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2732 {
2733 /* Synchronize initialization structure with the new fifo threshold value */
2734 hxspi->Init.FifoThresholdByte = Threshold;
2735
2736 /* Configure new fifo threshold */
2737 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos));
2738
2739 }
2740 else
2741 {
2742 status = HAL_ERROR;
2743 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2744 }
2745
2746 return status;
2747 }
2748
2749 /** @brief Get XSPI Fifo threshold.
2750 * @param hxspi : XSPI handle.
2751 * @retval Fifo threshold
2752 */
HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef * hxspi)2753 uint32_t HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef *hxspi)
2754 {
2755 return ((READ_BIT(hxspi->Instance->CR, XSPI_CR_FTHRES) >> XSPI_CR_FTHRES_Pos) + 1U);
2756 }
2757
2758 /** @brief Set XSPI Memory Type.
2759 * @param hxspi : XSPI handle.
2760 * @param Type : Memory Type.
2761 * @retval HAL status
2762 */
HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef * hxspi,uint32_t Type)2763 HAL_StatusTypeDef HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef *hxspi, uint32_t Type)
2764 {
2765 HAL_StatusTypeDef status = HAL_OK;
2766
2767 assert_param(IS_XSPI_MEMORY_TYPE(Type));
2768
2769 /* Check the state */
2770 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2771 {
2772 /* Synchronize initialization structure with the new memory type value */
2773 hxspi->Init.MemoryType = Type;
2774
2775 /* Configure new memory type */
2776 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP, hxspi->Init.MemoryType);
2777 }
2778 else
2779 {
2780 status = HAL_ERROR;
2781 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2782 }
2783
2784 return status;
2785 }
2786
2787 /** @brief Set XSPI Device Size.
2788 * @param hxspi : XSPI handle.
2789 * @param Size : Device Size.
2790 * @retval HAL status
2791 */
HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef * hxspi,uint32_t Size)2792 HAL_StatusTypeDef HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef *hxspi, uint32_t Size)
2793 {
2794 HAL_StatusTypeDef status = HAL_OK;
2795
2796 assert_param(IS_XSPI_MEMORY_SIZE(Size));
2797
2798 /* Check the state */
2799 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2800 {
2801 /* Synchronize initialization structure with the new device size value */
2802 hxspi->Init.MemorySize = Size;
2803
2804 /* Configure new device size */
2805 MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_DEVSIZE,
2806 (hxspi->Init.MemorySize << XSPI_DCR1_DEVSIZE_Pos));
2807 }
2808 else
2809 {
2810 status = HAL_ERROR;
2811 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2812 }
2813
2814 return status;
2815 }
2816
2817 /** @brief Set XSPI Clock prescaler.
2818 * @param hxspi : XSPI handle.
2819 * @param Prescaler : Clock prescaler.
2820 * @retval HAL status
2821 */
HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef * hxspi,uint32_t Prescaler)2822 HAL_StatusTypeDef HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef *hxspi, uint32_t Prescaler)
2823 {
2824 HAL_StatusTypeDef status = HAL_OK;
2825 assert_param(IS_XSPI_CLK_PRESCALER(Prescaler));
2826
2827 /* Check the state */
2828 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
2829 {
2830 /* Synchronize initialization structure with the new clock prescaler value */
2831 hxspi->Init.ClockPrescaler = Prescaler;
2832
2833 /* Configure clock prescaler */
2834 MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER,
2835 ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos));
2836 }
2837 else
2838 {
2839 status = HAL_ERROR;
2840 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
2841 }
2842
2843 return status;
2844 }
2845
2846 /** @brief Set XSPI timeout.
2847 * @param hxspi : XSPI handle.
2848 * @param Timeout : Timeout for the memory access.
2849 * @retval HAL state
2850 */
HAL_XSPI_SetTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Timeout)2851 HAL_StatusTypeDef HAL_XSPI_SetTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Timeout)
2852 {
2853 hxspi->Timeout = Timeout;
2854 return HAL_OK;
2855 }
2856
2857 /**
2858 * @brief Return the XSPI error code.
2859 * @param hxspi : XSPI handle
2860 * @retval XSPI Error Code
2861 */
HAL_XSPI_GetError(const XSPI_HandleTypeDef * hxspi)2862 uint32_t HAL_XSPI_GetError(const XSPI_HandleTypeDef *hxspi)
2863 {
2864 return hxspi->ErrorCode;
2865 }
2866
2867 /**
2868 * @brief Return the XSPI handle state.
2869 * @param hxspi : XSPI handle
2870 * @retval HAL state
2871 */
HAL_XSPI_GetState(const XSPI_HandleTypeDef * hxspi)2872 uint32_t HAL_XSPI_GetState(const XSPI_HandleTypeDef *hxspi)
2873 {
2874 /* Return XSPI handle state */
2875 return hxspi->State;
2876 }
2877
2878 /**
2879 * @}
2880 */
2881
2882 #if defined(OCTOSPIM)
2883 /** @defgroup XSPI_Exported_Functions_Group4 IO Manager configuration function
2884 * @brief XSPI IO Manager configuration function
2885 *
2886 @verbatim
2887 ===============================================================================
2888 ##### IO Manager configuration function #####
2889 ===============================================================================
2890 [..]
2891 This subsection provides a set of functions allowing to :
2892 (+) Configure the IO manager.
2893
2894 @endverbatim
2895 * @{
2896 */
2897
2898 /**
2899 * @brief Configure the XSPI IO manager.
2900 * @param hxspi : XSPI handle
2901 * @param pCfg : Pointer to Configuration of the IO Manager for the instance
2902 * @param Timeout : Timeout duration
2903 * @retval HAL status
2904 */
HAL_XSPIM_Config(XSPI_HandleTypeDef * const hxspi,XSPIM_CfgTypeDef * const pCfg,uint32_t Timeout)2905 HAL_StatusTypeDef HAL_XSPIM_Config(XSPI_HandleTypeDef *const hxspi, XSPIM_CfgTypeDef *const pCfg, uint32_t Timeout)
2906 {
2907 HAL_StatusTypeDef status = HAL_OK;
2908 uint32_t instance;
2909 uint8_t index;
2910 uint8_t xspi_enabled = 0U;
2911 uint8_t other_instance;
2912 XSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2913
2914 /* Prevent unused argument(s) compilation warning */
2915 UNUSED(Timeout);
2916
2917 /* Check the parameters of the XSPI IO Manager configuration structure */
2918 assert_param(IS_XSPIM_PORT(pCfg->ClkPort));
2919 assert_param(IS_XSPIM_DQS_PORT(pCfg->DQSPort));
2920 assert_param(IS_XSPIM_PORT(pCfg->NCSPort));
2921 assert_param(IS_XSPIM_IO_PORT(pCfg->IOLowPort));
2922 assert_param(IS_XSPIM_IO_PORT(pCfg->IOHighPort));
2923 assert_param(IS_XSPIM_REQ2ACKTIME(pCfg->Req2AckTime));
2924
2925 if (hxspi->Instance == OCTOSPI1)
2926 {
2927 instance = 0U;
2928 other_instance = 1U;
2929 }
2930 else if (hxspi->Instance == OCTOSPI2)
2931 {
2932 instance = 1U;
2933 other_instance = 0U;
2934 }
2935 else
2936 {
2937 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
2938 return HAL_ERROR;
2939 }
2940
2941 /**************** Get current configuration of the instances ****************/
2942 for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2943 {
2944 XSPIM_GetConfig(index + 1U, &(IOM_cfg[index]));
2945 }
2946
2947 /********** Disable both XSPI to configure XSPI IO Manager **********/
2948 if ((OCTOSPI1->CR & XSPI_CR_EN) != 0U)
2949 {
2950 CLEAR_BIT(OCTOSPI1->CR, XSPI_CR_EN);
2951 xspi_enabled |= 0x1U;
2952 }
2953 if ((OCTOSPI2->CR & XSPI_CR_EN) != 0U)
2954 {
2955 CLEAR_BIT(OCTOSPI2->CR, XSPI_CR_EN);
2956 xspi_enabled |= 0x2U;
2957 }
2958
2959 /***************** Deactivation of previous configuration *****************/
2960 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
2961 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2962 {
2963 /* De-multiplexing should be performed */
2964 CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2965
2966 if (other_instance == 1U)
2967 {
2968 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
2969 if (IOM_cfg[other_instance].DQSPort != 0U)
2970 {
2971 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
2972 }
2973 if (IOM_cfg[other_instance].IOLowPort != HAL_XSPIM_IOPORT_NONE)
2974 {
2975 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2976 OCTOSPIM_PCR_IOLSRC_1);
2977 }
2978 if (IOM_cfg[other_instance].IOHighPort != HAL_XSPIM_IOPORT_NONE)
2979 {
2980 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2981 OCTOSPIM_PCR_IOHSRC_1);
2982 }
2983 }
2984 }
2985 else
2986 {
2987 if (IOM_cfg[instance].ClkPort != 0U)
2988 {
2989 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
2990 if (IOM_cfg[instance].DQSPort != 0U)
2991 {
2992 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
2993 }
2994 if (IOM_cfg[instance].IOLowPort != HAL_XSPIM_IOPORT_NONE)
2995 {
2996 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2997 }
2998 if (IOM_cfg[instance].IOHighPort != HAL_XSPIM_IOPORT_NONE)
2999 {
3000 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
3001 }
3002 }
3003 }
3004
3005 /********************* Deactivation of other instance *********************/
3006 if ((pCfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (pCfg->DQSPort == IOM_cfg[other_instance].DQSPort) ||
3007 (pCfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (pCfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
3008 (pCfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
3009 {
3010 if ((pCfg->ClkPort == IOM_cfg[other_instance].ClkPort) &&
3011 (pCfg->DQSPort == IOM_cfg[other_instance].DQSPort) &&
3012 (pCfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
3013 (pCfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
3014 {
3015 /* Multiplexing should be performed */
3016 SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
3017 }
3018 else
3019 {
3020 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
3021 if (IOM_cfg[other_instance].DQSPort != 0U)
3022 {
3023 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
3024 }
3025 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
3026 if (IOM_cfg[other_instance].IOLowPort != HAL_XSPIM_IOPORT_NONE)
3027 {
3028 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
3029 }
3030 if (IOM_cfg[other_instance].IOHighPort != HAL_XSPIM_IOPORT_NONE)
3031 {
3032 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
3033 }
3034 }
3035 }
3036
3037 /******************** Activation of new configuration *********************/
3038 MODIFY_REG(OCTOSPIM->PCR[(pCfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
3039 (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
3040
3041 if ((pCfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
3042 {
3043 MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((pCfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
3044 }
3045
3046 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
3047 {
3048 MODIFY_REG(OCTOSPIM->PCR[(pCfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
3049 if (pCfg->DQSPort != 0U)
3050 {
3051 MODIFY_REG(OCTOSPIM->PCR[(pCfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
3052 }
3053
3054 if ((pCfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
3055 {
3056 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
3057 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
3058 }
3059 else if (pCfg->IOLowPort != HAL_XSPIM_IOPORT_NONE)
3060 {
3061 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
3062 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
3063 }
3064 else
3065 {
3066 /* Nothing to do */
3067 }
3068
3069 if ((pCfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
3070 {
3071 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
3072 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
3073 }
3074 else if (pCfg->IOHighPort != HAL_XSPIM_IOPORT_NONE)
3075 {
3076 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
3077 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
3078 }
3079 else
3080 {
3081 /* Nothing to do */
3082 }
3083 }
3084 else
3085 {
3086 MODIFY_REG(OCTOSPIM->PCR[(pCfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
3087 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
3088 if (pCfg->DQSPort != 0U)
3089 {
3090 MODIFY_REG(OCTOSPIM->PCR[(pCfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
3091 (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
3092 }
3093
3094 if ((pCfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
3095 {
3096 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
3097 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
3098 (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
3099 }
3100 else if (pCfg->IOLowPort != HAL_XSPIM_IOPORT_NONE)
3101 {
3102 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
3103 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
3104 (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
3105 }
3106 else
3107 {
3108 /* Nothing to do */
3109 }
3110
3111 if ((pCfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
3112 {
3113 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
3114 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
3115 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
3116 }
3117 else if (pCfg->IOHighPort != HAL_XSPIM_IOPORT_NONE)
3118 {
3119 MODIFY_REG(OCTOSPIM->PCR[((pCfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
3120 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
3121 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
3122 }
3123 else
3124 {
3125 /* Nothing to do */
3126 }
3127 }
3128
3129 /******* Re-enable both XSPI after configure XSPI IO Manager ********/
3130 if ((xspi_enabled & 0x1U) != 0U)
3131 {
3132 SET_BIT(OCTOSPI1->CR, XSPI_CR_EN);
3133 }
3134 if ((xspi_enabled & 0x2U) != 0U)
3135 {
3136 SET_BIT(OCTOSPI2->CR, XSPI_CR_EN);
3137 }
3138
3139 return status;
3140 }
3141
3142 /**
3143 * @}
3144 */
3145
3146 #endif /* OCTOSPIM */
3147 /** @defgroup XSPI_Exported_Functions_Group5 Delay Block function
3148 * @brief Delay block function
3149 *
3150 @verbatim
3151 ===============================================================================
3152 ##### Delay Block function #####
3153 ===============================================================================
3154 [..]
3155 This subsection provides a set of functions allowing to :
3156 (+) Configure the delay block.
3157
3158 @endverbatim
3159 * @{
3160 */
3161
3162 /**
3163 * @brief Set the Delay Block configuration.
3164 * @param hxspi : XSPI handle.
3165 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
3166 * @retval HAL status.
3167 */
HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)3168 HAL_StatusTypeDef HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
3169 {
3170 HAL_StatusTypeDef status = HAL_ERROR;
3171
3172 /* Enable XSPI Free Running Clock (mandatory) */
3173 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
3174
3175 /* Update XSPI state */
3176 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
3177
3178 if (hxspi->Instance == OCTOSPI1)
3179 {
3180 /* Enable the DelayBlock */
3181 LL_DLYB_Enable(DLYB_OCTOSPI1);
3182
3183 /* Set the Delay Block configuration */
3184 LL_DLYB_SetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
3185 status = HAL_OK;
3186 }
3187 #if defined(OCTOSPI2)
3188 else if (hxspi->Instance == OCTOSPI2)
3189 {
3190 /* Enable the DelayBlock */
3191 LL_DLYB_Enable(DLYB_OCTOSPI2);
3192
3193 /* Set the Delay Block configuration */
3194 LL_DLYB_SetDelay(DLYB_OCTOSPI2, pdlyb_cfg);
3195 status = HAL_OK;
3196 }
3197 #endif /* OCTOSPI2 */
3198 else
3199 {
3200 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
3201 }
3202
3203 /* Abort the current XSPI operation if exist */
3204 (void)HAL_XSPI_Abort(hxspi);
3205
3206 /* Disable Free Running Clock */
3207 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
3208
3209 return status;
3210 }
3211
3212 /**
3213 * @brief Get the Delay Block configuration.
3214 * @param hxspi : XSPI handle.
3215 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
3216 * @retval HAL status.
3217 */
HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)3218 HAL_StatusTypeDef HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
3219 {
3220 HAL_StatusTypeDef status = HAL_ERROR;
3221
3222 if (hxspi->Instance == OCTOSPI1)
3223 {
3224 LL_DLYB_GetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
3225 status = HAL_OK;
3226 }
3227 #if defined(OCTOSPI2)
3228 else if (hxspi->Instance == OCTOSPI2)
3229 {
3230 LL_DLYB_GetDelay(DLYB_OCTOSPI2, pdlyb_cfg);
3231 status = HAL_OK;
3232 }
3233 #endif /* OCTOSPI2 */
3234 else
3235 {
3236 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
3237 }
3238
3239 return status;
3240 }
3241
3242 /**
3243 * @brief Get the Delay line length value.
3244 * @param hxspi : XSPI handle.
3245 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
3246 * @retval HAL status.
3247 */
HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef * hxspi,HAL_XSPI_DLYB_CfgTypeDef * const pdlyb_cfg)3248 HAL_StatusTypeDef HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg)
3249 {
3250 HAL_StatusTypeDef status = HAL_ERROR;
3251
3252 /* Enable XSPI Free Running Clock (mandatory) */
3253 SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
3254
3255 /* Update XSPI state */
3256 hxspi->State = HAL_XSPI_STATE_BUSY_CMD;
3257
3258 if (hxspi->Instance == OCTOSPI1)
3259 {
3260 /* Enable the DelayBlock */
3261 LL_DLYB_Enable(DLYB_OCTOSPI1);
3262
3263 /* try to detect Period */
3264 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI1, pdlyb_cfg) == (uint32_t)SUCCESS)
3265 {
3266 status = HAL_OK;
3267 }
3268
3269 /* Disable the DelayBlock */
3270 LL_DLYB_Disable(DLYB_OCTOSPI1);
3271 }
3272 #if defined(OCTOSPI2)
3273 else if (hxspi->Instance == OCTOSPI2)
3274 {
3275 /* Enable the DelayBlock */
3276 LL_DLYB_Enable(DLYB_OCTOSPI2);
3277
3278 /* try to detect Period */
3279 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI2, pdlyb_cfg) == (uint32_t)SUCCESS)
3280 {
3281 status = HAL_OK;
3282 }
3283
3284 /* Disable the DelayBlock */
3285 LL_DLYB_Disable(DLYB_OCTOSPI2);
3286 }
3287 #endif /* OCTOSPI2 */
3288 else
3289 {
3290 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
3291 }
3292
3293 /* Abort the current XSPI operation if exist */
3294 (void)HAL_XSPI_Abort(hxspi);
3295
3296 /* Disable Free Running Clock */
3297 CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK);
3298
3299 return status;
3300 }
3301
3302 /**
3303 * @}
3304 */
3305
3306 /** @defgroup XSPI_Exported_Functions_Group6 High-speed interface and calibration functions
3307 * @brief XSPI high-speed interface and calibration functions
3308 *
3309 @verbatim
3310 ===============================================================================
3311 ##### High-speed interface and calibration functions #####
3312 ===============================================================================
3313 [..]
3314 This subsection provides a set of functions allowing to :
3315 (+) Get the delay values of the high-speed interface DLLs.
3316 (+) Set a delay value for the high-speed interface DLLs.
3317
3318 @endverbatim
3319 * @{
3320 */
3321 #if defined(HSPI1)
3322
3323 /**
3324 * @brief Get the delay values of the high-speed interface DLLs.
3325 * @param hxspi : XSPI handle
3326 * @param pCfg : Current delay values corresponding to the DelayValueType field.
3327 * @retval HAL status
3328 */
HAL_XSPI_GetDelayValue(XSPI_HandleTypeDef * hxspi,XSPI_HSCalTypeDef * const pCfg)3329 HAL_StatusTypeDef HAL_XSPI_GetDelayValue(XSPI_HandleTypeDef *hxspi, XSPI_HSCalTypeDef *const pCfg)
3330 {
3331 HAL_StatusTypeDef status = HAL_OK;
3332 __IO uint32_t reg = 0;
3333
3334 if (IS_HSPI_ALL_INSTANCE(hxspi->Instance))
3335 {
3336 /* Check the parameter specified in the structure */
3337 assert_param(IS_XSPI_DELAY_TYPE(pCfg->DelayValueType));
3338
3339 switch (pCfg->DelayValueType)
3340 {
3341 case HAL_XSPI_CAL_FULL_CYCLE_DELAY:
3342 reg = hxspi->Instance->CALFCR;
3343 pCfg->MaxCalibration = (reg & HSPI_CALFCR_CALMAX);
3344 break;
3345 case HAL_XSPI_CAL_FEEDBACK_CLK_DELAY:
3346 reg = hxspi->Instance->CALMR;
3347 break;
3348 case HAL_XSPI_CAL_DATA_OUTPUT_DELAY:
3349 reg = hxspi->Instance->CALSOR;
3350 break;
3351 case HAL_XSPI_CAL_DQS_INPUT_DELAY:
3352 reg = hxspi->Instance->CALSIR;
3353 break;
3354 default:
3355 status = HAL_ERROR;
3356 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3357 break;
3358 }
3359
3360 if (status == HAL_OK)
3361 {
3362 pCfg->FineCalibrationUnit = (reg & HSPI_CALFCR_FINE);
3363 pCfg->CoarseCalibrationUnit = ((reg & HSPI_CALFCR_COARSE) >> HSPI_CALFCR_COARSE_Pos);
3364 }
3365 }
3366 else
3367 {
3368 status = HAL_ERROR;
3369 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3370 }
3371
3372 return status;
3373 }
3374
3375 /**
3376 * @brief Set a delay value for the high-speed interface DLLs.
3377 * @param hxspi : XSPI handle
3378 * @param pCfg : Configuration of delay value specified in DelayValueType field.
3379 * @retval HAL status
3380 */
HAL_XSPI_SetDelayValue(XSPI_HandleTypeDef * hxspi,XSPI_HSCalTypeDef * const pCfg)3381 HAL_StatusTypeDef HAL_XSPI_SetDelayValue(XSPI_HandleTypeDef *hxspi, XSPI_HSCalTypeDef *const pCfg)
3382 {
3383 HAL_StatusTypeDef status = HAL_OK;
3384
3385 if (IS_HSPI_ALL_INSTANCE(hxspi->Instance))
3386 {
3387 /* Check the parameter specified in the structure */
3388 assert_param(IS_XSPI_DELAY_TYPE(pCfg->DelayValueType));
3389 assert_param(IS_XSPI_FINECAL_VALUE(pCfg->FineCalibrationUnit));
3390 assert_param(IS_XSPI_COARSECAL_VALUE(pCfg->CoarseCalibrationUnit));
3391
3392 /* Check if the state isn't in one of the busy states */
3393 if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U)
3394 {
3395 switch (pCfg->DelayValueType)
3396 {
3397 case HAL_XSPI_CAL_FEEDBACK_CLK_DELAY:
3398 MODIFY_REG(hxspi->Instance->CALMR, (HSPI_CALMR_COARSE | HSPI_CALMR_FINE),
3399 (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << HSPI_CALMR_COARSE_Pos)));
3400 break;
3401 case HAL_XSPI_CAL_DATA_OUTPUT_DELAY:
3402 MODIFY_REG(hxspi->Instance->CALSOR, (HSPI_CALSOR_COARSE | HSPI_CALSOR_FINE),
3403 (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << HSPI_CALSOR_COARSE_Pos)));
3404 break;
3405 case HAL_XSPI_CAL_DQS_INPUT_DELAY:
3406 MODIFY_REG(hxspi->Instance->CALSIR, (HSPI_CALSIR_COARSE | HSPI_CALSIR_FINE),
3407 (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << HSPI_CALSIR_COARSE_Pos)));
3408 break;
3409 default:
3410 status = HAL_ERROR;
3411 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3412 break;
3413 }
3414 }
3415 else
3416 {
3417 status = HAL_ERROR;
3418 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE;
3419 }
3420 }
3421 else
3422 {
3423 status = HAL_ERROR;
3424 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3425 }
3426
3427 return status;
3428 }
3429
3430 #endif /* HSPI1 */
3431 /**
3432 * @}
3433 */
3434
3435 /**
3436 @cond 0
3437 */
3438 /**
3439 * @brief DMA XSPI process complete callback.
3440 * @param hdma : DMA handle
3441 * @retval None
3442 */
XSPI_DMACplt(DMA_HandleTypeDef * hdma)3443 static void XSPI_DMACplt(DMA_HandleTypeDef *hdma)
3444 {
3445 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
3446 hxspi->XferCount = 0;
3447
3448 /* Disable the DMA transfer on the XSPI side */
3449 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
3450
3451 /* Enable the XSPI transfer complete Interrupt */
3452 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
3453 }
3454
3455 /**
3456 * @brief DMA XSPI process half complete callback.
3457 * @param hdma : DMA handle
3458 * @retval None
3459 */
XSPI_DMAHalfCplt(DMA_HandleTypeDef * hdma)3460 static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
3461 {
3462 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
3463 hxspi->XferCount = (hxspi->XferCount >> 1);
3464
3465 if (hxspi->State == HAL_XSPI_STATE_BUSY_RX)
3466 {
3467 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
3468 hxspi->RxHalfCpltCallback(hxspi);
3469 #else
3470 HAL_XSPI_RxHalfCpltCallback(hxspi);
3471 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
3472 }
3473 else
3474 {
3475 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
3476 hxspi->TxHalfCpltCallback(hxspi);
3477 #else
3478 HAL_XSPI_TxHalfCpltCallback(hxspi);
3479 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
3480 }
3481 }
3482
3483 /**
3484 * @brief DMA XSPI communication error callback.
3485 * @param hdma : DMA handle
3486 * @retval None
3487 */
XSPI_DMAError(DMA_HandleTypeDef * hdma)3488 static void XSPI_DMAError(DMA_HandleTypeDef *hdma)
3489 {
3490 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
3491 hxspi->XferCount = 0;
3492 hxspi->ErrorCode = HAL_XSPI_ERROR_DMA;
3493
3494 /* Disable the DMA transfer on the XSPI side */
3495 CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN);
3496
3497 /* Abort the XSPI */
3498 if (HAL_XSPI_Abort_IT(hxspi) != HAL_OK)
3499 {
3500 /* Disable the interrupts */
3501 HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE);
3502
3503 hxspi->State = HAL_XSPI_STATE_READY;
3504
3505 /* Error callback */
3506 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
3507 hxspi->ErrorCallback(hxspi);
3508 #else
3509 HAL_XSPI_ErrorCallback(hxspi);
3510 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
3511 }
3512 }
3513
3514 /**
3515 * @brief DMA XSPI abort complete callback.
3516 * @param hdma : DMA handle
3517 * @retval None
3518 */
XSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)3519 static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
3520 {
3521 XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent);
3522 hxspi->XferCount = 0;
3523
3524 /* Check the state */
3525 if (hxspi->State == HAL_XSPI_STATE_ABORT)
3526 {
3527 /* DMA abort called by XSPI abort */
3528 if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET)
3529 {
3530 /* Clear transfer complete flag */
3531 HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC);
3532
3533 /* Enable the transfer complete interrupts */
3534 HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC);
3535
3536 /* Perform an abort of the XSPI */
3537 SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT);
3538 }
3539 else
3540 {
3541 hxspi->State = HAL_XSPI_STATE_READY;
3542
3543 /* Abort callback */
3544 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
3545 hxspi->AbortCpltCallback(hxspi);
3546 #else
3547 HAL_XSPI_AbortCpltCallback(hxspi);
3548 #endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
3549 }
3550 }
3551 else
3552 {
3553 /* DMA abort called due to a transfer error interrupt */
3554 hxspi->State = HAL_XSPI_STATE_READY;
3555
3556 /* Error callback */
3557 #if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U)
3558 hxspi->ErrorCallback(hxspi);
3559 #else
3560 HAL_XSPI_ErrorCallback(hxspi);
3561 #endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */
3562 }
3563 }
3564
3565 /**
3566 * @brief Wait for a flag state until timeout.
3567 * @param hxspi : XSPI handle
3568 * @param Flag : Flag checked
3569 * @param State : Value of the flag expected
3570 * @param Timeout : Duration of the timeout
3571 * @param Tickstart : Tick start value
3572 * @retval HAL status
3573 */
XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef * hxspi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)3574 static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag,
3575 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
3576 {
3577 /* Wait until flag is in expected state */
3578 while ((HAL_XSPI_GET_FLAG(hxspi, Flag)) != State)
3579 {
3580 /* Check for the Timeout */
3581 if (Timeout != HAL_MAX_DELAY)
3582 {
3583 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3584 {
3585 hxspi->State = HAL_XSPI_STATE_READY;
3586 hxspi->ErrorCode |= HAL_XSPI_ERROR_TIMEOUT;
3587
3588 return HAL_TIMEOUT;
3589 }
3590 }
3591 }
3592 return HAL_OK;
3593 }
3594
3595 /**
3596 * @brief Configure the registers for the regular command mode.
3597 * @param hxspi : XSPI handle
3598 * @param pCmd : structure that contains the command configuration information
3599 * @retval HAL status
3600 */
XSPI_ConfigCmd(XSPI_HandleTypeDef * hxspi,XSPI_RegularCmdTypeDef * pCmd)3601 static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *pCmd)
3602 {
3603 HAL_StatusTypeDef status = HAL_OK;
3604 __IO uint32_t *ccr_reg;
3605 __IO uint32_t *tcr_reg;
3606 __IO uint32_t *ir_reg;
3607 __IO uint32_t *abr_reg;
3608
3609 /* Re-initialize the value of the functional mode */
3610 MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U);
3611
3612 if (IS_OSPI_ALL_INSTANCE(hxspi->Instance))
3613 {
3614 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
3615 {
3616 assert_param(IS_OCTOSPI_IO_SELECT(pCmd->IOSelect));
3617 MODIFY_REG(hxspi->Instance->CR, OCTOSPI_CR_MSEL, pCmd->IOSelect);
3618 }
3619 }
3620 #if defined(HSPI1)
3621 else if (IS_HSPI_ALL_INSTANCE(hxspi->Instance))
3622 {
3623 if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM)
3624 {
3625 assert_param(IS_HSPI_IO_SELECT(pCmd->IOSelect));
3626 MODIFY_REG(hxspi->Instance->CR, HSPI_CR_MSEL, pCmd->IOSelect);
3627 }
3628 }
3629 #endif /* HSPI1 */
3630 else
3631 {
3632 hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM;
3633 return HAL_ERROR;
3634 }
3635
3636 if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
3637 {
3638 ccr_reg = &(hxspi->Instance->WCCR);
3639 tcr_reg = &(hxspi->Instance->WTCR);
3640 ir_reg = &(hxspi->Instance->WIR);
3641 abr_reg = &(hxspi->Instance->WABR);
3642 }
3643 else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG)
3644 {
3645 ccr_reg = &(hxspi->Instance->WPCCR);
3646 tcr_reg = &(hxspi->Instance->WPTCR);
3647 ir_reg = &(hxspi->Instance->WPIR);
3648 abr_reg = &(hxspi->Instance->WPABR);
3649 }
3650 else
3651 {
3652 ccr_reg = &(hxspi->Instance->CCR);
3653 tcr_reg = &(hxspi->Instance->TCR);
3654 ir_reg = &(hxspi->Instance->IR);
3655 abr_reg = &(hxspi->Instance->ABR);
3656 }
3657
3658 /* Configure the CCR register with DQS and SIOO modes */
3659 *ccr_reg = (pCmd->DQSMode | pCmd->SIOOMode);
3660
3661 /* Workaround for Erratasheet: Memory-mapped write error response when DQS output is disabled */
3662 if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG)
3663 {
3664 /* When doing memory-mapped writes, set the DQSE bit of the OCTOSPI_WCCR register,
3665 even for memories that have no DQS pin. */
3666 SET_BIT((*ccr_reg), XSPI_CCR_DQSE);
3667 }
3668
3669 if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE)
3670 {
3671 /* Configure the ABR register with alternate bytes value */
3672 *abr_reg = pCmd->AlternateBytes;
3673
3674 /* Configure the CCR register with alternate bytes communication parameters */
3675 MODIFY_REG((*ccr_reg), (XSPI_CCR_ABMODE | XSPI_CCR_ABDTR | XSPI_CCR_ABSIZE),
3676 (pCmd->AlternateBytesMode | pCmd->AlternateBytesDTRMode | pCmd->AlternateBytesWidth));
3677 }
3678
3679 /* Configure the TCR register with the number of dummy cycles */
3680 MODIFY_REG((*tcr_reg), XSPI_TCR_DCYC, pCmd->DummyCycles);
3681
3682 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3683 {
3684 if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG)
3685 {
3686 /* Configure the DLR register with the number of data */
3687 hxspi->Instance->DLR = (pCmd->DataLength - 1U);
3688 }
3689 }
3690
3691 /* Configure SSHIFT register to handle SDR/DTR data transfer */
3692 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3693 {
3694 if (pCmd->DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)
3695 {
3696 /* Deactivate sample shifting when receiving data in DTR mode (DDTR=1) */
3697 CLEAR_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT);
3698 }
3699 else if (hxspi->Init.SampleShifting == HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE)
3700 {
3701 /* Configure sample shifting */
3702 SET_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT);
3703 }
3704 else
3705 {
3706 /* Do nothing */
3707 }
3708 }
3709
3710 if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE)
3711 {
3712 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3713 {
3714 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3715 {
3716 /* ---- Command with instruction, address and data ---- */
3717
3718 /* Configure the CCR register with all communication parameters */
3719 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3720 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3721 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3722 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3723 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3724 pCmd->DataMode | pCmd->DataDTRMode));
3725 }
3726 else
3727 {
3728 /* ---- Command with instruction and address ---- */
3729
3730 /* Configure the CCR register with all communication parameters */
3731 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3732 XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3733 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3734 pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
3735
3736 /* The DHQC bit is linked with DDTR bit which should be activated */
3737 if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) &&
3738 (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE))
3739 {
3740 MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE);
3741 }
3742 }
3743 /* Configure the IR register with the instruction value */
3744 *ir_reg = pCmd->Instruction;
3745
3746 /* Configure the AR register with the address value */
3747 hxspi->Instance->AR = pCmd->Address;
3748 }
3749 else
3750 {
3751 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3752 {
3753 /* ---- Command with instruction and data ---- */
3754
3755 /* Configure the CCR register with all communication parameters */
3756 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE |
3757 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3758 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth |
3759 pCmd->DataMode | pCmd->DataDTRMode));
3760 }
3761 else
3762 {
3763 /* ---- Command with only instruction ---- */
3764
3765 /* Configure the CCR register with all communication parameters */
3766 MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE),
3767 (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth));
3768
3769 /* The DHQC bit is linked with DDTR bit which should be activated */
3770 if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) &&
3771 (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE))
3772 {
3773 MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE);
3774 }
3775 }
3776
3777 /* Configure the IR register with the instruction value */
3778 *ir_reg = pCmd->Instruction;
3779
3780 }
3781 }
3782 else
3783 {
3784 if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE)
3785 {
3786 if (pCmd->DataMode != HAL_XSPI_DATA_NONE)
3787 {
3788 /* ---- Command with address and data ---- */
3789
3790 /* Configure the CCR register with all communication parameters */
3791 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE |
3792 XSPI_CCR_DMODE | XSPI_CCR_DDTR),
3793 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth |
3794 pCmd->DataMode | pCmd->DataDTRMode));
3795 }
3796 else
3797 {
3798 /* ---- Command with only address ---- */
3799
3800 /* Configure the CCR register with all communication parameters */
3801 MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE),
3802 (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth));
3803 }
3804
3805 /* Configure the AR register with the instruction value */
3806 hxspi->Instance->AR = pCmd->Address;
3807 }
3808 else
3809 {
3810 /* ---- Invalid command configuration (no instruction, no address) ---- */
3811 status = HAL_ERROR;
3812 hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM;
3813 }
3814 }
3815
3816 return status;
3817 }
3818
3819 #if defined(OCTOSPIM)
3820 /**
3821 * @brief Get the current IOM configuration for an XSPI instance.
3822 * @param instance_nb : number of the instance
3823 * @param pCfg : configuration of the IO Manager for the instance
3824 * @retval HAL status
3825 */
XSPIM_GetConfig(uint8_t instance_nb,XSPIM_CfgTypeDef * const pCfg)3826 static void XSPIM_GetConfig(uint8_t instance_nb, XSPIM_CfgTypeDef *const pCfg)
3827 {
3828 uint32_t reg;
3829 uint32_t value = 0U;
3830 uint32_t index;
3831
3832 /* Initialize the structure */
3833 pCfg->ClkPort = 0U;
3834 pCfg->DQSPort = 0U;
3835 pCfg->NCSPort = 0U;
3836 pCfg->IOLowPort = 0U;
3837 pCfg->IOHighPort = 0U;
3838
3839 if (instance_nb == 2U)
3840 {
3841 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
3842 {
3843 value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC |
3844 OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
3845 }
3846 else
3847 {
3848 value = OCTOSPIM_PCR_NCSSRC;
3849 }
3850 }
3851
3852 /* Get the information about the instance */
3853 for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
3854 {
3855 reg = OCTOSPIM->PCR[index];
3856
3857 if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
3858 {
3859 /* The clock is enabled on this port */
3860 if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
3861 {
3862 /* The clock correspond to the instance passed as parameter */
3863 pCfg->ClkPort = index + 1U;
3864 }
3865 }
3866
3867 if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
3868 {
3869 /* The DQS is enabled on this port */
3870 if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
3871 {
3872 /* The DQS correspond to the instance passed as parameter */
3873 pCfg->DQSPort = index + 1U;
3874 }
3875 }
3876
3877 if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
3878 {
3879 /* The nCS is enabled on this port */
3880 if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
3881 {
3882 /* The nCS correspond to the instance passed as parameter */
3883 pCfg->NCSPort = index + 1U;
3884 }
3885 }
3886
3887 if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
3888 {
3889 /* The IO Low is enabled on this port */
3890 if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
3891 {
3892 /* The IO Low correspond to the instance passed as parameter */
3893 if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
3894 {
3895 pCfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3896 }
3897 else
3898 {
3899 pCfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3900 }
3901 }
3902 }
3903
3904 if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
3905 {
3906 /* The IO High is enabled on this port */
3907 if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
3908 {
3909 /* The IO High correspond to the instance passed as parameter */
3910 if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
3911 {
3912 pCfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3913 }
3914 else
3915 {
3916 pCfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3917 }
3918 }
3919 }
3920 }
3921 }
3922 #endif /* OCTOSPIM */
3923 /**
3924 @endcond
3925 */
3926
3927 /**
3928 * @}
3929 */
3930
3931 #endif /* HAL_XSPI_MODULE_ENABLED */
3932
3933 /**
3934 * @}
3935 */
3936
3937 /**
3938 * @}
3939 */
3940
3941 #endif /* HSPI || HSPI1 || HSPI2 || OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3942