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