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