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