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