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