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