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