Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_ospi.c
blobb76f8050533a0a0240b6ba2f0cf2801f83bfe31d
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
18 @verbatim
19 ===============================================================================
20 ##### How to use this driver #####
21 ===============================================================================
22 [..]
23 *** Initialization ***
24 ======================
25 [..]
26 (#) As prerequisite, fill in the HAL_OSPI_MspInit() :
27 (++) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE().
28 (++) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET().
29 (++) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
30 (++) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
31 (++) If interrupt or DMA mode is used, enable and configure OctoSPI global
32 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
33 (++) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
34 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
35 link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
36 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
37 (#) Configure the fifo threshold, the dual-quad mode, the memory type, the
38 device size, the CS high time, the free running clock, the clock mode,
39 the wrap size, the clock prescaler, the sample shifting, the hold delay
40 and the CS boundary using the HAL_OSPI_Init() function.
41 (#) When using Hyperbus, configure the RW recovery time, the access time,
42 the write latency and the latency mode unsing the HAL_OSPI_HyperbusCfg()
43 function.
45 *** Indirect functional mode ***
46 ================================
47 [..]
48 (#) In regular mode, configure the command sequence using the HAL_OSPI_Command()
49 or HAL_OSPI_Command_IT() functions :
50 (++) Instruction phase : the mode used and if present the size, the instruction
51 opcode and the DTR mode.
52 (++) Address phase : the mode used and if present the size, the address
53 value and the DTR mode.
54 (++) Alternate-bytes phase : the mode used and if present the size, the
55 alternate bytes values and the DTR mode.
56 (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
57 (++) Data phase : the mode used and if present the number of bytes and the DTR mode.
58 (++) Data strobe (DQS) mode : the activation (or not) of this mode
59 (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
60 (++) Flash identifier : in dual-quad mode, indicates which flash is concerned
61 (++) Operation type : always common configuration
62 (#) In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd()
63 function :
64 (++) Address space : indicate if the access will be done in register or memory
65 (++) Address size
66 (++) Number of data
67 (++) Data strobe (DQS) mode : the activation (or not) of this mode
68 (#) If no data is required for the command (only for regular mode, not for
69 Hyperbus mode), it is sent directly to the memory :
70 (++) In polling mode, the output of the function is done when the transfer is complete.
71 (++) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete.
72 (#) For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or
73 HAL_OSPI_Transmit_IT() after the command configuration :
74 (++) In polling mode, the output of the function is done when the transfer is complete.
75 (++) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
76 is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
77 (++) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and
78 HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
79 (#) For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or
80 HAL_OSPI_Receive_IT() after the command configuration :
81 (++) In polling mode, the output of the function is done when the transfer is complete.
82 (++) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
83 is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
84 (++) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and
85 HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
87 *** Auto-polling functional mode ***
88 ====================================
89 [..]
90 (#) Configure the command sequence by the same way than the indirect mode
91 (#) Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling()
92 or HAL_OSPI_AutoPolling_IT() functions :
93 (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
94 the polling interval and the automatic stop activation.
95 (#) After the configuration :
96 (++) In polling mode, the output of the function is done when the status match is reached. The
97 automatic stop is activated to avoid an infinite loop.
98 (++) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached.
99 *** MDMA functional mode ***
100 ====================================
101 [..]
102 (#) Configure the SourceInc and DestinationInc of MDMA paramters in the HAL_OSPI_MspInit() function :
103 (++) MDMA settings for write operation :
104 (+) The DestinationInc should be MDMA_DEST_INC_DISABLE
105 (+) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD).
106 (+) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD)
107 aligned with @ref MDMA_Source_increment_mode .
108 (+) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
109 (++) MDMA settings for read operation :
110 (+) The SourceInc should be MDMA_SRC_INC_DISABLE
111 (+) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode (Except the MDMA_DEST_INC_DOUBLEWORD).
112 (+) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) .
113 (+) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD)
114 aligned with @ref MDMA_Destination_increment_mode.
115 (++)The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Octospi.
116 (#)In case of wrong MDMA setting
117 (++) For write operation :
118 (+) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled by the HAL_OSPI_Transmit_DMA().
119 (++) For read operation :
120 (+) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled by the HAL_OSPI_Receive_DMA().
122 *** Memory-mapped functional mode ***
123 =====================================
124 [..]
125 (#) Configure the command sequence by the same way than the indirect mode except
126 for the operation type in regular mode :
127 (++) Operation type equals to read configuration : the command configuration
128 applies to read access in memory-mapped mode
129 (++) Operation type equals to write configuration : the command configuration
130 applies to write access in memory-mapped mode
131 (++) Both read and write configuration should be performed before activating
132 memory-mapped mode
133 (#) Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
134 functions :
135 (++) The timeout activation and the timeout period.
136 (#) After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
137 the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires.
139 *** Errors management and abort functionality ***
140 =================================================
141 [..]
142 (#) HAL_OSPI_GetError() function gives the error raised during the last operation.
143 (#) HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and
144 flushes the fifo :
145 (++) In polling mode, the output of the function is done when the transfer
146 complete bit is set and the busy bit cleared.
147 (++) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when
148 the transfer complete bit is set.
150 *** Control functions ***
151 =========================
152 [..]
153 (#) HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver.
154 (#) HAL_OSPI_SetTimeout() function configures the timeout value used in the driver.
155 (#) HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral.
156 (#) HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
158 *** IO manager configuration functions ***
159 ==========================================
160 [..]
161 (#) HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.
163 *** Callback registration ***
164 =============================================
165 [..]
166 The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1
167 allows the user to configure dynamically the driver callbacks.
169 Use Functions @ref HAL_OSPI_RegisterCallback() to register a user callback,
170 it allows to register following callbacks:
171 (+) ErrorCallback : callback when error occurs.
172 (+) AbortCpltCallback : callback when abort is completed.
173 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
174 (+) CmdCpltCallback : callback when a command without data is completed.
175 (+) RxCpltCallback : callback when a reception transfer is completed.
176 (+) TxCpltCallback : callback when a transmission transfer is completed.
177 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
178 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
179 (+) StatusMatchCallback : callback when a status match occurs.
180 (+) TimeOutCallback : callback when the timeout perioed expires.
181 (+) MspInitCallback : OSPI MspInit.
182 (+) MspDeInitCallback : OSPI MspDeInit.
183 This function takes as parameters the HAL peripheral handle, the Callback ID
184 and a pointer to the user callback function.
186 Use function @ref HAL_OSPI_UnRegisterCallback() to reset a callback to the default
187 weak (surcharged) function. It allows to reset following callbacks:
188 (+) ErrorCallback : callback when error occurs.
189 (+) AbortCpltCallback : callback when abort is completed.
190 (+) FifoThresholdCallback : callback when the fifo threshold is reached.
191 (+) CmdCpltCallback : callback when a command without data is completed.
192 (+) RxCpltCallback : callback when a reception transfer is completed.
193 (+) TxCpltCallback : callback when a transmission transfer is completed.
194 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
195 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
196 (+) StatusMatchCallback : callback when a status match occurs.
197 (+) TimeOutCallback : callback when the timeout perioed expires.
198 (+) MspInitCallback : OSPI MspInit.
199 (+) MspDeInitCallback : OSPI MspDeInit.
200 This function) takes as parameters the HAL peripheral handle and the Callback ID.
202 By default, after the @ref HAL_OSPI_Init and if the state is HAL_OSPI_STATE_RESET
203 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
204 Exception done for MspInit and MspDeInit callbacks that are respectively
205 reset to the legacy weak (surcharged) functions in the @ref HAL_OSPI_Init
206 and @ref HAL_OSPI_DeInit only when these callbacks are null (not registered beforehand).
207 If not, MspInit or MspDeInit are not null, the @ref HAL_OSPI_Init and @ref HAL_OSPI_DeInit
208 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
210 Callbacks can be registered/unregistered in READY state only.
211 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
212 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
213 during the Init/DeInit.
214 In that case first register the MspInit/MspDeInit user callbacks
215 using @ref HAL_OSPI_RegisterCallback before calling @ref HAL_OSPI_DeInit
216 or @ref HAL_OSPI_Init function.
218 When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or
219 not defined, the callback registering feature is not available
220 and weak (surcharged) callbacks are used.
222 @endverbatim
223 ******************************************************************************
224 * @attention
226 * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
227 * All rights reserved.</center></h2>
229 * This software component is licensed by ST under BSD 3-Clause license,
230 * the "License"; You may not use this file except in compliance with the
231 * License. You may obtain a copy of the License at:
232 * opensource.org/licenses/BSD-3-Clause
234 ******************************************************************************
237 /* Includes ------------------------------------------------------------------*/
238 #include "stm32h7xx_hal.h"
240 #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)
242 /** @addtogroup STM32H7xx_HAL_Driver
243 * @{
246 /** @defgroup OSPI OSPI
247 * @brief OSPI HAL module driver
248 * @{
251 #ifdef HAL_OSPI_MODULE_ENABLED
254 @cond 0
256 /* Private typedef -----------------------------------------------------------*/
258 /* Private define ------------------------------------------------------------*/
259 #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!< Indirect write mode */
260 #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode */
261 #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */
262 #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)OCTOSPI_CR_FMODE) /*!< Memory-mapped mode */
264 #define OSPI_CFG_STATE_MASK 0x00000004U
265 #define OSPI_BUSY_STATE_MASK 0x00000008U
267 #define OSPI_NB_INSTANCE 2U
268 #define OSPI_IOM_NB_PORTS 2U
269 #define OSPI_IOM_PORT_MASK 0x1U
271 /* Private macro -------------------------------------------------------------*/
272 #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
273 ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
274 ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
275 ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
277 /* Private variables ---------------------------------------------------------*/
279 /* Private function prototypes -----------------------------------------------*/
280 static void OSPI_DMACplt (MDMA_HandleTypeDef *hmdma);
281 static void OSPI_DMAError (MDMA_HandleTypeDef *hmdma);
282 static void OSPI_DMAAbortCplt (MDMA_HandleTypeDef *hmdma);
283 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
284 static HAL_StatusTypeDef OSPI_ConfigCmd (OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
285 static HAL_StatusTypeDef OSPIM_GetConfig (uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
287 @endcond
290 /* Exported functions --------------------------------------------------------*/
292 /** @defgroup OSPI_Exported_Functions OSPI Exported Functions
293 * @{
296 /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
297 * @brief Initialization and Configuration functions
299 @verbatim
300 ===============================================================================
301 ##### Initialization and Configuration functions #####
302 ===============================================================================
303 [..]
304 This subsection provides a set of functions allowing to :
305 (+) Initialize the OctoSPI.
306 (+) De-initialize the OctoSPI.
308 @endverbatim
309 * @{
313 * @brief Initialize the OSPI mode according to the specified parameters
314 * in the OSPI_InitTypeDef and initialize the associated handle.
315 * @param hospi : OSPI handle
316 * @retval HAL status
318 HAL_StatusTypeDef HAL_OSPI_Init (OSPI_HandleTypeDef *hospi)
320 HAL_StatusTypeDef status = HAL_OK;
321 uint32_t tickstart = HAL_GetTick();
323 /* Check the OSPI handle allocation */
324 if (hospi == NULL)
326 status = HAL_ERROR;
327 /* No error code can be set set as the handler is null */
329 else
331 /* Check the parameters of the initialization structure */
332 assert_param(IS_OSPI_FIFO_THRESHOLD (hospi->Init.FifoThreshold));
333 assert_param(IS_OSPI_DUALQUAD_MODE (hospi->Init.DualQuad));
334 assert_param(IS_OSPI_MEMORY_TYPE (hospi->Init.MemoryType));
335 assert_param(IS_OSPI_DEVICE_SIZE (hospi->Init.DeviceSize));
336 assert_param(IS_OSPI_CS_HIGH_TIME (hospi->Init.ChipSelectHighTime));
337 assert_param(IS_OSPI_FREE_RUN_CLK (hospi->Init.FreeRunningClock));
338 assert_param(IS_OSPI_CLOCK_MODE (hospi->Init.ClockMode));
339 assert_param(IS_OSPI_WRAP_SIZE (hospi->Init.WrapSize));
340 assert_param(IS_OSPI_CLK_PRESCALER (hospi->Init.ClockPrescaler));
341 assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
342 assert_param(IS_OSPI_DHQC (hospi->Init.DelayHoldQuarterCycle));
343 assert_param(IS_OSPI_CS_BOUNDARY (hospi->Init.ChipSelectBoundary));
344 assert_param(IS_OSPI_CKCSHT (hospi->Init.ClkChipSelectHighTime));
345 assert_param(IS_OSPI_DLYBYP (hospi->Init.DelayBlockBypass));
346 assert_param(IS_OSPI_MAXTRAN (hospi->Init.MaxTran));
348 /* Initialize error code */
349 hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
351 /* Check if the state is the reset state */
352 if (hospi->State == HAL_OSPI_STATE_RESET)
354 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
355 /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
356 hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
357 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
358 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
359 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
360 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
361 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
362 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
363 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
364 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
365 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
367 if(hospi->MspInitCallback == NULL)
369 hospi->MspInitCallback = HAL_OSPI_MspInit;
372 /* Init the low level hardware */
373 hospi->MspInitCallback(hospi);
374 #else
375 /* Initialization of the low level hardware */
376 HAL_OSPI_MspInit(hospi);
377 #endif
379 /* Configure the default timeout for the OSPI memory access */
380 (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
382 /* Configure memory type, device size, chip select high time, clocked chip select high time, delay block bypass, free running clock, clock mode */
383 MODIFY_REG(hospi->Instance->DCR1,
384 (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_CKCSHT |
385 OCTOSPI_DCR1_DLYBYP | OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
386 (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
387 ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
388 (hospi->Init.ClkChipSelectHighTime << OCTOSPI_DCR1_CKCSHT_Pos) |
389 hospi->Init.DelayBlockBypass | hospi->Init.ClockMode));
391 /* Configure wrap size */
392 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);
394 /* Configure chip select boundary and maximun transfer */
395 hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) | (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));
397 /* Configure refresh */
398 hospi->Instance->DCR4 = hospi->Init.Refresh;
400 /* Configure FIFO threshold */
401 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
403 /* Wait till busy flag is reset */
404 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
406 if (status == HAL_OK)
408 /* Configure clock prescaler */
409 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
411 /* Configure Dual Quad mode */
412 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
414 /* Configure sample shifting and delay hold quarter cycle */
415 MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
417 /* Enable OctoSPI */
418 __HAL_OSPI_ENABLE(hospi);
420 /* Enable free running clock if needed : must be done after OSPI enable */
421 if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
423 SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
426 /* Initialize the OSPI state */
427 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
429 hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
431 else
433 hospi->State = HAL_OSPI_STATE_READY;
439 /* Return function status */
440 return status;
444 * @brief Initialize the OSPI MSP.
445 * @param hospi : OSPI handle
446 * @retval None
448 __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
450 /* Prevent unused argument(s) compilation warning */
451 UNUSED(hospi);
453 /* NOTE : This function should not be modified, when the callback is needed,
454 the HAL_OSPI_MspInit can be implemented in the user file
459 * @brief De-Initialize the OSPI peripheral.
460 * @param hospi : OSPI handle
461 * @retval HAL status
463 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
465 HAL_StatusTypeDef status = HAL_OK;
467 /* Check the OSPI handle allocation */
468 if (hospi == NULL)
470 status = HAL_ERROR;
471 /* No error code can be set set as the handler is null */
473 else
475 /* Disable OctoSPI */
476 __HAL_OSPI_DISABLE(hospi);
478 /* Disable free running clock if needed : must be done after OSPI disable */
479 CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
481 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
482 if(hospi->MspDeInitCallback == NULL)
484 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
487 /* DeInit the low level hardware */
488 hospi->MspDeInitCallback(hospi);
489 #else
490 /* De-initialize the low-level hardware */
491 HAL_OSPI_MspDeInit(hospi);
492 #endif
494 /* Reset the driver state */
495 hospi->State = HAL_OSPI_STATE_RESET;
498 return status;
502 * @brief DeInitialize the OSPI MSP.
503 * @param hospi : OSPI handle
504 * @retval None
506 __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
508 /* Prevent unused argument(s) compilation warning */
509 UNUSED(hospi);
511 /* NOTE : This function should not be modified, when the callback is needed,
512 the HAL_OSPI_MspDeInit can be implemented in the user file
517 * @}
520 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
521 * @brief OSPI Transmit/Receive functions
523 @verbatim
524 ===============================================================================
525 ##### IO operation functions #####
526 ===============================================================================
527 [..]
528 This subsection provides a set of functions allowing to :
529 (+) Handle the interrupts.
530 (+) Handle the command sequence (regular and Hyperbus).
531 (+) Handle the Hyperbus configuration.
532 (+) Transmit data in blocking, interrupt or DMA mode.
533 (+) Receive data in blocking, interrupt or DMA mode.
534 (+) Manage the auto-polling functional mode.
535 (+) Manage the memory-mapped functional mode.
537 @endverbatim
538 * @{
542 * @brief Handle OSPI interrupt request.
543 * @param hospi : OSPI handle
544 * @retval None
546 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
548 __IO uint32_t *data_reg = &hospi->Instance->DR;
549 uint32_t flag = hospi->Instance->SR;
550 uint32_t itsource = hospi->Instance->CR;
551 uint32_t currentstate = hospi->State;
553 /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
554 if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
556 if (currentstate == HAL_OSPI_STATE_BUSY_TX)
558 /* Write a data in the fifo */
559 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
560 hospi->pBuffPtr++;
561 hospi->XferCount--;
563 else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
565 /* Read a data from the fifo */
566 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
567 hospi->pBuffPtr++;
568 hospi->XferCount--;
570 else
572 /* Nothing to do */
575 if (hospi->XferCount == 0U)
577 /* All data have been received or transmitted for the transfer */
578 /* Disable fifo threshold interrupt */
579 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
582 /* Fifo threshold callback */
583 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
584 hospi->FifoThresholdCallback(hospi);
585 #else
586 HAL_OSPI_FifoThresholdCallback(hospi);
587 #endif
589 /* OctoSPI transfer complete interrupt occurred ----------------------------*/
590 else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
592 if (currentstate == HAL_OSPI_STATE_BUSY_RX)
594 if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
596 /* Read the last data received in the fifo */
597 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
598 hospi->pBuffPtr++;
599 hospi->XferCount--;
601 else if(hospi->XferCount == 0U)
603 /* Clear flag */
604 hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
606 /* Disable the interrupts */
607 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
609 /* Update state */
610 hospi->State = HAL_OSPI_STATE_READY;
612 /* RX complete callback */
613 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
614 hospi->RxCpltCallback(hospi);
615 #else
616 HAL_OSPI_RxCpltCallback(hospi);
617 #endif
619 else
621 /* Nothing to do */
624 else
626 /* Clear flag */
627 hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
629 /* Disable the interrupts */
630 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
632 /* Update state */
633 hospi->State = HAL_OSPI_STATE_READY;
635 if (currentstate == HAL_OSPI_STATE_BUSY_TX)
637 /* TX complete callback */
638 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
639 hospi->TxCpltCallback(hospi);
640 #else
641 HAL_OSPI_TxCpltCallback(hospi);
642 #endif
644 else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
646 /* Command complete callback */
647 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
648 hospi->CmdCpltCallback(hospi);
649 #else
650 HAL_OSPI_CmdCpltCallback(hospi);
651 #endif
653 else if (currentstate == HAL_OSPI_STATE_ABORT)
655 if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
657 /* Abort called by the user */
658 /* Abort complete callback */
659 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
660 hospi->AbortCpltCallback(hospi);
661 #else
662 HAL_OSPI_AbortCpltCallback(hospi);
663 #endif
665 else
667 /* Abort due to an error (eg : DMA error) */
668 /* Error callback */
669 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
670 hospi->ErrorCallback(hospi);
671 #else
672 HAL_OSPI_ErrorCallback(hospi);
673 #endif
676 else
678 /* Nothing to do */
682 /* OctoSPI status match interrupt occurred ---------------------------------*/
683 else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
685 /* Clear flag */
686 hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
688 /* Check if automatic poll mode stop is activated */
689 if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
691 /* Disable the interrupts */
692 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
694 /* Update state */
695 hospi->State = HAL_OSPI_STATE_READY;
698 /* Status match callback */
699 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
700 hospi->StatusMatchCallback(hospi);
701 #else
702 HAL_OSPI_StatusMatchCallback(hospi);
703 #endif
705 /* OctoSPI transfer error interrupt occurred -------------------------------*/
706 else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
708 /* Clear flag */
709 hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
711 /* Disable all interrupts */
712 __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));
714 /* Set error code */
715 hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
717 /* Check if the DMA is enabled */
718 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
720 /* Disable the DMA transfer on the OctoSPI side */
721 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
723 /* Disable the DMA transfer on the DMA side */
724 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
725 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
727 /* Update state */
728 hospi->State = HAL_OSPI_STATE_READY;
730 /* Error callback */
731 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
732 hospi->ErrorCallback(hospi);
733 #else
734 HAL_OSPI_ErrorCallback(hospi);
735 #endif
738 else
740 /* Update state */
741 hospi->State = HAL_OSPI_STATE_READY;
743 /* Error callback */
744 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
745 hospi->ErrorCallback(hospi);
746 #else
747 HAL_OSPI_ErrorCallback(hospi);
748 #endif
751 /* OctoSPI timeout interrupt occurred --------------------------------------*/
752 else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
754 /* Clear flag */
755 hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
757 /* Timeout callback */
758 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
759 hospi->TimeOutCallback(hospi);
760 #else
761 HAL_OSPI_TimeOutCallback(hospi);
762 #endif
764 else
766 /* Nothing to do */
771 * @brief Set the command configuration.
772 * @param hospi : OSPI handle
773 * @param cmd : structure that contains the command configuration information
774 * @param Timeout : Timeout duration
775 * @retval HAL status
777 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
779 HAL_StatusTypeDef status;
780 uint32_t state;
781 uint32_t tickstart = HAL_GetTick();
783 /* Check the parameters of the command structure */
784 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
786 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
788 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
791 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
792 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
794 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
795 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
798 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
799 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
801 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
802 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
805 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
806 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
808 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
809 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
812 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
813 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
815 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
817 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
819 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
820 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
823 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
824 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
826 /* Check the state of the driver */
827 state = hospi->State;
828 if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
829 ((state == HAL_OSPI_STATE_READ_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) ||
830 ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))))
832 /* Wait till busy flag is reset */
833 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
835 if (status == HAL_OK)
837 /* Initialize error code */
838 hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
840 /* Configure the registers */
841 status = OSPI_ConfigCmd(hospi, cmd);
843 if (status == HAL_OK)
845 if (cmd->DataMode == HAL_OSPI_DATA_NONE)
847 /* When there is no data phase, the transfer start as soon as the configuration is done
848 so wait until TC flag is set to go back in idle state */
849 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
851 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
853 else
855 /* Update the state */
856 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
858 hospi->State = HAL_OSPI_STATE_CMD_CFG;
860 else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
862 if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
864 hospi->State = HAL_OSPI_STATE_CMD_CFG;
866 else
868 hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
871 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
873 if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
875 hospi->State = HAL_OSPI_STATE_CMD_CFG;
877 else
879 hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
882 else
884 /* Wrap configuration, no state change */
890 else
892 status = HAL_ERROR;
893 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
896 /* Return function status */
897 return status;
901 * @brief Set the command configuration in interrupt mode.
902 * @param hospi : OSPI handle
903 * @param cmd : structure that contains the command configuration information
904 * @note This function is used only in Indirect Read or Write Modes
905 * @retval HAL status
907 HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
909 HAL_StatusTypeDef status;
910 uint32_t tickstart = HAL_GetTick();
912 /* Check the parameters of the command structure */
913 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
915 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
917 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
920 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
921 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
923 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
924 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
927 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
928 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
930 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
931 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
934 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
935 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
937 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
938 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
941 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
942 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
944 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
945 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
946 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
949 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
950 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
952 /* Check the state of the driver */
953 if ((hospi->State == HAL_OSPI_STATE_READY) && (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) &&
954 (cmd->DataMode == HAL_OSPI_DATA_NONE) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
956 /* Wait till busy flag is reset */
957 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
959 if (status == HAL_OK)
961 /* Initialize error code */
962 hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
964 /* Clear flags related to interrupt */
965 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
967 /* Configure the registers */
968 status = OSPI_ConfigCmd(hospi, cmd);
970 if (status == HAL_OK)
972 /* Update the state */
973 hospi->State = HAL_OSPI_STATE_BUSY_CMD;
975 /* Enable the transfer complete and transfer error interrupts */
976 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
980 else
982 status = HAL_ERROR;
983 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
986 /* Return function status */
987 return status;
991 * @brief Configure the Hyperbus parameters.
992 * @param hospi : OSPI handle
993 * @param cfg : Structure containing the Hyperbus configuration
994 * @param Timeout : Timeout duration
995 * @retval HAL status
997 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
999 HAL_StatusTypeDef status;
1000 uint32_t state;
1001 uint32_t tickstart = HAL_GetTick();
1003 /* Check the parameters of the hyperbus configuration structure */
1004 assert_param(IS_OSPI_RW_RECOVERY_TIME (cfg->RWRecoveryTime));
1005 assert_param(IS_OSPI_ACCESS_TIME (cfg->AccessTime));
1006 assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
1007 assert_param(IS_OSPI_LATENCY_MODE (cfg->LatencyMode));
1009 /* Check the state of the driver */
1010 state = hospi->State;
1011 if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
1013 /* Wait till busy flag is reset */
1014 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1016 if (status == HAL_OK)
1018 /* Configure Hyperbus configuration Latency register */
1019 WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
1020 (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos) |
1021 cfg->WriteZeroLatency | cfg->LatencyMode));
1023 /* Update the state */
1024 hospi->State = HAL_OSPI_STATE_READY;
1027 else
1029 status = HAL_ERROR;
1030 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1033 /* Return function status */
1034 return status;
1038 * @brief Set the Hyperbus command configuration.
1039 * @param hospi : OSPI handle
1040 * @param cmd : Structure containing the Hyperbus command
1041 * @param Timeout : Timeout duration
1042 * @retval HAL status
1044 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
1046 HAL_StatusTypeDef status;
1047 uint32_t tickstart = HAL_GetTick();
1049 /* Check the parameters of the hyperbus command structure */
1050 assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
1051 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
1052 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
1053 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
1055 /* Check the state of the driver */
1056 if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
1058 /* Wait till busy flag is reset */
1059 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1061 if (status == HAL_OK)
1063 /* Re-initialize the value of the functional mode */
1064 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
1066 /* Configure the address space in the DCR1 register */
1067 MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
1069 /* Configure the CCR and WCCR registers with the address size and the following configuration :
1070 - DQS signal enabled (used as RWDS)
1071 - DTR mode enabled on address and data
1072 - address and data on 8 lines */
1073 WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
1074 cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
1075 WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
1076 cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
1078 /* Configure the DLR register with the number of data */
1079 WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
1081 /* Configure the AR register with the address value */
1082 WRITE_REG(hospi->Instance->AR, cmd->Address);
1084 /* Update the state */
1085 hospi->State = HAL_OSPI_STATE_CMD_CFG;
1088 else
1090 status = HAL_ERROR;
1091 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1094 /* Return function status */
1095 return status;
1099 * @brief Transmit an amount of data in blocking mode.
1100 * @param hospi : OSPI handle
1101 * @param pData : pointer to data buffer
1102 * @param Timeout : Timeout duration
1103 * @note This function is used only in Indirect Write Mode
1104 * @retval HAL status
1106 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1108 HAL_StatusTypeDef status;
1109 uint32_t tickstart = HAL_GetTick();
1110 __IO uint32_t *data_reg = &hospi->Instance->DR;
1112 /* Check the data pointer allocation */
1113 if (pData == NULL)
1115 status = HAL_ERROR;
1116 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1118 else
1120 /* Check the state */
1121 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1123 /* Configure counters and size */
1124 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1125 hospi->XferSize = hospi->XferCount;
1126 hospi->pBuffPtr = pData;
1128 /* Configure CR register with functional mode as indirect write */
1129 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1133 /* Wait till fifo threshold flag is set to send data */
1134 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
1136 if (status != HAL_OK)
1138 break;
1141 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
1142 hospi->pBuffPtr++;
1143 hospi->XferCount--;
1144 } while (hospi->XferCount > 0U);
1146 if (status == HAL_OK)
1148 /* Wait till transfer complete flag is set to go back in idle state */
1149 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1151 if (status == HAL_OK)
1153 /* Clear transfer complete flag */
1154 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1156 /* Update state */
1157 hospi->State = HAL_OSPI_STATE_READY;
1161 else
1163 status = HAL_ERROR;
1164 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1168 /* Return function status */
1169 return status;
1173 * @brief Receive an amount of data in blocking mode.
1174 * @param hospi : OSPI handle
1175 * @param pData : pointer to data buffer
1176 * @param Timeout : Timeout duration
1177 * @note This function is used only in Indirect Read Mode
1178 * @retval HAL status
1180 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1182 HAL_StatusTypeDef status;
1183 uint32_t tickstart = HAL_GetTick();
1184 __IO uint32_t *data_reg = &hospi->Instance->DR;
1185 uint32_t addr_reg = hospi->Instance->AR;
1186 uint32_t ir_reg = hospi->Instance->IR;
1188 /* Check the data pointer allocation */
1189 if (pData == NULL)
1191 status = HAL_ERROR;
1192 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1194 else
1196 /* Check the state */
1197 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1199 /* Configure counters and size */
1200 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1201 hospi->XferSize = hospi->XferCount;
1202 hospi->pBuffPtr = pData;
1204 /* Configure CR register with functional mode as indirect read */
1205 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1207 /* Trig the transfer by re-writing address or instruction register */
1208 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1210 WRITE_REG(hospi->Instance->AR, addr_reg);
1212 else
1214 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1216 WRITE_REG(hospi->Instance->AR, addr_reg);
1218 else
1220 WRITE_REG(hospi->Instance->IR, ir_reg);
1226 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1227 status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
1229 if (status != HAL_OK)
1231 break;
1234 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
1235 hospi->pBuffPtr++;
1236 hospi->XferCount--;
1237 } while(hospi->XferCount > 0U);
1239 if (status == HAL_OK)
1241 /* Wait till transfer complete flag is set to go back in idle state */
1242 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1244 if (status == HAL_OK)
1246 /* Clear transfer complete flag */
1247 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1249 /* Update state */
1250 hospi->State = HAL_OSPI_STATE_READY;
1254 else
1256 status = HAL_ERROR;
1257 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1261 /* Return function status */
1262 return status;
1266 * @brief Send an amount of data in non-blocking mode with interrupt.
1267 * @param hospi : OSPI handle
1268 * @param pData : pointer to data buffer
1269 * @note This function is used only in Indirect Write Mode
1270 * @retval HAL status
1272 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1274 HAL_StatusTypeDef status = HAL_OK;
1276 /* Check the data pointer allocation */
1277 if (pData == NULL)
1279 status = HAL_ERROR;
1280 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1282 else
1284 /* Check the state */
1285 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1287 /* Configure counters and size */
1288 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1289 hospi->XferSize = hospi->XferCount;
1290 hospi->pBuffPtr = pData;
1292 /* Configure CR register with functional mode as indirect write */
1293 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1295 /* Clear flags related to interrupt */
1296 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1298 /* Update the state */
1299 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1301 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1302 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1304 else
1306 status = HAL_ERROR;
1307 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1311 /* Return function status */
1312 return status;
1316 * @brief Receive an amount of data in non-blocking mode with interrupt.
1317 * @param hospi : OSPI handle
1318 * @param pData : pointer to data buffer
1319 * @note This function is used only in Indirect Read Mode
1320 * @retval HAL status
1322 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1324 HAL_StatusTypeDef status = HAL_OK;
1325 uint32_t addr_reg = hospi->Instance->AR;
1326 uint32_t ir_reg = hospi->Instance->IR;
1328 /* Check the data pointer allocation */
1329 if (pData == NULL)
1331 status = HAL_ERROR;
1332 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1334 else
1336 /* Check the state */
1337 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1339 /* Configure counters and size */
1340 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1341 hospi->XferSize = hospi->XferCount;
1342 hospi->pBuffPtr = pData;
1344 /* Configure CR register with functional mode as indirect read */
1345 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1347 /* Clear flags related to interrupt */
1348 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1350 /* Update the state */
1351 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1353 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1354 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1356 /* Trig the transfer by re-writing address or instruction register */
1357 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1359 WRITE_REG(hospi->Instance->AR, addr_reg);
1361 else
1363 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1365 WRITE_REG(hospi->Instance->AR, addr_reg);
1367 else
1369 WRITE_REG(hospi->Instance->IR, ir_reg);
1373 else
1375 status = HAL_ERROR;
1376 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1380 /* Return function status */
1381 return status;
1385 * @brief Send an amount of data in non-blocking mode with DMA.
1386 * @param hospi : OSPI handle
1387 * @param pData : pointer to data buffer
1388 * @note This function is used only in Indirect Write Mode
1389 * @note If DMA peripheral access is configured as halfword, the number
1390 * of data and the fifo threshold should be aligned on halfword
1391 * @note If DMA peripheral access is configured as word, the number
1392 * of data and the fifo threshold should be aligned on word
1393 * @retval HAL status
1395 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1397 HAL_StatusTypeDef status = HAL_OK;
1398 uint32_t data_size = hospi->Instance->DLR + 1U;
1400 /* Check the data pointer allocation */
1401 if (pData == NULL)
1403 status = HAL_ERROR;
1404 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1406 else
1408 /* Check the state */
1409 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1411 hospi->XferCount = data_size;
1414 hospi->XferSize = hospi->XferCount;
1415 hospi->pBuffPtr = pData;
1417 /* Configure CR register with functional mode as indirect write */
1418 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1420 /* Clear flags related to interrupt */
1421 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1423 /* Update the state */
1424 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1426 /* Set the MDMA transfer complete callback */
1427 hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1429 /* Set the MDMA error callback */
1430 hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1432 /* Clear the MDMA abort callback */
1433 hospi->hmdma->XferAbortCallback = NULL;
1435 /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment to disable */
1436 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE);
1438 /* Update MDMA configuration with the correct SourceInc field for Write operation */
1439 if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
1441 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE);
1443 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
1445 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD);
1447 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
1449 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD);
1451 else
1453 /* in case of incorrect source data size */
1454 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1455 status = HAL_ERROR;
1458 /* Enable the transmit MDMA Channel */
1459 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize,1) == HAL_OK)
1461 /* Enable the transfer error interrupt */
1462 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1464 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1466 else
1468 status = HAL_ERROR;
1469 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1470 hospi->State = HAL_OSPI_STATE_READY;
1474 else
1476 status = HAL_ERROR;
1477 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1481 /* Return function status */
1482 return status;
1486 * @brief Receive an amount of data in non-blocking mode with DMA.
1487 * @param hospi : OSPI handle
1488 * @param pData : pointer to data buffer.
1489 * @note This function is used only in Indirect Read Mode
1490 * @note If DMA peripheral access is configured as halfword, the number
1491 * of data and the fifo threshold should be aligned on halfword
1492 * @note If DMA peripheral access is configured as word, the number
1493 * of data and the fifo threshold should be aligned on word
1494 * @retval HAL status
1496 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1498 HAL_StatusTypeDef status = HAL_OK;
1499 uint32_t data_size = hospi->Instance->DLR + 1U;
1500 uint32_t addr_reg = hospi->Instance->AR;
1501 uint32_t ir_reg = hospi->Instance->IR;
1503 /* Check the data pointer allocation */
1504 if (pData == NULL)
1506 status = HAL_ERROR;
1507 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1509 else
1511 /* Check the state */
1512 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1514 hospi->XferCount = data_size;
1517 hospi->XferSize = hospi->XferCount;
1518 hospi->pBuffPtr = pData;
1520 /* Configure CR register with functional mode as indirect read */
1521 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1523 /* Clear flags related to interrupt */
1524 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1526 /* Update the state */
1527 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1529 /* Set the DMA transfer complete callback */
1530 hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1532 /* Set the DMA error callback */
1533 hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1535 /* Clear the DMA abort callback */
1536 hospi->hmdma->XferAbortCallback = NULL;
1538 /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
1539 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE);
1541 /* Update MDMA configuration with the correct DestinationInc field for read operation */
1542 if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
1544 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE);
1546 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
1548 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD);
1550 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
1552 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD);
1554 else
1556 /* in case of incorrect destination data size */
1557 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1558 status = HAL_ERROR;
1561 /* Enable the transmit MDMA Channel */
1562 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize, 1) == HAL_OK)
1564 /* Enable the transfer error interrupt */
1565 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1567 /* Trig the transfer by re-writing address or instruction register */
1568 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1570 WRITE_REG(hospi->Instance->AR, addr_reg);
1572 else
1574 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1576 WRITE_REG(hospi->Instance->AR, addr_reg);
1578 else
1580 WRITE_REG(hospi->Instance->IR, ir_reg);
1584 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1586 else
1588 status = HAL_ERROR;
1589 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1590 hospi->State = HAL_OSPI_STATE_READY;
1594 else
1596 status = HAL_ERROR;
1597 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1601 /* Return function status */
1602 return status;
1606 * @brief Configure the OSPI Automatic Polling Mode in blocking mode.
1607 * @param hospi : OSPI handle
1608 * @param cfg : structure that contains the polling configuration information.
1609 * @param Timeout : Timeout duration
1610 * @note This function is used only in Automatic Polling Mode
1611 * @retval HAL status
1613 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1615 HAL_StatusTypeDef status;
1616 uint32_t tickstart = HAL_GetTick();
1617 uint32_t addr_reg = hospi->Instance->AR;
1618 uint32_t ir_reg = hospi->Instance->IR;
1619 #ifdef USE_FULL_ASSERT
1620 uint32_t dlr_reg = hospi->Instance->DLR;
1621 #endif
1623 /* Check the parameters of the autopolling configuration structure */
1624 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1625 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1626 assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1627 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1629 /* Check the state */
1630 if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
1632 /* Wait till busy flag is reset */
1633 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1635 if (status == HAL_OK)
1637 /* Configure registers */
1638 WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1639 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1640 WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1641 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1642 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1644 /* Trig the transfer by re-writing address or instruction register */
1645 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1647 WRITE_REG(hospi->Instance->AR, addr_reg);
1649 else
1651 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1653 WRITE_REG(hospi->Instance->AR, addr_reg);
1655 else
1657 WRITE_REG(hospi->Instance->IR, ir_reg);
1661 /* Wait till status match flag is set to go back in idle state */
1662 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
1664 if (status == HAL_OK)
1666 /* Clear status match flag */
1667 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
1669 /* Update state */
1670 hospi->State = HAL_OSPI_STATE_READY;
1674 else
1676 status = HAL_ERROR;
1677 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1680 /* Return function status */
1681 return status;
1685 * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode.
1686 * @param hospi : OSPI handle
1687 * @param cfg : structure that contains the polling configuration information.
1688 * @note This function is used only in Automatic Polling Mode
1689 * @retval HAL status
1691 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
1693 HAL_StatusTypeDef status;
1694 uint32_t tickstart = HAL_GetTick();
1695 uint32_t addr_reg = hospi->Instance->AR;
1696 uint32_t ir_reg = hospi->Instance->IR;
1697 #ifdef USE_FULL_ASSERT
1698 uint32_t dlr_reg = hospi->Instance->DLR;
1699 #endif
1701 /* Check the parameters of the autopolling configuration structure */
1702 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1703 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1704 assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1705 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1707 /* Check the state */
1708 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1710 /* Wait till busy flag is reset */
1711 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1713 if (status == HAL_OK)
1715 /* Configure registers */
1716 WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1717 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1718 WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1719 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1720 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1722 /* Clear flags related to interrupt */
1723 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
1725 /* Update state */
1726 hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
1728 /* Enable the status match and transfer error interrupts */
1729 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
1731 /* Trig the transfer by re-writing address or instruction register */
1732 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1734 WRITE_REG(hospi->Instance->AR, addr_reg);
1736 else
1738 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1740 WRITE_REG(hospi->Instance->AR, addr_reg);
1742 else
1744 WRITE_REG(hospi->Instance->IR, ir_reg);
1749 else
1751 status = HAL_ERROR;
1752 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1755 /* Return function status */
1756 return status;
1760 * @brief Configure the Memory Mapped mode.
1761 * @param hospi : OSPI handle
1762 * @param cfg : structure that contains the memory mapped configuration information.
1763 * @note This function is used only in Memory mapped Mode
1764 * @retval HAL status
1766 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
1768 HAL_StatusTypeDef status;
1769 uint32_t tickstart = HAL_GetTick();
1771 /* Check the parameters of the memory-mapped configuration structure */
1772 assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1774 /* Check the state */
1775 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1777 /* Wait till busy flag is reset */
1778 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1780 if (status == HAL_OK)
1782 /* Update state */
1783 hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
1785 if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
1787 assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1789 /* Configure register */
1790 WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
1792 /* Clear flags related to interrupt */
1793 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
1795 /* Enable the timeout interrupt */
1796 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
1799 /* Configure CR register with functional mode as memory-mapped */
1800 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
1801 (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1804 else
1806 status = HAL_ERROR;
1807 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1810 /* Return function status */
1811 return status;
1815 * @brief Transfer Error callback.
1816 * @param hospi : OSPI handle
1817 * @retval None
1819 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
1821 /* Prevent unused argument(s) compilation warning */
1822 UNUSED(hospi);
1824 /* NOTE : This function should not be modified, when the callback is needed,
1825 the HAL_OSPI_ErrorCallback could be implemented in the user file
1830 * @brief Abort completed callback.
1831 * @param hospi : OSPI handle
1832 * @retval None
1834 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
1836 /* Prevent unused argument(s) compilation warning */
1837 UNUSED(hospi);
1839 /* NOTE: This function should not be modified, when the callback is needed,
1840 the HAL_OSPI_AbortCpltCallback could be implemented in the user file
1845 * @brief FIFO Threshold callback.
1846 * @param hospi : OSPI handle
1847 * @retval None
1849 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
1851 /* Prevent unused argument(s) compilation warning */
1852 UNUSED(hospi);
1854 /* NOTE : This function should not be modified, when the callback is needed,
1855 the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
1860 * @brief Command completed callback.
1861 * @param hospi : OSPI handle
1862 * @retval None
1864 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
1866 /* Prevent unused argument(s) compilation warning */
1867 UNUSED(hospi);
1869 /* NOTE: This function should not be modified, when the callback is needed,
1870 the HAL_OSPI_CmdCpltCallback could be implemented in the user file
1875 * @brief Rx Transfer completed callback.
1876 * @param hospi : OSPI handle
1877 * @retval None
1879 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
1881 /* Prevent unused argument(s) compilation warning */
1882 UNUSED(hospi);
1884 /* NOTE: This function should not be modified, when the callback is needed,
1885 the HAL_OSPI_RxCpltCallback could be implemented in the user file
1890 * @brief Tx Transfer completed callback.
1891 * @param hospi : OSPI handle
1892 * @retval None
1894 __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
1896 /* Prevent unused argument(s) compilation warning */
1897 UNUSED(hospi);
1899 /* NOTE: This function should not be modified, when the callback is needed,
1900 the HAL_OSPI_TxCpltCallback could be implemented in the user file
1905 * @brief Rx Half Transfer completed callback.
1906 * @param hospi : OSPI handle
1907 * @retval None
1909 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1911 /* Prevent unused argument(s) compilation warning */
1912 UNUSED(hospi);
1914 /* NOTE: This function should not be modified, when the callback is needed,
1915 the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
1920 * @brief Tx Half Transfer completed callback.
1921 * @param hospi : OSPI handle
1922 * @retval None
1924 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1926 /* Prevent unused argument(s) compilation warning */
1927 UNUSED(hospi);
1929 /* NOTE: This function should not be modified, when the callback is needed,
1930 the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
1935 * @brief Status Match callback.
1936 * @param hospi : OSPI handle
1937 * @retval None
1939 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
1941 /* Prevent unused argument(s) compilation warning */
1942 UNUSED(hospi);
1944 /* NOTE : This function should not be modified, when the callback is needed,
1945 the HAL_OSPI_StatusMatchCallback could be implemented in the user file
1950 * @brief Timeout callback.
1951 * @param hospi : OSPI handle
1952 * @retval None
1954 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
1956 /* Prevent unused argument(s) compilation warning */
1957 UNUSED(hospi);
1959 /* NOTE : This function should not be modified, when the callback is needed,
1960 the HAL_OSPI_TimeOutCallback could be implemented in the user file
1964 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
1966 * @brief Register a User OSPI Callback
1967 * To be used instead of the weak (surcharged) predefined callback
1968 * @param hospi : OSPI handle
1969 * @param CallbackID : ID of the callback to be registered
1970 * This parameter can be one of the following values:
1971 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
1972 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
1973 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
1974 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
1975 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
1976 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
1977 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
1978 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
1979 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
1980 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
1981 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
1982 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
1983 * @param pCallback : pointer to the Callback function
1984 * @retval status
1986 HAL_StatusTypeDef HAL_OSPI_RegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID, pOSPI_CallbackTypeDef pCallback)
1988 HAL_StatusTypeDef status = HAL_OK;
1990 if(pCallback == NULL)
1992 /* Update the error code */
1993 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
1994 return HAL_ERROR;
1997 if(hospi->State == HAL_OSPI_STATE_READY)
1999 switch (CallbackID)
2001 case HAL_OSPI_ERROR_CB_ID :
2002 hospi->ErrorCallback = pCallback;
2003 break;
2004 case HAL_OSPI_ABORT_CB_ID :
2005 hospi->AbortCpltCallback = pCallback;
2006 break;
2007 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2008 hospi->FifoThresholdCallback = pCallback;
2009 break;
2010 case HAL_OSPI_CMD_CPLT_CB_ID :
2011 hospi->CmdCpltCallback = pCallback;
2012 break;
2013 case HAL_OSPI_RX_CPLT_CB_ID :
2014 hospi->RxCpltCallback = pCallback;
2015 break;
2016 case HAL_OSPI_TX_CPLT_CB_ID :
2017 hospi->TxCpltCallback = pCallback;
2018 break;
2019 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2020 hospi->RxHalfCpltCallback = pCallback;
2021 break;
2022 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2023 hospi->TxHalfCpltCallback = pCallback;
2024 break;
2025 case HAL_OSPI_STATUS_MATCH_CB_ID :
2026 hospi->StatusMatchCallback = pCallback;
2027 break;
2028 case HAL_OSPI_TIMEOUT_CB_ID :
2029 hospi->TimeOutCallback = pCallback;
2030 break;
2031 case HAL_OSPI_MSP_INIT_CB_ID :
2032 hospi->MspInitCallback = pCallback;
2033 break;
2034 case HAL_OSPI_MSP_DEINIT_CB_ID :
2035 hospi->MspDeInitCallback = pCallback;
2036 break;
2037 default :
2038 /* Update the error code */
2039 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2040 /* update return status */
2041 status = HAL_ERROR;
2042 break;
2045 else if (hospi->State == HAL_OSPI_STATE_RESET)
2047 switch (CallbackID)
2049 case HAL_OSPI_MSP_INIT_CB_ID :
2050 hospi->MspInitCallback = pCallback;
2051 break;
2052 case HAL_OSPI_MSP_DEINIT_CB_ID :
2053 hospi->MspDeInitCallback = pCallback;
2054 break;
2055 default :
2056 /* Update the error code */
2057 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2058 /* update return status */
2059 status = HAL_ERROR;
2060 break;
2063 else
2065 /* Update the error code */
2066 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2067 /* update return status */
2068 status = HAL_ERROR;
2071 return status;
2075 * @brief Unregister a User OSPI Callback
2076 * OSPI Callback is redirected to the weak (surcharged) predefined callback
2077 * @param hospi : OSPI handle
2078 * @param CallbackID : ID of the callback to be unregistered
2079 * This parameter can be one of the following values:
2080 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
2081 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
2082 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2083 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
2084 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
2085 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
2086 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
2087 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
2088 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
2089 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
2090 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
2091 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
2092 * @retval status
2094 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
2096 HAL_StatusTypeDef status = HAL_OK;
2098 if(hospi->State == HAL_OSPI_STATE_READY)
2100 switch (CallbackID)
2102 case HAL_OSPI_ERROR_CB_ID :
2103 hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
2104 break;
2105 case HAL_OSPI_ABORT_CB_ID :
2106 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
2107 break;
2108 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2109 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
2110 break;
2111 case HAL_OSPI_CMD_CPLT_CB_ID :
2112 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
2113 break;
2114 case HAL_OSPI_RX_CPLT_CB_ID :
2115 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
2116 break;
2117 case HAL_OSPI_TX_CPLT_CB_ID :
2118 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
2119 break;
2120 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2121 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
2122 break;
2123 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2124 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
2125 break;
2126 case HAL_OSPI_STATUS_MATCH_CB_ID :
2127 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
2128 break;
2129 case HAL_OSPI_TIMEOUT_CB_ID :
2130 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
2131 break;
2132 case HAL_OSPI_MSP_INIT_CB_ID :
2133 hospi->MspInitCallback = HAL_OSPI_MspInit;
2134 break;
2135 case HAL_OSPI_MSP_DEINIT_CB_ID :
2136 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2137 break;
2138 default :
2139 /* Update the error code */
2140 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2141 /* update return status */
2142 status = HAL_ERROR;
2143 break;
2146 else if (hospi->State == HAL_OSPI_STATE_RESET)
2148 switch (CallbackID)
2150 case HAL_OSPI_MSP_INIT_CB_ID :
2151 hospi->MspInitCallback = HAL_OSPI_MspInit;
2152 break;
2153 case HAL_OSPI_MSP_DEINIT_CB_ID :
2154 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2155 break;
2156 default :
2157 /* Update the error code */
2158 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2159 /* update return status */
2160 status = HAL_ERROR;
2161 break;
2164 else
2166 /* Update the error code */
2167 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2168 /* update return status */
2169 status = HAL_ERROR;
2172 return status;
2174 #endif
2177 * @}
2180 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
2181 * @brief OSPI control and State functions
2183 @verbatim
2184 ===============================================================================
2185 ##### Peripheral Control and State functions #####
2186 ===============================================================================
2187 [..]
2188 This subsection provides a set of functions allowing to :
2189 (+) Check in run-time the state of the driver.
2190 (+) Check the error code set during last operation.
2191 (+) Abort any operation.
2192 (+) Manage the Fifo threshold.
2193 (+) Configure the timeout duration used in the driver.
2195 @endverbatim
2196 * @{
2200 * @brief Abort the current transmission.
2201 * @param hospi : OSPI handle
2202 * @retval HAL status
2204 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
2206 HAL_StatusTypeDef status = HAL_OK;
2207 uint32_t state;
2208 uint32_t tickstart = HAL_GetTick();
2210 /* Check if the state is in one of the busy or configured states */
2211 state = hospi->State;
2212 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2214 /* Check if the DMA is enabled */
2215 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2217 /* Disable the DMA transfer on the OctoSPI side */
2218 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2220 /* Disable the DMA transfer on the DMA side */
2221 status = HAL_MDMA_Abort(hospi->hmdma);
2222 if (status != HAL_OK)
2224 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2228 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2230 /* Perform an abort of the OctoSPI */
2231 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2233 /* Wait until the transfer complete flag is set to go back in idle state */
2234 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
2236 if (status == HAL_OK)
2238 /* Clear transfer complete flag */
2239 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2241 /* Wait until the busy flag is reset to go back in idle state */
2242 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
2244 if (status == HAL_OK)
2246 /* Update state */
2247 hospi->State = HAL_OSPI_STATE_READY;
2251 else
2253 /* Update state */
2254 hospi->State = HAL_OSPI_STATE_READY;
2257 else
2259 status = HAL_ERROR;
2260 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2263 /* Return function status */
2264 return status;
2268 * @brief Abort the current transmission (non-blocking function)
2269 * @param hospi : OSPI handle
2270 * @retval HAL status
2272 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
2274 HAL_StatusTypeDef status = HAL_OK;
2275 uint32_t state;
2277 /* Check if the state is in one of the busy or configured states */
2278 state = hospi->State;
2279 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2281 /* Disable all interrupts */
2282 __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));
2284 /* Update state */
2285 hospi->State = HAL_OSPI_STATE_ABORT;
2287 /* Check if the DMA is enabled */
2288 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2290 /* Disable the DMA transfer on the OctoSPI side */
2291 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2293 /* Disable the DMA transfer on the DMA side */
2294 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
2295 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
2297 /* Update state */
2298 hospi->State = HAL_OSPI_STATE_READY;
2300 /* Abort callback */
2301 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2302 hospi->AbortCpltCallback(hospi);
2303 #else
2304 HAL_OSPI_AbortCpltCallback(hospi);
2305 #endif
2308 else
2310 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2312 /* Clear transfer complete flag */
2313 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2315 /* Enable the transfer complete interrupts */
2316 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2318 /* Perform an abort of the OctoSPI */
2319 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2321 else
2323 /* Update state */
2324 hospi->State = HAL_OSPI_STATE_READY;
2326 /* Abort callback */
2327 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2328 hospi->AbortCpltCallback(hospi);
2329 #else
2330 HAL_OSPI_AbortCpltCallback(hospi);
2331 #endif
2335 else
2337 status = HAL_ERROR;
2338 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2341 /* Return function status */
2342 return status;
2345 /** @brief Set OSPI Fifo threshold.
2346 * @param hospi : OSPI handle.
2347 * @param Threshold : Threshold of the Fifo.
2348 * @retval HAL status
2350 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
2352 HAL_StatusTypeDef status = HAL_OK;
2354 /* Check the state */
2355 if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
2357 /* Synchronize initialization structure with the new fifo threshold value */
2358 hospi->Init.FifoThreshold = Threshold;
2360 /* Configure new fifo threshold */
2361 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos));
2364 else
2366 status = HAL_ERROR;
2367 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2370 /* Return function status */
2371 return status;
2374 /** @brief Get OSPI Fifo threshold.
2375 * @param hospi : OSPI handle.
2376 * @retval Fifo threshold
2378 uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef *hospi)
2380 return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
2383 /** @brief Set OSPI timeout.
2384 * @param hospi : OSPI handle.
2385 * @param Timeout : Timeout for the memory access.
2386 * @retval None
2388 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
2390 hospi->Timeout = Timeout;
2391 return HAL_OK;
2395 * @brief Return the OSPI error code.
2396 * @param hospi : OSPI handle
2397 * @retval OSPI Error Code
2399 uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef *hospi)
2401 return hospi->ErrorCode;
2405 * @brief Return the OSPI handle state.
2406 * @param hospi : OSPI handle
2407 * @retval HAL state
2409 uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef *hospi)
2411 /* Return OSPI handle state */
2412 return hospi->State;
2416 * @}
2419 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
2420 * @brief OSPI IO Manager configuration function
2422 @verbatim
2423 ===============================================================================
2424 ##### IO Manager configuration function #####
2425 ===============================================================================
2426 [..]
2427 This subsection provides a set of functions allowing to :
2428 (+) Configure the IO manager.
2430 @endverbatim
2431 * @{
2435 * @brief Configure the OctoSPI IO manager.
2436 * @param hospi : OSPI handle
2437 * @param cfg : Configuration of the IO Manager for the instance
2438 * @param Timeout : Timeout duration
2439 * @retval HAL status
2441 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
2443 HAL_StatusTypeDef status = HAL_OK;
2444 uint32_t instance;
2445 uint8_t index, ospi_enabled = 0U, other_instance;
2446 OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2448 /* Prevent unused argument(s) compilation warning */
2449 UNUSED(Timeout);
2451 /* Check the parameters of the OctoSPI IO Manager configuration structure */
2452 assert_param(IS_OSPIM_PORT(cfg->ClkPort));
2453 assert_param(IS_OSPIM_PORT(cfg->DQSPort));
2454 assert_param(IS_OSPIM_PORT(cfg->NCSPort));
2455 assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
2456 assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
2457 assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime));
2459 if (hospi->Instance == OCTOSPI1)
2461 instance = 0U;
2462 other_instance = 1U;
2464 else
2466 instance = 1U;
2467 other_instance = 0U;
2470 /**************** Get current configuration of the instances ****************/
2471 for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2473 if (OSPIM_GetConfig(index+1U, &(IOM_cfg[index])) != HAL_OK)
2475 status = HAL_ERROR;
2476 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2480 if (status == HAL_OK)
2482 /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2483 if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
2485 CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2486 ospi_enabled |= 0x1U;
2488 if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
2490 CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2491 ospi_enabled |= 0x2U;
2494 /***************** Deactivation of previous configuration *****************/
2495 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2496 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2498 /* De-multiplexing should be performed */
2499 CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2501 if (other_instance == 1U)
2503 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKSRC);
2504 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSSRC);
2505 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLSRC_1);
2506 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHSRC_1);
2509 else
2511 if (IOM_cfg[instance].ClkPort != 0U)
2513 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2514 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2515 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2516 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2520 /********************* Deactivation of other instance *********************/
2521 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) ||
2522 (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
2523 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2525 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) && (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) &&
2526 (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) && (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2528 /* Multiplexing should be performed */
2529 SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2531 else
2533 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2534 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2535 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2536 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2537 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2541 /******************** Activation of new configuration *********************/
2542 MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
2544 if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
2546 MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
2549 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2551 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
2552 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
2554 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2556 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
2558 else
2560 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
2563 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2565 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
2567 else
2569 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
2572 else
2574 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
2575 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
2577 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2579 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2580 (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2582 else
2584 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2585 (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2588 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2590 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2591 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2593 else
2595 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2596 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2600 /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2601 if ((ospi_enabled & 0x1U) != 0U)
2603 SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2605 if ((ospi_enabled & 0x2U) != 0U)
2607 SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2611 /* Return function status */
2612 return status;
2616 * @}
2620 @cond 0
2623 * @brief DMA OSPI process complete callback.
2624 * @param hdma : DMA handle
2625 * @retval None
2627 static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma)
2629 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2630 hospi->XferCount = 0;
2632 /* Disable the DMA transfer on the OctoSPI side */
2633 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2635 /* Disable the DMA channel */
2636 __HAL_MDMA_DISABLE(hmdma);
2638 /* Enable the OSPI transfer complete Interrupt */
2639 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2643 * @brief DMA OSPI communication error callback.
2644 * @param hdma : DMA handle
2645 * @retval None
2647 static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2649 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2650 hospi->XferCount = 0;
2651 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2653 /* Disable the DMA transfer on the OctoSPI side */
2654 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2656 /* Abort the OctoSPI */
2657 if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
2659 /* Disable the interrupts */
2660 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
2662 /* Update state */
2663 hospi->State = HAL_OSPI_STATE_READY;
2665 /* Error callback */
2666 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2667 hospi->ErrorCallback(hospi);
2668 #else
2669 HAL_OSPI_ErrorCallback(hospi);
2670 #endif
2675 * @brief DMA OSPI abort complete callback.
2676 * @param hdma : DMA handle
2677 * @retval None
2679 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2681 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2682 hospi->XferCount = 0;
2684 /* Check the state */
2685 if (hospi->State == HAL_OSPI_STATE_ABORT)
2687 /* DMA abort called by OctoSPI abort */
2688 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2690 /* Clear transfer complete flag */
2691 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2693 /* Enable the transfer complete interrupts */
2694 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2696 /* Perform an abort of the OctoSPI */
2697 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2699 else
2701 /* Update state */
2702 hospi->State = HAL_OSPI_STATE_READY;
2704 /* Abort callback */
2705 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2706 hospi->AbortCpltCallback(hospi);
2707 #else
2708 HAL_OSPI_AbortCpltCallback(hospi);
2709 #endif
2712 else
2714 /* DMA abort called due to a transfer error interrupt */
2715 /* Update state */
2716 hospi->State = HAL_OSPI_STATE_READY;
2718 /* Error callback */
2719 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2720 hospi->ErrorCallback(hospi);
2721 #else
2722 HAL_OSPI_ErrorCallback(hospi);
2723 #endif
2728 * @brief Wait for a flag state until timeout.
2729 * @param hospi : OSPI handle
2730 * @param Flag : Flag checked
2731 * @param State : Value of the flag expected
2732 * @param Timeout : Duration of the timeout
2733 * @param Tickstart : Tick start value
2734 * @retval HAL status
2736 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
2737 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2739 /* Wait until flag is in expected state */
2740 while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
2742 /* Check for the Timeout */
2743 if (Timeout != HAL_MAX_DELAY)
2745 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2747 hospi->State = HAL_OSPI_STATE_ERROR;
2748 hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
2750 return HAL_ERROR;
2754 return HAL_OK;
2758 * @brief Configure the registers for the regular command mode.
2759 * @param hospi : OSPI handle
2760 * @param cmd : structure that contains the command configuration information
2761 * @retval HAL status
2763 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
2765 HAL_StatusTypeDef status = HAL_OK;
2766 __IO uint32_t *ccr_reg, *tcr_reg, *ir_reg, *abr_reg;
2768 /* Re-initialize the value of the functional mode */
2769 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
2771 /* Configure the flash ID */
2772 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
2774 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
2777 if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
2779 ccr_reg = &(hospi->Instance->WCCR);
2780 tcr_reg = &(hospi->Instance->WTCR);
2781 ir_reg = &(hospi->Instance->WIR);
2782 abr_reg = &(hospi->Instance->WABR);
2784 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
2786 ccr_reg = &(hospi->Instance->WPCCR);
2787 tcr_reg = &(hospi->Instance->WPTCR);
2788 ir_reg = &(hospi->Instance->WPIR);
2789 abr_reg = &(hospi->Instance->WPABR);
2791 else
2793 ccr_reg = &(hospi->Instance->CCR);
2794 tcr_reg = &(hospi->Instance->TCR);
2795 ir_reg = &(hospi->Instance->IR);
2796 abr_reg = &(hospi->Instance->ABR);
2799 /* Configure the CCR register with DQS and SIOO modes */
2800 *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
2802 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
2804 /* Configure the ABR register with alternate bytes value */
2805 *abr_reg = cmd->AlternateBytes;
2807 /* Configure the CCR register with alternate bytes communication parameters */
2808 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
2809 (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
2812 /* Configure the TCR register with the number of dummy cycles */
2813 MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
2815 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2817 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
2819 /* Configure the DLR register with the number of data */
2820 hospi->Instance->DLR = (cmd->NbData - 1U);
2824 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
2826 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2828 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2830 /* ---- Command with instruction, address and data ---- */
2832 /* Configure the CCR register with all communication parameters */
2833 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2834 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2835 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2836 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2837 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2838 cmd->DataMode | cmd->DataDtrMode));
2840 else
2842 /* ---- Command with instruction and address ---- */
2844 /* Configure the CCR register with all communication parameters */
2845 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2846 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2847 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2848 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2850 /* The DHQC bit is linked with DDTR bit which should be activated */
2851 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2852 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2854 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2858 /* Configure the IR register with the instruction value */
2859 *ir_reg = cmd->Instruction;
2861 /* Configure the AR register with the address value */
2862 hospi->Instance->AR = cmd->Address;
2864 else
2866 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2868 /* ---- Command with instruction and data ---- */
2870 /* Configure the CCR register with all communication parameters */
2871 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2872 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2873 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2874 cmd->DataMode | cmd->DataDtrMode));
2876 else
2878 /* ---- Command with only instruction ---- */
2880 /* Configure the CCR register with all communication parameters */
2881 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
2882 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
2884 /* The DHQC bit is linked with DDTR bit which should be activated */
2885 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2886 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2888 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2892 /* Configure the IR register with the instruction value */
2893 *ir_reg = cmd->Instruction;
2897 else
2899 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2901 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2903 /* ---- Command with address and data ---- */
2905 /* Configure the CCR register with all communication parameters */
2906 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2907 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2908 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2909 cmd->DataMode | cmd->DataDtrMode));
2911 else
2913 /* ---- Command with only address ---- */
2915 /* Configure the CCR register with all communication parameters */
2916 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2917 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2920 /* Configure the AR register with the instruction value */
2921 hospi->Instance->AR = cmd->Address;
2923 else
2925 /* ---- Invalid command configuration (no instruction, no address) ---- */
2926 status = HAL_ERROR;
2927 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2931 /* Return function status */
2932 return status;
2936 * @brief Get the current IOM configuration for an OctoSPI instance.
2937 * @param instance_nb : number of the instance
2938 * @param cfg : configuration of the IO Manager for the instance
2939 * @retval HAL status
2941 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
2943 HAL_StatusTypeDef status = HAL_OK;
2944 uint32_t reg, value = 0U;
2945 uint32_t index;
2947 if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
2949 /* Invalid parameter -> error returned */
2950 status = HAL_ERROR;
2952 else
2954 /* Initialize the structure */
2955 cfg->ClkPort = 0U;
2956 cfg->DQSPort = 0U;
2957 cfg->NCSPort = 0U;
2958 cfg->IOLowPort = 0U;
2959 cfg->IOHighPort = 0U;
2961 if (instance_nb == 2U)
2963 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
2965 value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
2967 else
2969 value = OCTOSPIM_PCR_NCSSRC;
2973 /* Get the information about the instance */
2974 for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
2976 reg = OCTOSPIM->PCR[index];
2978 if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
2980 /* The clock is enabled on this port */
2981 if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
2983 /* The clock correspond to the instance passed as parameter */
2984 cfg->ClkPort = index+1U;
2988 if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
2990 /* The DQS is enabled on this port */
2991 if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
2993 /* The DQS correspond to the instance passed as parameter */
2994 cfg->DQSPort = index+1U;
2998 if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
3000 /* The nCS is enabled on this port */
3001 if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
3003 /* The nCS correspond to the instance passed as parameter */
3004 cfg->NCSPort = index+1U;
3008 if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
3010 /* The IO Low is enabled on this port */
3011 if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
3013 /* The IO Low correspond to the instance passed as parameter */
3014 if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
3016 cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
3018 else
3020 cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
3025 if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
3027 /* The IO High is enabled on this port */
3028 if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
3030 /* The IO High correspond to the instance passed as parameter */
3031 if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
3033 cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
3035 else
3037 cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
3044 /* Return function status */
3045 return status;
3049 @endcond
3053 * @}
3056 #endif /* HAL_OSPI_MODULE_ENABLED */
3059 * @}
3063 * @}
3066 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3068 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/