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