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