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