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