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