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