Set blackbox file handler to NULL after closing file
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_ospi.c
blob0a8e4807053af4aad2d5d17d138431e8b2d0ff66
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 status = HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
383 if (status == HAL_OK)
385 /* Configure memory type, device size, chip select high time, clocked chip select high time, delay block bypass, free running clock, clock mode */
386 MODIFY_REG(hospi->Instance->DCR1,
387 (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_CKCSHT |
388 OCTOSPI_DCR1_DLYBYP | OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
389 (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
390 ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
391 (hospi->Init.ClkChipSelectHighTime << OCTOSPI_DCR1_CKCSHT_Pos) |
392 hospi->Init.DelayBlockBypass | hospi->Init.ClockMode));
394 /* Configure wrap size */
395 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);
397 /* Configure chip select boundary and maximun transfer */
398 hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) | (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));
400 /* Configure refresh */
401 hospi->Instance->DCR4 = hospi->Init.Refresh;
403 /* Configure FIFO threshold */
404 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
406 /* Wait till busy flag is reset */
407 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
409 if (status == HAL_OK)
411 /* Configure clock prescaler */
412 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
414 /* Configure Dual Quad mode */
415 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
417 /* Configure sample shifting and delay hold quarter cycle */
418 MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
420 /* Enable OctoSPI */
421 __HAL_OSPI_ENABLE(hospi);
423 /* Enable free running clock if needed : must be done after OSPI enable */
424 if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
426 SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
429 /* Initialize the OSPI state */
430 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
432 hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
434 else
436 hospi->State = HAL_OSPI_STATE_READY;
442 /* Return function status */
443 return status;
447 * @brief Initialize the OSPI MSP.
448 * @param hospi : OSPI handle
449 * @retval None
451 __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
453 /* Prevent unused argument(s) compilation warning */
454 UNUSED(hospi);
456 /* NOTE : This function should not be modified, when the callback is needed,
457 the HAL_OSPI_MspInit can be implemented in the user file
462 * @brief De-Initialize the OSPI peripheral.
463 * @param hospi : OSPI handle
464 * @retval HAL status
466 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
468 HAL_StatusTypeDef status = HAL_OK;
470 /* Check the OSPI handle allocation */
471 if (hospi == NULL)
473 status = HAL_ERROR;
474 /* No error code can be set set as the handler is null */
476 else
478 /* Disable OctoSPI */
479 __HAL_OSPI_DISABLE(hospi);
481 /* Disable free running clock if needed : must be done after OSPI disable */
482 CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
484 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
485 if(hospi->MspDeInitCallback == NULL)
487 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
490 /* DeInit the low level hardware */
491 hospi->MspDeInitCallback(hospi);
492 #else
493 /* De-initialize the low-level hardware */
494 HAL_OSPI_MspDeInit(hospi);
495 #endif
497 /* Reset the driver state */
498 hospi->State = HAL_OSPI_STATE_RESET;
501 return status;
505 * @brief DeInitialize the OSPI MSP.
506 * @param hospi : OSPI handle
507 * @retval None
509 __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
511 /* Prevent unused argument(s) compilation warning */
512 UNUSED(hospi);
514 /* NOTE : This function should not be modified, when the callback is needed,
515 the HAL_OSPI_MspDeInit can be implemented in the user file
520 * @}
523 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
524 * @brief OSPI Transmit/Receive functions
526 @verbatim
527 ===============================================================================
528 ##### IO operation functions #####
529 ===============================================================================
530 [..]
531 This subsection provides a set of functions allowing to :
532 (+) Handle the interrupts.
533 (+) Handle the command sequence (regular and Hyperbus).
534 (+) Handle the Hyperbus configuration.
535 (+) Transmit data in blocking, interrupt or DMA mode.
536 (+) Receive data in blocking, interrupt or DMA mode.
537 (+) Manage the auto-polling functional mode.
538 (+) Manage the memory-mapped functional mode.
540 @endverbatim
541 * @{
545 * @brief Handle OSPI interrupt request.
546 * @param hospi : OSPI handle
547 * @retval None
549 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
551 __IO uint32_t *data_reg = &hospi->Instance->DR;
552 uint32_t flag = hospi->Instance->SR;
553 uint32_t itsource = hospi->Instance->CR;
554 uint32_t currentstate = hospi->State;
556 /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
557 if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
559 if (currentstate == HAL_OSPI_STATE_BUSY_TX)
561 /* Write a data in the fifo */
562 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
563 hospi->pBuffPtr++;
564 hospi->XferCount--;
566 else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
568 /* Read a data from the fifo */
569 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
570 hospi->pBuffPtr++;
571 hospi->XferCount--;
573 else
575 /* Nothing to do */
578 if (hospi->XferCount == 0U)
580 /* All data have been received or transmitted for the transfer */
581 /* Disable fifo threshold interrupt */
582 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
585 /* Fifo threshold callback */
586 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
587 hospi->FifoThresholdCallback(hospi);
588 #else
589 HAL_OSPI_FifoThresholdCallback(hospi);
590 #endif
592 /* OctoSPI transfer complete interrupt occurred ----------------------------*/
593 else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
595 if (currentstate == HAL_OSPI_STATE_BUSY_RX)
597 if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
599 /* Read the last data received in the fifo */
600 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
601 hospi->pBuffPtr++;
602 hospi->XferCount--;
604 else if(hospi->XferCount == 0U)
606 /* Clear flag */
607 hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
609 /* Disable the interrupts */
610 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
612 /* Update state */
613 hospi->State = HAL_OSPI_STATE_READY;
615 /* RX complete callback */
616 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
617 hospi->RxCpltCallback(hospi);
618 #else
619 HAL_OSPI_RxCpltCallback(hospi);
620 #endif
622 else
624 /* Nothing to do */
627 else
629 /* Clear flag */
630 hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
632 /* Disable the interrupts */
633 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
635 /* Update state */
636 hospi->State = HAL_OSPI_STATE_READY;
638 if (currentstate == HAL_OSPI_STATE_BUSY_TX)
640 /* TX complete callback */
641 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
642 hospi->TxCpltCallback(hospi);
643 #else
644 HAL_OSPI_TxCpltCallback(hospi);
645 #endif
647 else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
649 /* Command complete callback */
650 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
651 hospi->CmdCpltCallback(hospi);
652 #else
653 HAL_OSPI_CmdCpltCallback(hospi);
654 #endif
656 else if (currentstate == HAL_OSPI_STATE_ABORT)
658 if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
660 /* Abort called by the user */
661 /* Abort complete callback */
662 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
663 hospi->AbortCpltCallback(hospi);
664 #else
665 HAL_OSPI_AbortCpltCallback(hospi);
666 #endif
668 else
670 /* Abort due to an error (eg : DMA error) */
671 /* Error callback */
672 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
673 hospi->ErrorCallback(hospi);
674 #else
675 HAL_OSPI_ErrorCallback(hospi);
676 #endif
679 else
681 /* Nothing to do */
685 /* OctoSPI status match interrupt occurred ---------------------------------*/
686 else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
688 /* Clear flag */
689 hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
691 /* Check if automatic poll mode stop is activated */
692 if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
694 /* Disable the interrupts */
695 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
697 /* Update state */
698 hospi->State = HAL_OSPI_STATE_READY;
701 /* Status match callback */
702 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
703 hospi->StatusMatchCallback(hospi);
704 #else
705 HAL_OSPI_StatusMatchCallback(hospi);
706 #endif
708 /* OctoSPI transfer error interrupt occurred -------------------------------*/
709 else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
711 /* Clear flag */
712 hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
714 /* Disable all interrupts */
715 __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));
717 /* Set error code */
718 hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
720 /* Check if the DMA is enabled */
721 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
723 /* Disable the DMA transfer on the OctoSPI side */
724 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
726 /* Disable the DMA transfer on the DMA side */
727 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
728 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
730 /* Update state */
731 hospi->State = HAL_OSPI_STATE_READY;
733 /* Error callback */
734 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
735 hospi->ErrorCallback(hospi);
736 #else
737 HAL_OSPI_ErrorCallback(hospi);
738 #endif
741 else
743 /* Update state */
744 hospi->State = HAL_OSPI_STATE_READY;
746 /* Error callback */
747 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
748 hospi->ErrorCallback(hospi);
749 #else
750 HAL_OSPI_ErrorCallback(hospi);
751 #endif
754 /* OctoSPI timeout interrupt occurred --------------------------------------*/
755 else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
757 /* Clear flag */
758 hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
760 /* Timeout callback */
761 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
762 hospi->TimeOutCallback(hospi);
763 #else
764 HAL_OSPI_TimeOutCallback(hospi);
765 #endif
767 else
769 /* Nothing to do */
774 * @brief Set the command configuration.
775 * @param hospi : OSPI handle
776 * @param cmd : structure that contains the command configuration information
777 * @param Timeout : Timeout duration
778 * @retval HAL status
780 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
782 HAL_StatusTypeDef status;
783 uint32_t state;
784 uint32_t tickstart = HAL_GetTick();
786 /* Check the parameters of the command structure */
787 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
789 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
791 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
794 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
795 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
797 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
798 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
801 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
802 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
804 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
805 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
808 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
809 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
811 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
812 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
815 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
816 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
818 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
820 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
822 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
823 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
826 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
827 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
829 /* Check the state of the driver */
830 state = hospi->State;
831 if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
832 ((state == HAL_OSPI_STATE_READ_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) ||
833 ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))))
835 /* Wait till busy flag is reset */
836 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
838 if (status == HAL_OK)
840 /* Initialize error code */
841 hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
843 /* Configure the registers */
844 status = OSPI_ConfigCmd(hospi, cmd);
846 if (status == HAL_OK)
848 if (cmd->DataMode == HAL_OSPI_DATA_NONE)
850 /* When there is no data phase, the transfer start as soon as the configuration is done
851 so wait until TC flag is set to go back in idle state */
852 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
854 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
856 else
858 /* Update the state */
859 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
861 hospi->State = HAL_OSPI_STATE_CMD_CFG;
863 else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
865 if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
867 hospi->State = HAL_OSPI_STATE_CMD_CFG;
869 else
871 hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
874 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
876 if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
878 hospi->State = HAL_OSPI_STATE_CMD_CFG;
880 else
882 hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
885 else
887 /* Wrap configuration, no state change */
893 else
895 status = HAL_ERROR;
896 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
899 /* Return function status */
900 return status;
904 * @brief Set the command configuration in interrupt mode.
905 * @param hospi : OSPI handle
906 * @param cmd : structure that contains the command configuration information
907 * @note This function is used only in Indirect Read or Write Modes
908 * @retval HAL status
910 HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
912 HAL_StatusTypeDef status;
913 uint32_t tickstart = HAL_GetTick();
915 /* Check the parameters of the command structure */
916 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
918 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
920 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
923 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
924 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
926 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
927 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
930 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
931 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
933 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
934 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
937 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
938 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
940 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
941 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
944 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
945 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
947 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
948 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
949 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
952 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
953 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
955 /* Check the state of the driver */
956 if ((hospi->State == HAL_OSPI_STATE_READY) && (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) &&
957 (cmd->DataMode == HAL_OSPI_DATA_NONE) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
959 /* Wait till busy flag is reset */
960 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
962 if (status == HAL_OK)
964 /* Initialize error code */
965 hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
967 /* Clear flags related to interrupt */
968 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
970 /* Configure the registers */
971 status = OSPI_ConfigCmd(hospi, cmd);
973 if (status == HAL_OK)
975 /* Update the state */
976 hospi->State = HAL_OSPI_STATE_BUSY_CMD;
978 /* Enable the transfer complete and transfer error interrupts */
979 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
983 else
985 status = HAL_ERROR;
986 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
989 /* Return function status */
990 return status;
994 * @brief Configure the Hyperbus parameters.
995 * @param hospi : OSPI handle
996 * @param cfg : Structure containing the Hyperbus configuration
997 * @param Timeout : Timeout duration
998 * @retval HAL status
1000 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
1002 HAL_StatusTypeDef status;
1003 uint32_t state;
1004 uint32_t tickstart = HAL_GetTick();
1006 /* Check the parameters of the hyperbus configuration structure */
1007 assert_param(IS_OSPI_RW_RECOVERY_TIME (cfg->RWRecoveryTime));
1008 assert_param(IS_OSPI_ACCESS_TIME (cfg->AccessTime));
1009 assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
1010 assert_param(IS_OSPI_LATENCY_MODE (cfg->LatencyMode));
1012 /* Check the state of the driver */
1013 state = hospi->State;
1014 if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
1016 /* Wait till busy flag is reset */
1017 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1019 if (status == HAL_OK)
1021 /* Configure Hyperbus configuration Latency register */
1022 WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
1023 (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos) |
1024 cfg->WriteZeroLatency | cfg->LatencyMode));
1026 /* Update the state */
1027 hospi->State = HAL_OSPI_STATE_READY;
1030 else
1032 status = HAL_ERROR;
1033 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1036 /* Return function status */
1037 return status;
1041 * @brief Set the Hyperbus command configuration.
1042 * @param hospi : OSPI handle
1043 * @param cmd : Structure containing the Hyperbus command
1044 * @param Timeout : Timeout duration
1045 * @retval HAL status
1047 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
1049 HAL_StatusTypeDef status;
1050 uint32_t tickstart = HAL_GetTick();
1052 /* Check the parameters of the hyperbus command structure */
1053 assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
1054 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
1055 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
1056 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
1058 /* Check the state of the driver */
1059 if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
1061 /* Wait till busy flag is reset */
1062 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1064 if (status == HAL_OK)
1066 /* Re-initialize the value of the functional mode */
1067 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
1069 /* Configure the address space in the DCR1 register */
1070 MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
1072 /* Configure the CCR and WCCR registers with the address size and the following configuration :
1073 - DQS signal enabled (used as RWDS)
1074 - DTR mode enabled on address and data
1075 - address and data on 8 lines */
1076 WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
1077 cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
1078 WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
1079 cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
1081 /* Configure the DLR register with the number of data */
1082 WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
1084 /* Configure the AR register with the address value */
1085 WRITE_REG(hospi->Instance->AR, cmd->Address);
1087 /* Update the state */
1088 hospi->State = HAL_OSPI_STATE_CMD_CFG;
1091 else
1093 status = HAL_ERROR;
1094 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1097 /* Return function status */
1098 return status;
1102 * @brief Transmit an amount of data in blocking mode.
1103 * @param hospi : OSPI handle
1104 * @param pData : pointer to data buffer
1105 * @param Timeout : Timeout duration
1106 * @note This function is used only in Indirect Write Mode
1107 * @retval HAL status
1109 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1111 HAL_StatusTypeDef status;
1112 uint32_t tickstart = HAL_GetTick();
1113 __IO uint32_t *data_reg = &hospi->Instance->DR;
1115 /* Check the data pointer allocation */
1116 if (pData == NULL)
1118 status = HAL_ERROR;
1119 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1121 else
1123 /* Check the state */
1124 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1126 /* Configure counters and size */
1127 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1128 hospi->XferSize = hospi->XferCount;
1129 hospi->pBuffPtr = pData;
1131 /* Configure CR register with functional mode as indirect write */
1132 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1136 /* Wait till fifo threshold flag is set to send data */
1137 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
1139 if (status != HAL_OK)
1141 break;
1144 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
1145 hospi->pBuffPtr++;
1146 hospi->XferCount--;
1147 } while (hospi->XferCount > 0U);
1149 if (status == HAL_OK)
1151 /* Wait till transfer complete flag is set to go back in idle state */
1152 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1154 if (status == HAL_OK)
1156 /* Clear transfer complete flag */
1157 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1159 /* Update state */
1160 hospi->State = HAL_OSPI_STATE_READY;
1164 else
1166 status = HAL_ERROR;
1167 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1171 /* Return function status */
1172 return status;
1176 * @brief Receive an amount of data in blocking mode.
1177 * @param hospi : OSPI handle
1178 * @param pData : pointer to data buffer
1179 * @param Timeout : Timeout duration
1180 * @note This function is used only in Indirect Read Mode
1181 * @retval HAL status
1183 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1185 HAL_StatusTypeDef status;
1186 uint32_t tickstart = HAL_GetTick();
1187 __IO uint32_t *data_reg = &hospi->Instance->DR;
1188 uint32_t addr_reg = hospi->Instance->AR;
1189 uint32_t ir_reg = hospi->Instance->IR;
1191 /* Check the data pointer allocation */
1192 if (pData == NULL)
1194 status = HAL_ERROR;
1195 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1197 else
1199 /* Check the state */
1200 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1202 /* Configure counters and size */
1203 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1204 hospi->XferSize = hospi->XferCount;
1205 hospi->pBuffPtr = pData;
1207 /* Configure CR register with functional mode as indirect read */
1208 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1210 /* Trig the transfer by re-writing address or instruction register */
1211 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1213 WRITE_REG(hospi->Instance->AR, addr_reg);
1215 else
1217 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1219 WRITE_REG(hospi->Instance->AR, addr_reg);
1221 else
1223 WRITE_REG(hospi->Instance->IR, ir_reg);
1229 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1230 status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
1232 if (status != HAL_OK)
1234 break;
1237 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
1238 hospi->pBuffPtr++;
1239 hospi->XferCount--;
1240 } while(hospi->XferCount > 0U);
1242 if (status == HAL_OK)
1244 /* Wait till transfer complete flag is set to go back in idle state */
1245 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1247 if (status == HAL_OK)
1249 /* Clear transfer complete flag */
1250 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1252 /* Update state */
1253 hospi->State = HAL_OSPI_STATE_READY;
1257 else
1259 status = HAL_ERROR;
1260 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1264 /* Return function status */
1265 return status;
1269 * @brief Send an amount of data in non-blocking mode with interrupt.
1270 * @param hospi : OSPI handle
1271 * @param pData : pointer to data buffer
1272 * @note This function is used only in Indirect Write Mode
1273 * @retval HAL status
1275 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1277 HAL_StatusTypeDef status = HAL_OK;
1279 /* Check the data pointer allocation */
1280 if (pData == NULL)
1282 status = HAL_ERROR;
1283 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1285 else
1287 /* Check the state */
1288 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1290 /* Configure counters and size */
1291 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1292 hospi->XferSize = hospi->XferCount;
1293 hospi->pBuffPtr = pData;
1295 /* Configure CR register with functional mode as indirect write */
1296 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1298 /* Clear flags related to interrupt */
1299 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1301 /* Update the state */
1302 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1304 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1305 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1307 else
1309 status = HAL_ERROR;
1310 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1314 /* Return function status */
1315 return status;
1319 * @brief Receive an amount of data in non-blocking mode with interrupt.
1320 * @param hospi : OSPI handle
1321 * @param pData : pointer to data buffer
1322 * @note This function is used only in Indirect Read Mode
1323 * @retval HAL status
1325 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1327 HAL_StatusTypeDef status = HAL_OK;
1328 uint32_t addr_reg = hospi->Instance->AR;
1329 uint32_t ir_reg = hospi->Instance->IR;
1331 /* Check the data pointer allocation */
1332 if (pData == NULL)
1334 status = HAL_ERROR;
1335 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1337 else
1339 /* Check the state */
1340 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1342 /* Configure counters and size */
1343 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1344 hospi->XferSize = hospi->XferCount;
1345 hospi->pBuffPtr = pData;
1347 /* Configure CR register with functional mode as indirect read */
1348 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1350 /* Clear flags related to interrupt */
1351 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1353 /* Update the state */
1354 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1356 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1357 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1359 /* Trig the transfer by re-writing address or instruction register */
1360 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1362 WRITE_REG(hospi->Instance->AR, addr_reg);
1364 else
1366 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1368 WRITE_REG(hospi->Instance->AR, addr_reg);
1370 else
1372 WRITE_REG(hospi->Instance->IR, ir_reg);
1376 else
1378 status = HAL_ERROR;
1379 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1383 /* Return function status */
1384 return status;
1388 * @brief Send an amount of data in non-blocking mode with DMA.
1389 * @param hospi : OSPI handle
1390 * @param pData : pointer to data buffer
1391 * @note This function is used only in Indirect Write Mode
1392 * @note If DMA peripheral access is configured as halfword, the number
1393 * of data and the fifo threshold should be aligned on halfword
1394 * @note If DMA peripheral access is configured as word, the number
1395 * of data and the fifo threshold should be aligned on word
1396 * @retval HAL status
1398 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1400 HAL_StatusTypeDef status = HAL_OK;
1401 uint32_t data_size = hospi->Instance->DLR + 1U;
1403 /* Check the data pointer allocation */
1404 if (pData == NULL)
1406 status = HAL_ERROR;
1407 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1409 else
1411 /* Check the state */
1412 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1414 hospi->XferCount = data_size;
1417 hospi->XferSize = hospi->XferCount;
1418 hospi->pBuffPtr = pData;
1420 /* Configure CR register with functional mode as indirect write */
1421 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1423 /* Clear flags related to interrupt */
1424 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1426 /* Update the state */
1427 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1429 /* Set the MDMA transfer complete callback */
1430 hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1432 /* Set the MDMA error callback */
1433 hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1435 /* Clear the MDMA abort callback */
1436 hospi->hmdma->XferAbortCallback = NULL;
1438 /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment to disable */
1439 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE);
1441 /* Update MDMA configuration with the correct SourceInc field for Write operation */
1442 if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE)
1444 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE);
1446 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD)
1448 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD);
1450 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD)
1452 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD);
1454 else
1456 /* in case of incorrect source data size */
1457 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1458 status = HAL_ERROR;
1461 /* Enable the transmit MDMA Channel */
1462 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize,1) == HAL_OK)
1464 /* Enable the transfer error interrupt */
1465 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1467 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1469 else
1471 status = HAL_ERROR;
1472 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1473 hospi->State = HAL_OSPI_STATE_READY;
1477 else
1479 status = HAL_ERROR;
1480 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1484 /* Return function status */
1485 return status;
1489 * @brief Receive an amount of data in non-blocking mode with DMA.
1490 * @param hospi : OSPI handle
1491 * @param pData : pointer to data buffer.
1492 * @note This function is used only in Indirect Read Mode
1493 * @note If DMA peripheral access is configured as halfword, the number
1494 * of data and the fifo threshold should be aligned on halfword
1495 * @note If DMA peripheral access is configured as word, the number
1496 * of data and the fifo threshold should be aligned on word
1497 * @retval HAL status
1499 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1501 HAL_StatusTypeDef status = HAL_OK;
1502 uint32_t data_size = hospi->Instance->DLR + 1U;
1503 uint32_t addr_reg = hospi->Instance->AR;
1504 uint32_t ir_reg = hospi->Instance->IR;
1506 /* Check the data pointer allocation */
1507 if (pData == NULL)
1509 status = HAL_ERROR;
1510 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1512 else
1514 /* Check the state */
1515 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1517 hospi->XferCount = data_size;
1520 hospi->XferSize = hospi->XferCount;
1521 hospi->pBuffPtr = pData;
1523 /* Configure CR register with functional mode as indirect read */
1524 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1526 /* Clear flags related to interrupt */
1527 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1529 /* Update the state */
1530 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1532 /* Set the DMA transfer complete callback */
1533 hospi->hmdma->XferCpltCallback = OSPI_DMACplt;
1535 /* Set the DMA error callback */
1536 hospi->hmdma->XferErrorCallback = OSPI_DMAError;
1538 /* Clear the DMA abort callback */
1539 hospi->hmdma->XferAbortCallback = NULL;
1541 /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
1542 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE);
1544 /* Update MDMA configuration with the correct DestinationInc field for read operation */
1545 if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE)
1547 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE);
1549 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD)
1551 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD);
1553 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD)
1555 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD);
1557 else
1559 /* in case of incorrect destination data size */
1560 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA;
1561 status = HAL_ERROR;
1564 /* Enable the transmit MDMA Channel */
1565 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize, 1) == HAL_OK)
1567 /* Enable the transfer error interrupt */
1568 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1570 /* Trig the transfer by re-writing address or instruction register */
1571 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1573 WRITE_REG(hospi->Instance->AR, addr_reg);
1575 else
1577 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1579 WRITE_REG(hospi->Instance->AR, addr_reg);
1581 else
1583 WRITE_REG(hospi->Instance->IR, ir_reg);
1587 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1589 else
1591 status = HAL_ERROR;
1592 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1593 hospi->State = HAL_OSPI_STATE_READY;
1597 else
1599 status = HAL_ERROR;
1600 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1604 /* Return function status */
1605 return status;
1609 * @brief Configure the OSPI Automatic Polling Mode in blocking mode.
1610 * @param hospi : OSPI handle
1611 * @param cfg : structure that contains the polling configuration information.
1612 * @param Timeout : Timeout duration
1613 * @note This function is used only in Automatic Polling Mode
1614 * @retval HAL status
1616 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1618 HAL_StatusTypeDef status;
1619 uint32_t tickstart = HAL_GetTick();
1620 uint32_t addr_reg = hospi->Instance->AR;
1621 uint32_t ir_reg = hospi->Instance->IR;
1622 #ifdef USE_FULL_ASSERT
1623 uint32_t dlr_reg = hospi->Instance->DLR;
1624 #endif
1626 /* Check the parameters of the autopolling configuration structure */
1627 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1628 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1629 assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1630 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1632 /* Check the state */
1633 if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
1635 /* Wait till busy flag is reset */
1636 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1638 if (status == HAL_OK)
1640 /* Configure registers */
1641 WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1642 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1643 WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1644 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1645 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1647 /* Trig the transfer by re-writing address or instruction register */
1648 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1650 WRITE_REG(hospi->Instance->AR, addr_reg);
1652 else
1654 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1656 WRITE_REG(hospi->Instance->AR, addr_reg);
1658 else
1660 WRITE_REG(hospi->Instance->IR, ir_reg);
1664 /* Wait till status match flag is set to go back in idle state */
1665 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
1667 if (status == HAL_OK)
1669 /* Clear status match flag */
1670 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
1672 /* Update state */
1673 hospi->State = HAL_OSPI_STATE_READY;
1677 else
1679 status = HAL_ERROR;
1680 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1683 /* Return function status */
1684 return status;
1688 * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode.
1689 * @param hospi : OSPI handle
1690 * @param cfg : structure that contains the polling configuration information.
1691 * @note This function is used only in Automatic Polling Mode
1692 * @retval HAL status
1694 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
1696 HAL_StatusTypeDef status;
1697 uint32_t tickstart = HAL_GetTick();
1698 uint32_t addr_reg = hospi->Instance->AR;
1699 uint32_t ir_reg = hospi->Instance->IR;
1700 #ifdef USE_FULL_ASSERT
1701 uint32_t dlr_reg = hospi->Instance->DLR;
1702 #endif
1704 /* Check the parameters of the autopolling configuration structure */
1705 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1706 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1707 assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1708 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1710 /* Check the state */
1711 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1713 /* Wait till busy flag is reset */
1714 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1716 if (status == HAL_OK)
1718 /* Configure registers */
1719 WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1720 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1721 WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1722 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1723 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1725 /* Clear flags related to interrupt */
1726 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
1728 /* Update state */
1729 hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
1731 /* Enable the status match and transfer error interrupts */
1732 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
1734 /* Trig the transfer by re-writing address or instruction register */
1735 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1737 WRITE_REG(hospi->Instance->AR, addr_reg);
1739 else
1741 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1743 WRITE_REG(hospi->Instance->AR, addr_reg);
1745 else
1747 WRITE_REG(hospi->Instance->IR, ir_reg);
1752 else
1754 status = HAL_ERROR;
1755 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1758 /* Return function status */
1759 return status;
1763 * @brief Configure the Memory Mapped mode.
1764 * @param hospi : OSPI handle
1765 * @param cfg : structure that contains the memory mapped configuration information.
1766 * @note This function is used only in Memory mapped Mode
1767 * @retval HAL status
1769 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
1771 HAL_StatusTypeDef status;
1772 uint32_t tickstart = HAL_GetTick();
1774 /* Check the parameters of the memory-mapped configuration structure */
1775 assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1777 /* Check the state */
1778 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1780 /* Wait till busy flag is reset */
1781 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1783 if (status == HAL_OK)
1785 /* Update state */
1786 hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
1788 if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
1790 assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1792 /* Configure register */
1793 WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
1795 /* Clear flags related to interrupt */
1796 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
1798 /* Enable the timeout interrupt */
1799 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
1802 /* Configure CR register with functional mode as memory-mapped */
1803 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
1804 (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1807 else
1809 status = HAL_ERROR;
1810 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1813 /* Return function status */
1814 return status;
1818 * @brief Transfer Error callback.
1819 * @param hospi : OSPI handle
1820 * @retval None
1822 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
1824 /* Prevent unused argument(s) compilation warning */
1825 UNUSED(hospi);
1827 /* NOTE : This function should not be modified, when the callback is needed,
1828 the HAL_OSPI_ErrorCallback could be implemented in the user file
1833 * @brief Abort completed callback.
1834 * @param hospi : OSPI handle
1835 * @retval None
1837 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
1839 /* Prevent unused argument(s) compilation warning */
1840 UNUSED(hospi);
1842 /* NOTE: This function should not be modified, when the callback is needed,
1843 the HAL_OSPI_AbortCpltCallback could be implemented in the user file
1848 * @brief FIFO Threshold callback.
1849 * @param hospi : OSPI handle
1850 * @retval None
1852 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
1854 /* Prevent unused argument(s) compilation warning */
1855 UNUSED(hospi);
1857 /* NOTE : This function should not be modified, when the callback is needed,
1858 the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
1863 * @brief Command completed callback.
1864 * @param hospi : OSPI handle
1865 * @retval None
1867 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
1869 /* Prevent unused argument(s) compilation warning */
1870 UNUSED(hospi);
1872 /* NOTE: This function should not be modified, when the callback is needed,
1873 the HAL_OSPI_CmdCpltCallback could be implemented in the user file
1878 * @brief Rx Transfer completed callback.
1879 * @param hospi : OSPI handle
1880 * @retval None
1882 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
1884 /* Prevent unused argument(s) compilation warning */
1885 UNUSED(hospi);
1887 /* NOTE: This function should not be modified, when the callback is needed,
1888 the HAL_OSPI_RxCpltCallback could be implemented in the user file
1893 * @brief Tx Transfer completed callback.
1894 * @param hospi : OSPI handle
1895 * @retval None
1897 __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
1899 /* Prevent unused argument(s) compilation warning */
1900 UNUSED(hospi);
1902 /* NOTE: This function should not be modified, when the callback is needed,
1903 the HAL_OSPI_TxCpltCallback could be implemented in the user file
1908 * @brief Rx Half Transfer completed callback.
1909 * @param hospi : OSPI handle
1910 * @retval None
1912 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1914 /* Prevent unused argument(s) compilation warning */
1915 UNUSED(hospi);
1917 /* NOTE: This function should not be modified, when the callback is needed,
1918 the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
1923 * @brief Tx Half Transfer completed callback.
1924 * @param hospi : OSPI handle
1925 * @retval None
1927 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
1929 /* Prevent unused argument(s) compilation warning */
1930 UNUSED(hospi);
1932 /* NOTE: This function should not be modified, when the callback is needed,
1933 the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
1938 * @brief Status Match callback.
1939 * @param hospi : OSPI handle
1940 * @retval None
1942 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
1944 /* Prevent unused argument(s) compilation warning */
1945 UNUSED(hospi);
1947 /* NOTE : This function should not be modified, when the callback is needed,
1948 the HAL_OSPI_StatusMatchCallback could be implemented in the user file
1953 * @brief Timeout callback.
1954 * @param hospi : OSPI handle
1955 * @retval None
1957 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
1959 /* Prevent unused argument(s) compilation warning */
1960 UNUSED(hospi);
1962 /* NOTE : This function should not be modified, when the callback is needed,
1963 the HAL_OSPI_TimeOutCallback could be implemented in the user file
1967 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
1969 * @brief Register a User OSPI Callback
1970 * To be used instead of the weak (surcharged) predefined callback
1971 * @param hospi : OSPI handle
1972 * @param CallbackID : ID of the callback to be registered
1973 * This parameter can be one of the following values:
1974 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
1975 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
1976 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
1977 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
1978 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
1979 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
1980 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
1981 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
1982 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
1983 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
1984 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
1985 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
1986 * @param pCallback : pointer to the Callback function
1987 * @retval status
1989 HAL_StatusTypeDef HAL_OSPI_RegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID, pOSPI_CallbackTypeDef pCallback)
1991 HAL_StatusTypeDef status = HAL_OK;
1993 if(pCallback == NULL)
1995 /* Update the error code */
1996 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
1997 return HAL_ERROR;
2000 if(hospi->State == HAL_OSPI_STATE_READY)
2002 switch (CallbackID)
2004 case HAL_OSPI_ERROR_CB_ID :
2005 hospi->ErrorCallback = pCallback;
2006 break;
2007 case HAL_OSPI_ABORT_CB_ID :
2008 hospi->AbortCpltCallback = pCallback;
2009 break;
2010 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2011 hospi->FifoThresholdCallback = pCallback;
2012 break;
2013 case HAL_OSPI_CMD_CPLT_CB_ID :
2014 hospi->CmdCpltCallback = pCallback;
2015 break;
2016 case HAL_OSPI_RX_CPLT_CB_ID :
2017 hospi->RxCpltCallback = pCallback;
2018 break;
2019 case HAL_OSPI_TX_CPLT_CB_ID :
2020 hospi->TxCpltCallback = pCallback;
2021 break;
2022 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2023 hospi->RxHalfCpltCallback = pCallback;
2024 break;
2025 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2026 hospi->TxHalfCpltCallback = pCallback;
2027 break;
2028 case HAL_OSPI_STATUS_MATCH_CB_ID :
2029 hospi->StatusMatchCallback = pCallback;
2030 break;
2031 case HAL_OSPI_TIMEOUT_CB_ID :
2032 hospi->TimeOutCallback = pCallback;
2033 break;
2034 case HAL_OSPI_MSP_INIT_CB_ID :
2035 hospi->MspInitCallback = pCallback;
2036 break;
2037 case HAL_OSPI_MSP_DEINIT_CB_ID :
2038 hospi->MspDeInitCallback = pCallback;
2039 break;
2040 default :
2041 /* Update the error code */
2042 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2043 /* update return status */
2044 status = HAL_ERROR;
2045 break;
2048 else if (hospi->State == HAL_OSPI_STATE_RESET)
2050 switch (CallbackID)
2052 case HAL_OSPI_MSP_INIT_CB_ID :
2053 hospi->MspInitCallback = pCallback;
2054 break;
2055 case HAL_OSPI_MSP_DEINIT_CB_ID :
2056 hospi->MspDeInitCallback = pCallback;
2057 break;
2058 default :
2059 /* Update the error code */
2060 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2061 /* update return status */
2062 status = HAL_ERROR;
2063 break;
2066 else
2068 /* Update the error code */
2069 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2070 /* update return status */
2071 status = HAL_ERROR;
2074 return status;
2078 * @brief Unregister a User OSPI Callback
2079 * OSPI Callback is redirected to the weak (surcharged) predefined callback
2080 * @param hospi : OSPI handle
2081 * @param CallbackID : ID of the callback to be unregistered
2082 * This parameter can be one of the following values:
2083 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
2084 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
2085 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2086 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
2087 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
2088 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
2089 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
2090 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
2091 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
2092 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
2093 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
2094 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
2095 * @retval status
2097 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
2099 HAL_StatusTypeDef status = HAL_OK;
2101 if(hospi->State == HAL_OSPI_STATE_READY)
2103 switch (CallbackID)
2105 case HAL_OSPI_ERROR_CB_ID :
2106 hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
2107 break;
2108 case HAL_OSPI_ABORT_CB_ID :
2109 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
2110 break;
2111 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2112 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
2113 break;
2114 case HAL_OSPI_CMD_CPLT_CB_ID :
2115 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
2116 break;
2117 case HAL_OSPI_RX_CPLT_CB_ID :
2118 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
2119 break;
2120 case HAL_OSPI_TX_CPLT_CB_ID :
2121 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
2122 break;
2123 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2124 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
2125 break;
2126 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2127 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
2128 break;
2129 case HAL_OSPI_STATUS_MATCH_CB_ID :
2130 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
2131 break;
2132 case HAL_OSPI_TIMEOUT_CB_ID :
2133 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
2134 break;
2135 case HAL_OSPI_MSP_INIT_CB_ID :
2136 hospi->MspInitCallback = HAL_OSPI_MspInit;
2137 break;
2138 case HAL_OSPI_MSP_DEINIT_CB_ID :
2139 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2140 break;
2141 default :
2142 /* Update the error code */
2143 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2144 /* update return status */
2145 status = HAL_ERROR;
2146 break;
2149 else if (hospi->State == HAL_OSPI_STATE_RESET)
2151 switch (CallbackID)
2153 case HAL_OSPI_MSP_INIT_CB_ID :
2154 hospi->MspInitCallback = HAL_OSPI_MspInit;
2155 break;
2156 case HAL_OSPI_MSP_DEINIT_CB_ID :
2157 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2158 break;
2159 default :
2160 /* Update the error code */
2161 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2162 /* update return status */
2163 status = HAL_ERROR;
2164 break;
2167 else
2169 /* Update the error code */
2170 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2171 /* update return status */
2172 status = HAL_ERROR;
2175 return status;
2177 #endif
2180 * @}
2183 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
2184 * @brief OSPI control and State functions
2186 @verbatim
2187 ===============================================================================
2188 ##### Peripheral Control and State functions #####
2189 ===============================================================================
2190 [..]
2191 This subsection provides a set of functions allowing to :
2192 (+) Check in run-time the state of the driver.
2193 (+) Check the error code set during last operation.
2194 (+) Abort any operation.
2195 (+) Manage the Fifo threshold.
2196 (+) Configure the timeout duration used in the driver.
2198 @endverbatim
2199 * @{
2203 * @brief Abort the current transmission.
2204 * @param hospi : OSPI handle
2205 * @retval HAL status
2207 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
2209 HAL_StatusTypeDef status = HAL_OK;
2210 uint32_t state;
2211 uint32_t tickstart = HAL_GetTick();
2213 /* Check if the state is in one of the busy or configured states */
2214 state = hospi->State;
2215 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2217 /* Check if the DMA is enabled */
2218 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2220 /* Disable the DMA transfer on the OctoSPI side */
2221 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2223 /* Disable the DMA transfer on the DMA side */
2224 status = HAL_MDMA_Abort(hospi->hmdma);
2225 if (status != HAL_OK)
2227 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2231 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2233 /* Perform an abort of the OctoSPI */
2234 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2236 /* Wait until the transfer complete flag is set to go back in idle state */
2237 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
2239 if (status == HAL_OK)
2241 /* Clear transfer complete flag */
2242 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2244 /* Wait until the busy flag is reset to go back in idle state */
2245 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
2247 if (status == HAL_OK)
2249 /* Update state */
2250 hospi->State = HAL_OSPI_STATE_READY;
2254 else
2256 /* Update state */
2257 hospi->State = HAL_OSPI_STATE_READY;
2260 else
2262 status = HAL_ERROR;
2263 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2266 /* Return function status */
2267 return status;
2271 * @brief Abort the current transmission (non-blocking function)
2272 * @param hospi : OSPI handle
2273 * @retval HAL status
2275 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
2277 HAL_StatusTypeDef status = HAL_OK;
2278 uint32_t state;
2280 /* Check if the state is in one of the busy or configured states */
2281 state = hospi->State;
2282 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2284 /* Disable all interrupts */
2285 __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));
2287 /* Update state */
2288 hospi->State = HAL_OSPI_STATE_ABORT;
2290 /* Check if the DMA is enabled */
2291 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2293 /* Disable the DMA transfer on the OctoSPI side */
2294 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2296 /* Disable the DMA transfer on the DMA side */
2297 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt;
2298 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK)
2300 /* Update state */
2301 hospi->State = HAL_OSPI_STATE_READY;
2303 /* Abort callback */
2304 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2305 hospi->AbortCpltCallback(hospi);
2306 #else
2307 HAL_OSPI_AbortCpltCallback(hospi);
2308 #endif
2311 else
2313 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2315 /* Clear transfer complete flag */
2316 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2318 /* Enable the transfer complete interrupts */
2319 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2321 /* Perform an abort of the OctoSPI */
2322 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2324 else
2326 /* Update state */
2327 hospi->State = HAL_OSPI_STATE_READY;
2329 /* Abort callback */
2330 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2331 hospi->AbortCpltCallback(hospi);
2332 #else
2333 HAL_OSPI_AbortCpltCallback(hospi);
2334 #endif
2338 else
2340 status = HAL_ERROR;
2341 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2344 /* Return function status */
2345 return status;
2348 /** @brief Set OSPI Fifo threshold.
2349 * @param hospi : OSPI handle.
2350 * @param Threshold : Threshold of the Fifo.
2351 * @retval HAL status
2353 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
2355 HAL_StatusTypeDef status = HAL_OK;
2357 /* Check the state */
2358 if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
2360 /* Synchronize initialization structure with the new fifo threshold value */
2361 hospi->Init.FifoThreshold = Threshold;
2363 /* Configure new fifo threshold */
2364 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos));
2367 else
2369 status = HAL_ERROR;
2370 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2373 /* Return function status */
2374 return status;
2377 /** @brief Get OSPI Fifo threshold.
2378 * @param hospi : OSPI handle.
2379 * @retval Fifo threshold
2381 uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef *hospi)
2383 return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
2386 /** @brief Set OSPI timeout.
2387 * @param hospi : OSPI handle.
2388 * @param Timeout : Timeout for the memory access.
2389 * @retval None
2391 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
2393 hospi->Timeout = Timeout;
2394 return HAL_OK;
2398 * @brief Return the OSPI error code.
2399 * @param hospi : OSPI handle
2400 * @retval OSPI Error Code
2402 uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef *hospi)
2404 return hospi->ErrorCode;
2408 * @brief Return the OSPI handle state.
2409 * @param hospi : OSPI handle
2410 * @retval HAL state
2412 uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef *hospi)
2414 /* Return OSPI handle state */
2415 return hospi->State;
2419 * @}
2422 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
2423 * @brief OSPI IO Manager configuration function
2425 @verbatim
2426 ===============================================================================
2427 ##### IO Manager configuration function #####
2428 ===============================================================================
2429 [..]
2430 This subsection provides a set of functions allowing to :
2431 (+) Configure the IO manager.
2433 @endverbatim
2434 * @{
2438 * @brief Configure the OctoSPI IO manager.
2439 * @param hospi : OSPI handle
2440 * @param cfg : Configuration of the IO Manager for the instance
2441 * @param Timeout : Timeout duration
2442 * @retval HAL status
2444 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
2446 HAL_StatusTypeDef status = HAL_OK;
2447 uint32_t instance;
2448 uint8_t index, ospi_enabled = 0U, other_instance;
2449 OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2451 /* Prevent unused argument(s) compilation warning */
2452 UNUSED(Timeout);
2454 /* Check the parameters of the OctoSPI IO Manager configuration structure */
2455 assert_param(IS_OSPIM_PORT(cfg->ClkPort));
2456 assert_param(IS_OSPIM_PORT(cfg->DQSPort));
2457 assert_param(IS_OSPIM_PORT(cfg->NCSPort));
2458 assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
2459 assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
2461 if (hospi->Instance == OCTOSPI1)
2463 instance = 0U;
2464 other_instance = 1U;
2466 else
2468 instance = 1U;
2469 other_instance = 0U;
2472 /**************** Get current configuration of the instances ****************/
2473 for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2475 if (OSPIM_GetConfig(index+1U, &(IOM_cfg[index])) != HAL_OK)
2477 status = HAL_ERROR;
2478 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2482 if (status == HAL_OK)
2484 /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2485 if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
2487 CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2488 ospi_enabled |= 0x1U;
2490 if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
2492 CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2493 ospi_enabled |= 0x2U;
2496 /***************** Deactivation of previous configuration *****************/
2497 if (IOM_cfg[instance].ClkPort != 0U)
2499 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2500 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2501 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2502 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2503 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2506 /********************* Deactivation of other instance *********************/
2507 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) ||
2508 (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
2509 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2511 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2512 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2513 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2514 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2515 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2518 /******************** Activation of new configuration *********************/
2519 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
2520 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
2521 MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
2523 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2525 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2526 (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2528 else
2530 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2531 (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2534 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2536 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2537 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2539 else
2541 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2542 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2545 /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2546 if ((ospi_enabled & 0x1U) != 0U)
2548 SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2550 if ((ospi_enabled & 0x2U) != 0U)
2552 SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2556 /* Return function status */
2557 return status;
2561 * @}
2565 @cond 0
2568 * @brief DMA OSPI process complete callback.
2569 * @param hdma : DMA handle
2570 * @retval None
2572 static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma)
2574 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2575 hospi->XferCount = 0;
2577 /* Disable the DMA transfer on the OctoSPI side */
2578 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2580 /* Disable the DMA channel */
2581 __HAL_MDMA_DISABLE(hmdma);
2583 /* Enable the OSPI transfer complete Interrupt */
2584 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2588 * @brief DMA OSPI communication error callback.
2589 * @param hdma : DMA handle
2590 * @retval None
2592 static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma)
2594 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2595 hospi->XferCount = 0;
2596 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2598 /* Disable the DMA transfer on the OctoSPI side */
2599 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2601 /* Abort the OctoSPI */
2602 if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
2604 /* Disable the interrupts */
2605 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
2607 /* Update state */
2608 hospi->State = HAL_OSPI_STATE_READY;
2610 /* Error callback */
2611 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2612 hospi->ErrorCallback(hospi);
2613 #else
2614 HAL_OSPI_ErrorCallback(hospi);
2615 #endif
2620 * @brief DMA OSPI abort complete callback.
2621 * @param hdma : DMA handle
2622 * @retval None
2624 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma)
2626 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent);
2627 hospi->XferCount = 0;
2629 /* Check the state */
2630 if (hospi->State == HAL_OSPI_STATE_ABORT)
2632 /* DMA abort called by OctoSPI abort */
2633 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2635 /* Clear transfer complete flag */
2636 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2638 /* Enable the transfer complete interrupts */
2639 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2641 /* Perform an abort of the OctoSPI */
2642 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2644 else
2646 /* Update state */
2647 hospi->State = HAL_OSPI_STATE_READY;
2649 /* Abort callback */
2650 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2651 hospi->AbortCpltCallback(hospi);
2652 #else
2653 HAL_OSPI_AbortCpltCallback(hospi);
2654 #endif
2657 else
2659 /* DMA abort called due to a transfer error interrupt */
2660 /* Update state */
2661 hospi->State = HAL_OSPI_STATE_READY;
2663 /* Error callback */
2664 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2665 hospi->ErrorCallback(hospi);
2666 #else
2667 HAL_OSPI_ErrorCallback(hospi);
2668 #endif
2673 * @brief Wait for a flag state until timeout.
2674 * @param hospi : OSPI handle
2675 * @param Flag : Flag checked
2676 * @param State : Value of the flag expected
2677 * @param Timeout : Duration of the timeout
2678 * @param Tickstart : Tick start value
2679 * @retval HAL status
2681 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
2682 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2684 /* Wait until flag is in expected state */
2685 while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
2687 /* Check for the Timeout */
2688 if (Timeout != HAL_MAX_DELAY)
2690 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2692 hospi->State = HAL_OSPI_STATE_ERROR;
2693 hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
2695 return HAL_ERROR;
2699 return HAL_OK;
2703 * @brief Configure the registers for the regular command mode.
2704 * @param hospi : OSPI handle
2705 * @param cmd : structure that contains the command configuration information
2706 * @retval HAL status
2708 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
2710 HAL_StatusTypeDef status = HAL_OK;
2711 __IO uint32_t *ccr_reg, *tcr_reg, *ir_reg, *abr_reg;
2713 /* Re-initialize the value of the functional mode */
2714 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
2716 /* Configure the flash ID */
2717 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
2719 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
2722 if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
2724 ccr_reg = &(hospi->Instance->WCCR);
2725 tcr_reg = &(hospi->Instance->WTCR);
2726 ir_reg = &(hospi->Instance->WIR);
2727 abr_reg = &(hospi->Instance->WABR);
2729 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
2731 ccr_reg = &(hospi->Instance->WPCCR);
2732 tcr_reg = &(hospi->Instance->WPTCR);
2733 ir_reg = &(hospi->Instance->WPIR);
2734 abr_reg = &(hospi->Instance->WPABR);
2736 else
2738 ccr_reg = &(hospi->Instance->CCR);
2739 tcr_reg = &(hospi->Instance->TCR);
2740 ir_reg = &(hospi->Instance->IR);
2741 abr_reg = &(hospi->Instance->ABR);
2744 /* Configure the CCR register with DQS and SIOO modes */
2745 *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
2747 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
2749 /* Configure the ABR register with alternate bytes value */
2750 *abr_reg = cmd->AlternateBytes;
2752 /* Configure the CCR register with alternate bytes communication parameters */
2753 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
2754 (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
2757 /* Configure the TCR register with the number of dummy cycles */
2758 MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
2760 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2762 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
2764 /* Configure the DLR register with the number of data */
2765 hospi->Instance->DLR = (cmd->NbData - 1U);
2769 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
2771 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2773 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2775 /* ---- Command with instruction, address and data ---- */
2777 /* Configure the CCR register with all communication parameters */
2778 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2779 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2780 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2781 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2782 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2783 cmd->DataMode | cmd->DataDtrMode));
2785 else
2787 /* ---- Command with instruction and address ---- */
2789 /* Configure the CCR register with all communication parameters */
2790 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2791 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2792 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2793 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2795 /* The DHQC bit is linked with DDTR bit which should be activated */
2796 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2797 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2799 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2803 /* Configure the IR register with the instruction value */
2804 *ir_reg = cmd->Instruction;
2806 /* Configure the AR register with the address value */
2807 hospi->Instance->AR = cmd->Address;
2809 else
2811 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2813 /* ---- Command with instruction and data ---- */
2815 /* Configure the CCR register with all communication parameters */
2816 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2817 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2818 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2819 cmd->DataMode | cmd->DataDtrMode));
2821 else
2823 /* ---- Command with only instruction ---- */
2825 /* Configure the CCR register with all communication parameters */
2826 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
2827 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
2829 /* The DHQC bit is linked with DDTR bit which should be activated */
2830 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2831 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2833 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2837 /* Configure the IR register with the instruction value */
2838 *ir_reg = cmd->Instruction;
2842 else
2844 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2846 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2848 /* ---- Command with address and data ---- */
2850 /* Configure the CCR register with all communication parameters */
2851 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2852 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2853 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2854 cmd->DataMode | cmd->DataDtrMode));
2856 else
2858 /* ---- Command with only address ---- */
2860 /* Configure the CCR register with all communication parameters */
2861 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2862 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2865 /* Configure the AR register with the instruction value */
2866 hospi->Instance->AR = cmd->Address;
2868 else
2870 /* ---- Invalid command configuration (no instruction, no address) ---- */
2871 status = HAL_ERROR;
2872 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2876 /* Return function status */
2877 return status;
2881 * @brief Get the current IOM configuration for an OctoSPI instance.
2882 * @param instance_nb : number of the instance
2883 * @param cfg : configuration of the IO Manager for the instance
2884 * @retval HAL status
2886 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
2888 HAL_StatusTypeDef status = HAL_OK;
2889 uint32_t reg, value = 0U;
2890 uint32_t index;
2892 if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
2894 /* Invalid parameter -> error returned */
2895 status = HAL_ERROR;
2897 else
2899 /* Initialize the structure */
2900 cfg->ClkPort = 0U;
2901 cfg->DQSPort = 0U;
2902 cfg->NCSPort = 0U;
2903 cfg->IOLowPort = 0U;
2904 cfg->IOHighPort = 0U;
2906 if (instance_nb == 2U)
2908 value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
2911 /* Get the information about the instance */
2912 for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
2914 reg = OCTOSPIM->PCR[index];
2916 if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
2918 /* The clock is enabled on this port */
2919 if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
2921 /* The clock correspond to the instance passed as parameter */
2922 cfg->ClkPort = index+1U;
2926 if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
2928 /* The DQS is enabled on this port */
2929 if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
2931 /* The DQS correspond to the instance passed as parameter */
2932 cfg->DQSPort = index+1U;
2936 if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
2938 /* The nCS is enabled on this port */
2939 if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
2941 /* The nCS correspond to the instance passed as parameter */
2942 cfg->NCSPort = index+1U;
2946 if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
2948 /* The IO Low is enabled on this port */
2949 if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
2951 /* The IO Low correspond to the instance passed as parameter */
2952 if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
2954 cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
2956 else
2958 cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
2963 if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
2965 /* The IO High is enabled on this port */
2966 if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
2968 /* The IO High correspond to the instance passed as parameter */
2969 if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
2971 cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
2973 else
2975 cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
2982 /* Return function status */
2983 return status;
2987 @endcond
2991 * @}
2994 #endif /* HAL_OSPI_MODULE_ENABLED */
2997 * @}
3001 * @}
3004 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3006 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/