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
19 ===============================================================================
20 ##### How to use this driver #####
21 ===============================================================================
23 *** Initialization ***
24 ======================
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()
45 *** Indirect functional mode ***
46 ================================
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()
64 (++) Address space : indicate if the access will be done in register or memory
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 ====================================
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 ====================================
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 =====================================
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
133 (#) Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
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 =================================================
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
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 =========================
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 ==========================================
161 (#) HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.
163 *** Callback registration ***
164 =============================================
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.
223 ******************************************************************************
226 * <h2><center>© 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
246 /** @defgroup OSPI OSPI
247 * @brief OSPI HAL module driver
251 #ifdef HAL_OSPI_MODULE_ENABLED
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
);
290 /* Exported functions --------------------------------------------------------*/
292 /** @defgroup OSPI_Exported_Functions OSPI Exported Functions
296 /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
297 * @brief Initialization and Configuration functions
300 ===============================================================================
301 ##### Initialization and Configuration functions #####
302 ===============================================================================
304 This subsection provides a set of functions allowing to :
305 (+) Initialize the OctoSPI.
306 (+) De-initialize the OctoSPI.
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
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 */
327 /* No error code can be set set as the handler is null */
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
);
375 /* Initialization of the low level hardware */
376 HAL_OSPI_MspInit(hospi
);
379 /* Configure the default timeout for the OSPI memory access */
380 (void)HAL_OSPI_SetTimeout(hospi
, HAL_OSPI_TIMEOUT_DEFAULT_VALUE
);
382 /* Configure memory type, device size, chip select high time, clocked chip select high time, delay block bypass, free running clock, clock mode */
383 MODIFY_REG(hospi
->Instance
->DCR1
,
384 (OCTOSPI_DCR1_MTYP
| OCTOSPI_DCR1_DEVSIZE
| OCTOSPI_DCR1_CSHT
| OCTOSPI_DCR1_CKCSHT
|
385 OCTOSPI_DCR1_DLYBYP
| OCTOSPI_DCR1_FRCK
| OCTOSPI_DCR1_CKMODE
),
386 (hospi
->Init
.MemoryType
| ((hospi
->Init
.DeviceSize
- 1U) << OCTOSPI_DCR1_DEVSIZE_Pos
) |
387 ((hospi
->Init
.ChipSelectHighTime
- 1U) << OCTOSPI_DCR1_CSHT_Pos
) |
388 (hospi
->Init
.ClkChipSelectHighTime
<< OCTOSPI_DCR1_CKCSHT_Pos
) |
389 hospi
->Init
.DelayBlockBypass
| hospi
->Init
.ClockMode
));
391 /* Configure wrap size */
392 MODIFY_REG(hospi
->Instance
->DCR2
, OCTOSPI_DCR2_WRAPSIZE
, hospi
->Init
.WrapSize
);
394 /* Configure chip select boundary and maximun transfer */
395 hospi
->Instance
->DCR3
= ((hospi
->Init
.ChipSelectBoundary
<< OCTOSPI_DCR3_CSBOUND_Pos
) | (hospi
->Init
.MaxTran
<< OCTOSPI_DCR3_MAXTRAN_Pos
));
397 /* Configure refresh */
398 hospi
->Instance
->DCR4
= hospi
->Init
.Refresh
;
400 /* Configure FIFO threshold */
401 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FTHRES
, ((hospi
->Init
.FifoThreshold
- 1U) << OCTOSPI_CR_FTHRES_Pos
));
403 /* Wait till busy flag is reset */
404 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, hospi
->Timeout
);
406 if (status
== HAL_OK
)
408 /* Configure clock prescaler */
409 MODIFY_REG(hospi
->Instance
->DCR2
, OCTOSPI_DCR2_PRESCALER
, ((hospi
->Init
.ClockPrescaler
- 1U) << OCTOSPI_DCR2_PRESCALER_Pos
));
411 /* Configure Dual Quad mode */
412 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_DQM
, hospi
->Init
.DualQuad
);
414 /* Configure sample shifting and delay hold quarter cycle */
415 MODIFY_REG(hospi
->Instance
->TCR
, (OCTOSPI_TCR_SSHIFT
| OCTOSPI_TCR_DHQC
), (hospi
->Init
.SampleShifting
| hospi
->Init
.DelayHoldQuarterCycle
));
418 __HAL_OSPI_ENABLE(hospi
);
420 /* Enable free running clock if needed : must be done after OSPI enable */
421 if (hospi
->Init
.FreeRunningClock
== HAL_OSPI_FREERUNCLK_ENABLE
)
423 SET_BIT(hospi
->Instance
->DCR1
, OCTOSPI_DCR1_FRCK
);
426 /* Initialize the OSPI state */
427 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
429 hospi
->State
= HAL_OSPI_STATE_HYPERBUS_INIT
;
433 hospi
->State
= HAL_OSPI_STATE_READY
;
439 /* Return function status */
444 * @brief Initialize the OSPI MSP.
445 * @param hospi : OSPI handle
448 __weak
void HAL_OSPI_MspInit(OSPI_HandleTypeDef
*hospi
)
450 /* Prevent unused argument(s) compilation warning */
453 /* NOTE : This function should not be modified, when the callback is needed,
454 the HAL_OSPI_MspInit can be implemented in the user file
459 * @brief De-Initialize the OSPI peripheral.
460 * @param hospi : OSPI handle
463 HAL_StatusTypeDef
HAL_OSPI_DeInit(OSPI_HandleTypeDef
*hospi
)
465 HAL_StatusTypeDef status
= HAL_OK
;
467 /* Check the OSPI handle allocation */
471 /* No error code can be set set as the handler is null */
475 /* Disable OctoSPI */
476 __HAL_OSPI_DISABLE(hospi
);
478 /* Disable free running clock if needed : must be done after OSPI disable */
479 CLEAR_BIT(hospi
->Instance
->DCR1
, OCTOSPI_DCR1_FRCK
);
481 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
482 if(hospi
->MspDeInitCallback
== NULL
)
484 hospi
->MspDeInitCallback
= HAL_OSPI_MspDeInit
;
487 /* DeInit the low level hardware */
488 hospi
->MspDeInitCallback(hospi
);
490 /* De-initialize the low-level hardware */
491 HAL_OSPI_MspDeInit(hospi
);
494 /* Reset the driver state */
495 hospi
->State
= HAL_OSPI_STATE_RESET
;
502 * @brief DeInitialize the OSPI MSP.
503 * @param hospi : OSPI handle
506 __weak
void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef
*hospi
)
508 /* Prevent unused argument(s) compilation warning */
511 /* NOTE : This function should not be modified, when the callback is needed,
512 the HAL_OSPI_MspDeInit can be implemented in the user file
520 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
521 * @brief OSPI Transmit/Receive functions
524 ===============================================================================
525 ##### IO operation functions #####
526 ===============================================================================
528 This subsection provides a set of functions allowing to :
529 (+) Handle the interrupts.
530 (+) Handle the command sequence (regular and Hyperbus).
531 (+) Handle the Hyperbus configuration.
532 (+) Transmit data in blocking, interrupt or DMA mode.
533 (+) Receive data in blocking, interrupt or DMA mode.
534 (+) Manage the auto-polling functional mode.
535 (+) Manage the memory-mapped functional mode.
542 * @brief Handle OSPI interrupt request.
543 * @param hospi : OSPI handle
546 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef
*hospi
)
548 __IO
uint32_t *data_reg
= &hospi
->Instance
->DR
;
549 uint32_t flag
= hospi
->Instance
->SR
;
550 uint32_t itsource
= hospi
->Instance
->CR
;
551 uint32_t currentstate
= hospi
->State
;
553 /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
554 if (((flag
& HAL_OSPI_FLAG_FT
) != 0U) && ((itsource
& HAL_OSPI_IT_FT
) != 0U))
556 if (currentstate
== HAL_OSPI_STATE_BUSY_TX
)
558 /* Write a data in the fifo */
559 *((__IO
uint8_t *)data_reg
) = *hospi
->pBuffPtr
;
563 else if (currentstate
== HAL_OSPI_STATE_BUSY_RX
)
565 /* Read a data from the fifo */
566 *hospi
->pBuffPtr
= *((__IO
uint8_t *)data_reg
);
575 if (hospi
->XferCount
== 0U)
577 /* All data have been received or transmitted for the transfer */
578 /* Disable fifo threshold interrupt */
579 __HAL_OSPI_DISABLE_IT(hospi
, HAL_OSPI_IT_FT
);
582 /* Fifo threshold callback */
583 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
584 hospi
->FifoThresholdCallback(hospi
);
586 HAL_OSPI_FifoThresholdCallback(hospi
);
589 /* OctoSPI transfer complete interrupt occurred ----------------------------*/
590 else if (((flag
& HAL_OSPI_FLAG_TC
) != 0U) && ((itsource
& HAL_OSPI_IT_TC
) != 0U))
592 if (currentstate
== HAL_OSPI_STATE_BUSY_RX
)
594 if ((hospi
->XferCount
> 0U) && ((flag
& OCTOSPI_SR_FLEVEL
) != 0U))
596 /* Read the last data received in the fifo */
597 *hospi
->pBuffPtr
= *((__IO
uint8_t *)data_reg
);
601 else if(hospi
->XferCount
== 0U)
604 hospi
->Instance
->FCR
= HAL_OSPI_FLAG_TC
;
606 /* Disable the interrupts */
607 __HAL_OSPI_DISABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TE
);
610 hospi
->State
= HAL_OSPI_STATE_READY
;
612 /* RX complete callback */
613 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
614 hospi
->RxCpltCallback(hospi
);
616 HAL_OSPI_RxCpltCallback(hospi
);
627 hospi
->Instance
->FCR
= HAL_OSPI_FLAG_TC
;
629 /* Disable the interrupts */
630 __HAL_OSPI_DISABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TE
);
633 hospi
->State
= HAL_OSPI_STATE_READY
;
635 if (currentstate
== HAL_OSPI_STATE_BUSY_TX
)
637 /* TX complete callback */
638 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
639 hospi
->TxCpltCallback(hospi
);
641 HAL_OSPI_TxCpltCallback(hospi
);
644 else if (currentstate
== HAL_OSPI_STATE_BUSY_CMD
)
646 /* Command complete callback */
647 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
648 hospi
->CmdCpltCallback(hospi
);
650 HAL_OSPI_CmdCpltCallback(hospi
);
653 else if (currentstate
== HAL_OSPI_STATE_ABORT
)
655 if (hospi
->ErrorCode
== HAL_OSPI_ERROR_NONE
)
657 /* Abort called by the user */
658 /* Abort complete callback */
659 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
660 hospi
->AbortCpltCallback(hospi
);
662 HAL_OSPI_AbortCpltCallback(hospi
);
667 /* Abort due to an error (eg : DMA error) */
669 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
670 hospi
->ErrorCallback(hospi
);
672 HAL_OSPI_ErrorCallback(hospi
);
682 /* OctoSPI status match interrupt occurred ---------------------------------*/
683 else if (((flag
& HAL_OSPI_FLAG_SM
) != 0U) && ((itsource
& HAL_OSPI_IT_SM
) != 0U))
686 hospi
->Instance
->FCR
= HAL_OSPI_FLAG_SM
;
688 /* Check if automatic poll mode stop is activated */
689 if ((hospi
->Instance
->CR
& OCTOSPI_CR_APMS
) != 0U)
691 /* Disable the interrupts */
692 __HAL_OSPI_DISABLE_IT(hospi
, HAL_OSPI_IT_SM
| HAL_OSPI_IT_TE
);
695 hospi
->State
= HAL_OSPI_STATE_READY
;
698 /* Status match callback */
699 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
700 hospi
->StatusMatchCallback(hospi
);
702 HAL_OSPI_StatusMatchCallback(hospi
);
705 /* OctoSPI transfer error interrupt occurred -------------------------------*/
706 else if (((flag
& HAL_OSPI_FLAG_TE
) != 0U) && ((itsource
& HAL_OSPI_IT_TE
) != 0U))
709 hospi
->Instance
->FCR
= HAL_OSPI_FLAG_TE
;
711 /* Disable all interrupts */
712 __HAL_OSPI_DISABLE_IT(hospi
, (HAL_OSPI_IT_TO
| HAL_OSPI_IT_SM
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TC
| HAL_OSPI_IT_TE
));
715 hospi
->ErrorCode
= HAL_OSPI_ERROR_TRANSFER
;
717 /* Check if the DMA is enabled */
718 if ((hospi
->Instance
->CR
& OCTOSPI_CR_DMAEN
) != 0U)
720 /* Disable the DMA transfer on the OctoSPI side */
721 CLEAR_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_DMAEN
);
723 /* Disable the DMA transfer on the DMA side */
724 hospi
->hmdma
->XferAbortCallback
= OSPI_DMAAbortCplt
;
725 if (HAL_MDMA_Abort_IT(hospi
->hmdma
) != HAL_OK
)
728 hospi
->State
= HAL_OSPI_STATE_READY
;
731 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
732 hospi
->ErrorCallback(hospi
);
734 HAL_OSPI_ErrorCallback(hospi
);
741 hospi
->State
= HAL_OSPI_STATE_READY
;
744 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
745 hospi
->ErrorCallback(hospi
);
747 HAL_OSPI_ErrorCallback(hospi
);
751 /* OctoSPI timeout interrupt occurred --------------------------------------*/
752 else if (((flag
& HAL_OSPI_FLAG_TO
) != 0U) && ((itsource
& HAL_OSPI_IT_TO
) != 0U))
755 hospi
->Instance
->FCR
= HAL_OSPI_FLAG_TO
;
757 /* Timeout callback */
758 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
759 hospi
->TimeOutCallback(hospi
);
761 HAL_OSPI_TimeOutCallback(hospi
);
771 * @brief Set the command configuration.
772 * @param hospi : OSPI handle
773 * @param cmd : structure that contains the command configuration information
774 * @param Timeout : Timeout duration
777 HAL_StatusTypeDef
HAL_OSPI_Command(OSPI_HandleTypeDef
*hospi
, OSPI_RegularCmdTypeDef
*cmd
, uint32_t Timeout
)
779 HAL_StatusTypeDef status
;
781 uint32_t tickstart
= HAL_GetTick();
783 /* Check the parameters of the command structure */
784 assert_param(IS_OSPI_OPERATION_TYPE(cmd
->OperationType
));
786 if (hospi
->Init
.DualQuad
== HAL_OSPI_DUALQUAD_DISABLE
)
788 assert_param(IS_OSPI_FLASH_ID(cmd
->FlashId
));
791 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
792 if (cmd
->InstructionMode
!= HAL_OSPI_INSTRUCTION_NONE
)
794 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd
->InstructionSize
));
795 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd
->InstructionDtrMode
));
798 assert_param(IS_OSPI_ADDRESS_MODE(cmd
->AddressMode
));
799 if (cmd
->AddressMode
!= HAL_OSPI_ADDRESS_NONE
)
801 assert_param(IS_OSPI_ADDRESS_SIZE (cmd
->AddressSize
));
802 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd
->AddressDtrMode
));
805 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd
->AlternateBytesMode
));
806 if (cmd
->AlternateBytesMode
!= HAL_OSPI_ALTERNATE_BYTES_NONE
)
808 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd
->AlternateBytesSize
));
809 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd
->AlternateBytesDtrMode
));
812 assert_param(IS_OSPI_DATA_MODE(cmd
->DataMode
));
813 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
815 if (cmd
->OperationType
== HAL_OSPI_OPTYPE_COMMON_CFG
)
817 assert_param(IS_OSPI_NUMBER_DATA (cmd
->NbData
));
819 assert_param(IS_OSPI_DATA_DTR_MODE(cmd
->DataDtrMode
));
820 assert_param(IS_OSPI_DUMMY_CYCLES (cmd
->DummyCycles
));
823 assert_param(IS_OSPI_DQS_MODE (cmd
->DQSMode
));
824 assert_param(IS_OSPI_SIOO_MODE(cmd
->SIOOMode
));
826 /* Check the state of the driver */
827 state
= hospi
->State
;
828 if (((state
== HAL_OSPI_STATE_READY
) && (hospi
->Init
.MemoryType
!= HAL_OSPI_MEMTYPE_HYPERBUS
)) ||
829 ((state
== HAL_OSPI_STATE_READ_CMD_CFG
) && ((cmd
->OperationType
== HAL_OSPI_OPTYPE_WRITE_CFG
) || (cmd
->OperationType
== HAL_OSPI_OPTYPE_WRAP_CFG
))) ||
830 ((state
== HAL_OSPI_STATE_WRITE_CMD_CFG
) && ((cmd
->OperationType
== HAL_OSPI_OPTYPE_READ_CFG
) || (cmd
->OperationType
== HAL_OSPI_OPTYPE_WRAP_CFG
))))
832 /* Wait till busy flag is reset */
833 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
835 if (status
== HAL_OK
)
837 /* Initialize error code */
838 hospi
->ErrorCode
= HAL_OSPI_ERROR_NONE
;
840 /* Configure the registers */
841 status
= OSPI_ConfigCmd(hospi
, cmd
);
843 if (status
== HAL_OK
)
845 if (cmd
->DataMode
== HAL_OSPI_DATA_NONE
)
847 /* When there is no data phase, the transfer start as soon as the configuration is done
848 so wait until TC flag is set to go back in idle state */
849 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
851 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
855 /* Update the state */
856 if (cmd
->OperationType
== HAL_OSPI_OPTYPE_COMMON_CFG
)
858 hospi
->State
= HAL_OSPI_STATE_CMD_CFG
;
860 else if (cmd
->OperationType
== HAL_OSPI_OPTYPE_READ_CFG
)
862 if (hospi
->State
== HAL_OSPI_STATE_WRITE_CMD_CFG
)
864 hospi
->State
= HAL_OSPI_STATE_CMD_CFG
;
868 hospi
->State
= HAL_OSPI_STATE_READ_CMD_CFG
;
871 else if (cmd
->OperationType
== HAL_OSPI_OPTYPE_WRITE_CFG
)
873 if (hospi
->State
== HAL_OSPI_STATE_READ_CMD_CFG
)
875 hospi
->State
= HAL_OSPI_STATE_CMD_CFG
;
879 hospi
->State
= HAL_OSPI_STATE_WRITE_CMD_CFG
;
884 /* Wrap configuration, no state change */
893 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
896 /* Return function status */
901 * @brief Set the command configuration in interrupt mode.
902 * @param hospi : OSPI handle
903 * @param cmd : structure that contains the command configuration information
904 * @note This function is used only in Indirect Read or Write Modes
907 HAL_StatusTypeDef
HAL_OSPI_Command_IT(OSPI_HandleTypeDef
*hospi
, OSPI_RegularCmdTypeDef
*cmd
)
909 HAL_StatusTypeDef status
;
910 uint32_t tickstart
= HAL_GetTick();
912 /* Check the parameters of the command structure */
913 assert_param(IS_OSPI_OPERATION_TYPE(cmd
->OperationType
));
915 if (hospi
->Init
.DualQuad
== HAL_OSPI_DUALQUAD_DISABLE
)
917 assert_param(IS_OSPI_FLASH_ID(cmd
->FlashId
));
920 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd
->InstructionMode
));
921 if (cmd
->InstructionMode
!= HAL_OSPI_INSTRUCTION_NONE
)
923 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd
->InstructionSize
));
924 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd
->InstructionDtrMode
));
927 assert_param(IS_OSPI_ADDRESS_MODE(cmd
->AddressMode
));
928 if (cmd
->AddressMode
!= HAL_OSPI_ADDRESS_NONE
)
930 assert_param(IS_OSPI_ADDRESS_SIZE (cmd
->AddressSize
));
931 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd
->AddressDtrMode
));
934 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd
->AlternateBytesMode
));
935 if (cmd
->AlternateBytesMode
!= HAL_OSPI_ALTERNATE_BYTES_NONE
)
937 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd
->AlternateBytesSize
));
938 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd
->AlternateBytesDtrMode
));
941 assert_param(IS_OSPI_DATA_MODE(cmd
->DataMode
));
942 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
944 assert_param(IS_OSPI_NUMBER_DATA (cmd
->NbData
));
945 assert_param(IS_OSPI_DATA_DTR_MODE(cmd
->DataDtrMode
));
946 assert_param(IS_OSPI_DUMMY_CYCLES (cmd
->DummyCycles
));
949 assert_param(IS_OSPI_DQS_MODE (cmd
->DQSMode
));
950 assert_param(IS_OSPI_SIOO_MODE(cmd
->SIOOMode
));
952 /* Check the state of the driver */
953 if ((hospi
->State
== HAL_OSPI_STATE_READY
) && (cmd
->OperationType
== HAL_OSPI_OPTYPE_COMMON_CFG
) &&
954 (cmd
->DataMode
== HAL_OSPI_DATA_NONE
) && (hospi
->Init
.MemoryType
!= HAL_OSPI_MEMTYPE_HYPERBUS
))
956 /* Wait till busy flag is reset */
957 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, hospi
->Timeout
);
959 if (status
== HAL_OK
)
961 /* Initialize error code */
962 hospi
->ErrorCode
= HAL_OSPI_ERROR_NONE
;
964 /* Clear flags related to interrupt */
965 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_TC
);
967 /* Configure the registers */
968 status
= OSPI_ConfigCmd(hospi
, cmd
);
970 if (status
== HAL_OK
)
972 /* Update the state */
973 hospi
->State
= HAL_OSPI_STATE_BUSY_CMD
;
975 /* Enable the transfer complete and transfer error interrupts */
976 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_TE
);
983 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
986 /* Return function status */
991 * @brief Configure the Hyperbus parameters.
992 * @param hospi : OSPI handle
993 * @param cfg : Structure containing the Hyperbus configuration
994 * @param Timeout : Timeout duration
997 HAL_StatusTypeDef
HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef
*hospi
, OSPI_HyperbusCfgTypeDef
*cfg
, uint32_t Timeout
)
999 HAL_StatusTypeDef status
;
1001 uint32_t tickstart
= HAL_GetTick();
1003 /* Check the parameters of the hyperbus configuration structure */
1004 assert_param(IS_OSPI_RW_RECOVERY_TIME (cfg
->RWRecoveryTime
));
1005 assert_param(IS_OSPI_ACCESS_TIME (cfg
->AccessTime
));
1006 assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg
->WriteZeroLatency
));
1007 assert_param(IS_OSPI_LATENCY_MODE (cfg
->LatencyMode
));
1009 /* Check the state of the driver */
1010 state
= hospi
->State
;
1011 if ((state
== HAL_OSPI_STATE_HYPERBUS_INIT
) || (state
== HAL_OSPI_STATE_READY
))
1013 /* Wait till busy flag is reset */
1014 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
1016 if (status
== HAL_OK
)
1018 /* Configure Hyperbus configuration Latency register */
1019 WRITE_REG(hospi
->Instance
->HLCR
, ((cfg
->RWRecoveryTime
<< OCTOSPI_HLCR_TRWR_Pos
) |
1020 (cfg
->AccessTime
<< OCTOSPI_HLCR_TACC_Pos
) |
1021 cfg
->WriteZeroLatency
| cfg
->LatencyMode
));
1023 /* Update the state */
1024 hospi
->State
= HAL_OSPI_STATE_READY
;
1030 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1033 /* Return function status */
1038 * @brief Set the Hyperbus command configuration.
1039 * @param hospi : OSPI handle
1040 * @param cmd : Structure containing the Hyperbus command
1041 * @param Timeout : Timeout duration
1042 * @retval HAL status
1044 HAL_StatusTypeDef
HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef
*hospi
, OSPI_HyperbusCmdTypeDef
*cmd
, uint32_t Timeout
)
1046 HAL_StatusTypeDef status
;
1047 uint32_t tickstart
= HAL_GetTick();
1049 /* Check the parameters of the hyperbus command structure */
1050 assert_param(IS_OSPI_ADDRESS_SPACE(cmd
->AddressSpace
));
1051 assert_param(IS_OSPI_ADDRESS_SIZE (cmd
->AddressSize
));
1052 assert_param(IS_OSPI_NUMBER_DATA (cmd
->NbData
));
1053 assert_param(IS_OSPI_DQS_MODE (cmd
->DQSMode
));
1055 /* Check the state of the driver */
1056 if ((hospi
->State
== HAL_OSPI_STATE_READY
) && (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
))
1058 /* Wait till busy flag is reset */
1059 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
1061 if (status
== HAL_OK
)
1063 /* Re-initialize the value of the functional mode */
1064 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, 0U);
1066 /* Configure the address space in the DCR1 register */
1067 MODIFY_REG(hospi
->Instance
->DCR1
, OCTOSPI_DCR1_MTYP_0
, cmd
->AddressSpace
);
1069 /* Configure the CCR and WCCR registers with the address size and the following configuration :
1070 - DQS signal enabled (used as RWDS)
1071 - DTR mode enabled on address and data
1072 - address and data on 8 lines */
1073 WRITE_REG(hospi
->Instance
->CCR
, (cmd
->DQSMode
| OCTOSPI_CCR_DDTR
| OCTOSPI_CCR_DMODE_2
|
1074 cmd
->AddressSize
| OCTOSPI_CCR_ADDTR
| OCTOSPI_CCR_ADMODE_2
));
1075 WRITE_REG(hospi
->Instance
->WCCR
, (cmd
->DQSMode
| OCTOSPI_WCCR_DDTR
| OCTOSPI_WCCR_DMODE_2
|
1076 cmd
->AddressSize
| OCTOSPI_WCCR_ADDTR
| OCTOSPI_WCCR_ADMODE_2
));
1078 /* Configure the DLR register with the number of data */
1079 WRITE_REG(hospi
->Instance
->DLR
, (cmd
->NbData
- 1U));
1081 /* Configure the AR register with the address value */
1082 WRITE_REG(hospi
->Instance
->AR
, cmd
->Address
);
1084 /* Update the state */
1085 hospi
->State
= HAL_OSPI_STATE_CMD_CFG
;
1091 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1094 /* Return function status */
1099 * @brief Transmit an amount of data in blocking mode.
1100 * @param hospi : OSPI handle
1101 * @param pData : pointer to data buffer
1102 * @param Timeout : Timeout duration
1103 * @note This function is used only in Indirect Write Mode
1104 * @retval HAL status
1106 HAL_StatusTypeDef
HAL_OSPI_Transmit(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
, uint32_t Timeout
)
1108 HAL_StatusTypeDef status
;
1109 uint32_t tickstart
= HAL_GetTick();
1110 __IO
uint32_t *data_reg
= &hospi
->Instance
->DR
;
1112 /* Check the data pointer allocation */
1116 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1120 /* Check the state */
1121 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1123 /* Configure counters and size */
1124 hospi
->XferCount
= READ_REG(hospi
->Instance
->DLR
) + 1U;
1125 hospi
->XferSize
= hospi
->XferCount
;
1126 hospi
->pBuffPtr
= pData
;
1128 /* Configure CR register with functional mode as indirect write */
1129 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
1133 /* Wait till fifo threshold flag is set to send data */
1134 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_FT
, SET
, tickstart
, Timeout
);
1136 if (status
!= HAL_OK
)
1141 *((__IO
uint8_t *)data_reg
) = *hospi
->pBuffPtr
;
1144 } while (hospi
->XferCount
> 0U);
1146 if (status
== HAL_OK
)
1148 /* Wait till transfer complete flag is set to go back in idle state */
1149 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
1151 if (status
== HAL_OK
)
1153 /* Clear transfer complete flag */
1154 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
1157 hospi
->State
= HAL_OSPI_STATE_READY
;
1164 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1168 /* Return function status */
1173 * @brief Receive an amount of data in blocking mode.
1174 * @param hospi : OSPI handle
1175 * @param pData : pointer to data buffer
1176 * @param Timeout : Timeout duration
1177 * @note This function is used only in Indirect Read Mode
1178 * @retval HAL status
1180 HAL_StatusTypeDef
HAL_OSPI_Receive(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
, uint32_t Timeout
)
1182 HAL_StatusTypeDef status
;
1183 uint32_t tickstart
= HAL_GetTick();
1184 __IO
uint32_t *data_reg
= &hospi
->Instance
->DR
;
1185 uint32_t addr_reg
= hospi
->Instance
->AR
;
1186 uint32_t ir_reg
= hospi
->Instance
->IR
;
1188 /* Check the data pointer allocation */
1192 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1196 /* Check the state */
1197 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1199 /* Configure counters and size */
1200 hospi
->XferCount
= READ_REG(hospi
->Instance
->DLR
) + 1U;
1201 hospi
->XferSize
= hospi
->XferCount
;
1202 hospi
->pBuffPtr
= pData
;
1204 /* Configure CR register with functional mode as indirect read */
1205 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1207 /* Trig the transfer by re-writing address or instruction register */
1208 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
1210 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1214 if (READ_BIT(hospi
->Instance
->CCR
, OCTOSPI_CCR_ADMODE
) != HAL_OSPI_ADDRESS_NONE
)
1216 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1220 WRITE_REG(hospi
->Instance
->IR
, ir_reg
);
1226 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1227 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, (HAL_OSPI_FLAG_FT
| HAL_OSPI_FLAG_TC
), SET
, tickstart
, Timeout
);
1229 if (status
!= HAL_OK
)
1234 *hospi
->pBuffPtr
= *((__IO
uint8_t *)data_reg
);
1237 } while(hospi
->XferCount
> 0U);
1239 if (status
== HAL_OK
)
1241 /* Wait till transfer complete flag is set to go back in idle state */
1242 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_TC
, SET
, tickstart
, Timeout
);
1244 if (status
== HAL_OK
)
1246 /* Clear transfer complete flag */
1247 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
1250 hospi
->State
= HAL_OSPI_STATE_READY
;
1257 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1261 /* Return function status */
1266 * @brief Send an amount of data in non-blocking mode with interrupt.
1267 * @param hospi : OSPI handle
1268 * @param pData : pointer to data buffer
1269 * @note This function is used only in Indirect Write Mode
1270 * @retval HAL status
1272 HAL_StatusTypeDef
HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
)
1274 HAL_StatusTypeDef status
= HAL_OK
;
1276 /* Check the data pointer allocation */
1280 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1284 /* Check the state */
1285 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1287 /* Configure counters and size */
1288 hospi
->XferCount
= READ_REG(hospi
->Instance
->DLR
) + 1U;
1289 hospi
->XferSize
= hospi
->XferCount
;
1290 hospi
->pBuffPtr
= pData
;
1292 /* Configure CR register with functional mode as indirect write */
1293 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
1295 /* Clear flags related to interrupt */
1296 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_TC
);
1298 /* Update the state */
1299 hospi
->State
= HAL_OSPI_STATE_BUSY_TX
;
1301 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1302 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TE
);
1307 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1311 /* Return function status */
1316 * @brief Receive an amount of data in non-blocking mode with interrupt.
1317 * @param hospi : OSPI handle
1318 * @param pData : pointer to data buffer
1319 * @note This function is used only in Indirect Read Mode
1320 * @retval HAL status
1322 HAL_StatusTypeDef
HAL_OSPI_Receive_IT(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
)
1324 HAL_StatusTypeDef status
= HAL_OK
;
1325 uint32_t addr_reg
= hospi
->Instance
->AR
;
1326 uint32_t ir_reg
= hospi
->Instance
->IR
;
1328 /* Check the data pointer allocation */
1332 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1336 /* Check the state */
1337 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1339 /* Configure counters and size */
1340 hospi
->XferCount
= READ_REG(hospi
->Instance
->DLR
) + 1U;
1341 hospi
->XferSize
= hospi
->XferCount
;
1342 hospi
->pBuffPtr
= pData
;
1344 /* Configure CR register with functional mode as indirect read */
1345 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1347 /* Clear flags related to interrupt */
1348 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_TC
);
1350 /* Update the state */
1351 hospi
->State
= HAL_OSPI_STATE_BUSY_RX
;
1353 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1354 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TE
);
1356 /* Trig the transfer by re-writing address or instruction register */
1357 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
1359 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1363 if (READ_BIT(hospi
->Instance
->CCR
, OCTOSPI_CCR_ADMODE
) != HAL_OSPI_ADDRESS_NONE
)
1365 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1369 WRITE_REG(hospi
->Instance
->IR
, ir_reg
);
1376 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1380 /* Return function status */
1385 * @brief Send an amount of data in non-blocking mode with DMA.
1386 * @param hospi : OSPI handle
1387 * @param pData : pointer to data buffer
1388 * @note This function is used only in Indirect Write Mode
1389 * @note If DMA peripheral access is configured as halfword, the number
1390 * of data and the fifo threshold should be aligned on halfword
1391 * @note If DMA peripheral access is configured as word, the number
1392 * of data and the fifo threshold should be aligned on word
1393 * @retval HAL status
1395 HAL_StatusTypeDef
HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
)
1397 HAL_StatusTypeDef status
= HAL_OK
;
1398 uint32_t data_size
= hospi
->Instance
->DLR
+ 1U;
1400 /* Check the data pointer allocation */
1404 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1408 /* Check the state */
1409 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1411 hospi
->XferCount
= data_size
;
1414 hospi
->XferSize
= hospi
->XferCount
;
1415 hospi
->pBuffPtr
= pData
;
1417 /* Configure CR register with functional mode as indirect write */
1418 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE
);
1420 /* Clear flags related to interrupt */
1421 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_TC
);
1423 /* Update the state */
1424 hospi
->State
= HAL_OSPI_STATE_BUSY_TX
;
1426 /* Set the MDMA transfer complete callback */
1427 hospi
->hmdma
->XferCpltCallback
= OSPI_DMACplt
;
1429 /* Set the MDMA error callback */
1430 hospi
->hmdma
->XferErrorCallback
= OSPI_DMAError
;
1432 /* Clear the MDMA abort callback */
1433 hospi
->hmdma
->XferAbortCallback
= NULL
;
1435 /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment to disable */
1436 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_DINC
| MDMA_CTCR_DINCOS
) ,MDMA_DEST_INC_DISABLE
);
1438 /* Update MDMA configuration with the correct SourceInc field for Write operation */
1439 if (hospi
->hmdma
->Init
.SourceDataSize
== MDMA_SRC_DATASIZE_BYTE
)
1441 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_SINC
| MDMA_CTCR_SINCOS
) , MDMA_SRC_INC_BYTE
);
1443 else if (hospi
->hmdma
->Init
.SourceDataSize
== MDMA_SRC_DATASIZE_HALFWORD
)
1445 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_SINC
| MDMA_CTCR_SINCOS
) , MDMA_SRC_INC_HALFWORD
);
1447 else if (hospi
->hmdma
->Init
.SourceDataSize
== MDMA_SRC_DATASIZE_WORD
)
1449 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_SINC
| MDMA_CTCR_SINCOS
) , MDMA_SRC_INC_WORD
);
1453 /* in case of incorrect source data size */
1454 hospi
->ErrorCode
|= HAL_OSPI_ERROR_DMA
;
1458 /* Enable the transmit MDMA Channel */
1459 if (HAL_MDMA_Start_IT(hospi
->hmdma
, (uint32_t)pData
, (uint32_t)&hospi
->Instance
->DR
, hospi
->XferSize
,1) == HAL_OK
)
1461 /* Enable the transfer error interrupt */
1462 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TE
);
1464 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1469 hospi
->ErrorCode
= HAL_OSPI_ERROR_DMA
;
1470 hospi
->State
= HAL_OSPI_STATE_READY
;
1477 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1481 /* Return function status */
1486 * @brief Receive an amount of data in non-blocking mode with DMA.
1487 * @param hospi : OSPI handle
1488 * @param pData : pointer to data buffer.
1489 * @note This function is used only in Indirect Read Mode
1490 * @note If DMA peripheral access is configured as halfword, the number
1491 * of data and the fifo threshold should be aligned on halfword
1492 * @note If DMA peripheral access is configured as word, the number
1493 * of data and the fifo threshold should be aligned on word
1494 * @retval HAL status
1496 HAL_StatusTypeDef
HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef
*hospi
, uint8_t *pData
)
1498 HAL_StatusTypeDef status
= HAL_OK
;
1499 uint32_t data_size
= hospi
->Instance
->DLR
+ 1U;
1500 uint32_t addr_reg
= hospi
->Instance
->AR
;
1501 uint32_t ir_reg
= hospi
->Instance
->IR
;
1503 /* Check the data pointer allocation */
1507 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
1511 /* Check the state */
1512 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1514 hospi
->XferCount
= data_size
;
1517 hospi
->XferSize
= hospi
->XferCount
;
1518 hospi
->pBuffPtr
= pData
;
1520 /* Configure CR register with functional mode as indirect read */
1521 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, OSPI_FUNCTIONAL_MODE_INDIRECT_READ
);
1523 /* Clear flags related to interrupt */
1524 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_TC
);
1526 /* Update the state */
1527 hospi
->State
= HAL_OSPI_STATE_BUSY_RX
;
1529 /* Set the DMA transfer complete callback */
1530 hospi
->hmdma
->XferCpltCallback
= OSPI_DMACplt
;
1532 /* Set the DMA error callback */
1533 hospi
->hmdma
->XferErrorCallback
= OSPI_DMAError
;
1535 /* Clear the DMA abort callback */
1536 hospi
->hmdma
->XferAbortCallback
= NULL
;
1538 /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */
1539 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_SINC
| MDMA_CTCR_SINCOS
) , MDMA_SRC_INC_DISABLE
);
1541 /* Update MDMA configuration with the correct DestinationInc field for read operation */
1542 if (hospi
->hmdma
->Init
.DestDataSize
== MDMA_DEST_DATASIZE_BYTE
)
1544 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_DINC
| MDMA_CTCR_DINCOS
) , MDMA_DEST_INC_BYTE
);
1546 else if (hospi
->hmdma
->Init
.DestDataSize
== MDMA_DEST_DATASIZE_HALFWORD
)
1548 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_DINC
| MDMA_CTCR_DINCOS
) , MDMA_DEST_INC_HALFWORD
);
1550 else if (hospi
->hmdma
->Init
.DestDataSize
== MDMA_DEST_DATASIZE_WORD
)
1552 MODIFY_REG(hospi
->hmdma
->Instance
->CTCR
, (MDMA_CTCR_DINC
| MDMA_CTCR_DINCOS
) , MDMA_DEST_INC_WORD
);
1556 /* in case of incorrect destination data size */
1557 hospi
->ErrorCode
|= HAL_OSPI_ERROR_DMA
;
1561 /* Enable the transmit MDMA Channel */
1562 if (HAL_MDMA_Start_IT(hospi
->hmdma
, (uint32_t)&hospi
->Instance
->DR
, (uint32_t)pData
, hospi
->XferSize
, 1) == HAL_OK
)
1564 /* Enable the transfer error interrupt */
1565 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TE
);
1567 /* Trig the transfer by re-writing address or instruction register */
1568 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
1570 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1574 if (READ_BIT(hospi
->Instance
->CCR
, OCTOSPI_CCR_ADMODE
) != HAL_OSPI_ADDRESS_NONE
)
1576 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1580 WRITE_REG(hospi
->Instance
->IR
, ir_reg
);
1584 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/
1589 hospi
->ErrorCode
= HAL_OSPI_ERROR_DMA
;
1590 hospi
->State
= HAL_OSPI_STATE_READY
;
1597 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1601 /* Return function status */
1606 * @brief Configure the OSPI Automatic Polling Mode in blocking mode.
1607 * @param hospi : OSPI handle
1608 * @param cfg : structure that contains the polling configuration information.
1609 * @param Timeout : Timeout duration
1610 * @note This function is used only in Automatic Polling Mode
1611 * @retval HAL status
1613 HAL_StatusTypeDef
HAL_OSPI_AutoPolling(OSPI_HandleTypeDef
*hospi
, OSPI_AutoPollingTypeDef
*cfg
, uint32_t Timeout
)
1615 HAL_StatusTypeDef status
;
1616 uint32_t tickstart
= HAL_GetTick();
1617 uint32_t addr_reg
= hospi
->Instance
->AR
;
1618 uint32_t ir_reg
= hospi
->Instance
->IR
;
1619 #ifdef USE_FULL_ASSERT
1620 uint32_t dlr_reg
= hospi
->Instance
->DLR
;
1623 /* Check the parameters of the autopolling configuration structure */
1624 assert_param(IS_OSPI_MATCH_MODE (cfg
->MatchMode
));
1625 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg
->AutomaticStop
));
1626 assert_param(IS_OSPI_INTERVAL (cfg
->Interval
));
1627 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg
+1U));
1629 /* Check the state */
1630 if ((hospi
->State
== HAL_OSPI_STATE_CMD_CFG
) && (cfg
->AutomaticStop
== HAL_OSPI_AUTOMATIC_STOP_ENABLE
))
1632 /* Wait till busy flag is reset */
1633 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, Timeout
);
1635 if (status
== HAL_OK
)
1637 /* Configure registers */
1638 WRITE_REG (hospi
->Instance
->PSMAR
, cfg
->Match
);
1639 WRITE_REG (hospi
->Instance
->PSMKR
, cfg
->Mask
);
1640 WRITE_REG (hospi
->Instance
->PIR
, cfg
->Interval
);
1641 MODIFY_REG(hospi
->Instance
->CR
, (OCTOSPI_CR_PMM
| OCTOSPI_CR_APMS
| OCTOSPI_CR_FMODE
),
1642 (cfg
->MatchMode
| cfg
->AutomaticStop
| OSPI_FUNCTIONAL_MODE_AUTO_POLLING
));
1644 /* Trig the transfer by re-writing address or instruction register */
1645 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
1647 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1651 if (READ_BIT(hospi
->Instance
->CCR
, OCTOSPI_CCR_ADMODE
) != HAL_OSPI_ADDRESS_NONE
)
1653 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1657 WRITE_REG(hospi
->Instance
->IR
, ir_reg
);
1661 /* Wait till status match flag is set to go back in idle state */
1662 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_SM
, SET
, tickstart
, Timeout
);
1664 if (status
== HAL_OK
)
1666 /* Clear status match flag */
1667 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_SM
);
1670 hospi
->State
= HAL_OSPI_STATE_READY
;
1677 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1680 /* Return function status */
1685 * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode.
1686 * @param hospi : OSPI handle
1687 * @param cfg : structure that contains the polling configuration information.
1688 * @note This function is used only in Automatic Polling Mode
1689 * @retval HAL status
1691 HAL_StatusTypeDef
HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef
*hospi
, OSPI_AutoPollingTypeDef
*cfg
)
1693 HAL_StatusTypeDef status
;
1694 uint32_t tickstart
= HAL_GetTick();
1695 uint32_t addr_reg
= hospi
->Instance
->AR
;
1696 uint32_t ir_reg
= hospi
->Instance
->IR
;
1697 #ifdef USE_FULL_ASSERT
1698 uint32_t dlr_reg
= hospi
->Instance
->DLR
;
1701 /* Check the parameters of the autopolling configuration structure */
1702 assert_param(IS_OSPI_MATCH_MODE (cfg
->MatchMode
));
1703 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg
->AutomaticStop
));
1704 assert_param(IS_OSPI_INTERVAL (cfg
->Interval
));
1705 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg
+1U));
1707 /* Check the state */
1708 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1710 /* Wait till busy flag is reset */
1711 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, hospi
->Timeout
);
1713 if (status
== HAL_OK
)
1715 /* Configure registers */
1716 WRITE_REG (hospi
->Instance
->PSMAR
, cfg
->Match
);
1717 WRITE_REG (hospi
->Instance
->PSMKR
, cfg
->Mask
);
1718 WRITE_REG (hospi
->Instance
->PIR
, cfg
->Interval
);
1719 MODIFY_REG(hospi
->Instance
->CR
, (OCTOSPI_CR_PMM
| OCTOSPI_CR_APMS
| OCTOSPI_CR_FMODE
),
1720 (cfg
->MatchMode
| cfg
->AutomaticStop
| OSPI_FUNCTIONAL_MODE_AUTO_POLLING
));
1722 /* Clear flags related to interrupt */
1723 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TE
| HAL_OSPI_FLAG_SM
);
1726 hospi
->State
= HAL_OSPI_STATE_BUSY_AUTO_POLLING
;
1728 /* Enable the status match and transfer error interrupts */
1729 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_SM
| HAL_OSPI_IT_TE
);
1731 /* Trig the transfer by re-writing address or instruction register */
1732 if (hospi
->Init
.MemoryType
== HAL_OSPI_MEMTYPE_HYPERBUS
)
1734 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1738 if (READ_BIT(hospi
->Instance
->CCR
, OCTOSPI_CCR_ADMODE
) != HAL_OSPI_ADDRESS_NONE
)
1740 WRITE_REG(hospi
->Instance
->AR
, addr_reg
);
1744 WRITE_REG(hospi
->Instance
->IR
, ir_reg
);
1752 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1755 /* Return function status */
1760 * @brief Configure the Memory Mapped mode.
1761 * @param hospi : OSPI handle
1762 * @param cfg : structure that contains the memory mapped configuration information.
1763 * @note This function is used only in Memory mapped Mode
1764 * @retval HAL status
1766 HAL_StatusTypeDef
HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef
*hospi
, OSPI_MemoryMappedTypeDef
*cfg
)
1768 HAL_StatusTypeDef status
;
1769 uint32_t tickstart
= HAL_GetTick();
1771 /* Check the parameters of the memory-mapped configuration structure */
1772 assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg
->TimeOutActivation
));
1774 /* Check the state */
1775 if (hospi
->State
== HAL_OSPI_STATE_CMD_CFG
)
1777 /* Wait till busy flag is reset */
1778 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, hospi
->Timeout
);
1780 if (status
== HAL_OK
)
1783 hospi
->State
= HAL_OSPI_STATE_BUSY_MEM_MAPPED
;
1785 if (cfg
->TimeOutActivation
== HAL_OSPI_TIMEOUT_COUNTER_ENABLE
)
1787 assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg
->TimeOutPeriod
));
1789 /* Configure register */
1790 WRITE_REG(hospi
->Instance
->LPTR
, cfg
->TimeOutPeriod
);
1792 /* Clear flags related to interrupt */
1793 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TO
);
1795 /* Enable the timeout interrupt */
1796 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TO
);
1799 /* Configure CR register with functional mode as memory-mapped */
1800 MODIFY_REG(hospi
->Instance
->CR
, (OCTOSPI_CR_TCEN
| OCTOSPI_CR_FMODE
),
1801 (cfg
->TimeOutActivation
| OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED
));
1807 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
1810 /* Return function status */
1815 * @brief Transfer Error callback.
1816 * @param hospi : OSPI handle
1819 __weak
void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef
*hospi
)
1821 /* Prevent unused argument(s) compilation warning */
1824 /* NOTE : This function should not be modified, when the callback is needed,
1825 the HAL_OSPI_ErrorCallback could be implemented in the user file
1830 * @brief Abort completed callback.
1831 * @param hospi : OSPI handle
1834 __weak
void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef
*hospi
)
1836 /* Prevent unused argument(s) compilation warning */
1839 /* NOTE: This function should not be modified, when the callback is needed,
1840 the HAL_OSPI_AbortCpltCallback could be implemented in the user file
1845 * @brief FIFO Threshold callback.
1846 * @param hospi : OSPI handle
1849 __weak
void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef
*hospi
)
1851 /* Prevent unused argument(s) compilation warning */
1854 /* NOTE : This function should not be modified, when the callback is needed,
1855 the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
1860 * @brief Command completed callback.
1861 * @param hospi : OSPI handle
1864 __weak
void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef
*hospi
)
1866 /* Prevent unused argument(s) compilation warning */
1869 /* NOTE: This function should not be modified, when the callback is needed,
1870 the HAL_OSPI_CmdCpltCallback could be implemented in the user file
1875 * @brief Rx Transfer completed callback.
1876 * @param hospi : OSPI handle
1879 __weak
void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef
*hospi
)
1881 /* Prevent unused argument(s) compilation warning */
1884 /* NOTE: This function should not be modified, when the callback is needed,
1885 the HAL_OSPI_RxCpltCallback could be implemented in the user file
1890 * @brief Tx Transfer completed callback.
1891 * @param hospi : OSPI handle
1894 __weak
void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef
*hospi
)
1896 /* Prevent unused argument(s) compilation warning */
1899 /* NOTE: This function should not be modified, when the callback is needed,
1900 the HAL_OSPI_TxCpltCallback could be implemented in the user file
1905 * @brief Rx Half Transfer completed callback.
1906 * @param hospi : OSPI handle
1909 __weak
void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef
*hospi
)
1911 /* Prevent unused argument(s) compilation warning */
1914 /* NOTE: This function should not be modified, when the callback is needed,
1915 the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
1920 * @brief Tx Half Transfer completed callback.
1921 * @param hospi : OSPI handle
1924 __weak
void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef
*hospi
)
1926 /* Prevent unused argument(s) compilation warning */
1929 /* NOTE: This function should not be modified, when the callback is needed,
1930 the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
1935 * @brief Status Match callback.
1936 * @param hospi : OSPI handle
1939 __weak
void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef
*hospi
)
1941 /* Prevent unused argument(s) compilation warning */
1944 /* NOTE : This function should not be modified, when the callback is needed,
1945 the HAL_OSPI_StatusMatchCallback could be implemented in the user file
1950 * @brief Timeout callback.
1951 * @param hospi : OSPI handle
1954 __weak
void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef
*hospi
)
1956 /* Prevent unused argument(s) compilation warning */
1959 /* NOTE : This function should not be modified, when the callback is needed,
1960 the HAL_OSPI_TimeOutCallback could be implemented in the user file
1964 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
1966 * @brief Register a User OSPI Callback
1967 * To be used instead of the weak (surcharged) predefined callback
1968 * @param hospi : OSPI handle
1969 * @param CallbackID : ID of the callback to be registered
1970 * This parameter can be one of the following values:
1971 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
1972 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
1973 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
1974 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
1975 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
1976 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
1977 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
1978 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
1979 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
1980 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
1981 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
1982 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
1983 * @param pCallback : pointer to the Callback function
1986 HAL_StatusTypeDef
HAL_OSPI_RegisterCallback (OSPI_HandleTypeDef
*hospi
, HAL_OSPI_CallbackIDTypeDef CallbackID
, pOSPI_CallbackTypeDef pCallback
)
1988 HAL_StatusTypeDef status
= HAL_OK
;
1990 if(pCallback
== NULL
)
1992 /* Update the error code */
1993 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
1997 if(hospi
->State
== HAL_OSPI_STATE_READY
)
2001 case HAL_OSPI_ERROR_CB_ID
:
2002 hospi
->ErrorCallback
= pCallback
;
2004 case HAL_OSPI_ABORT_CB_ID
:
2005 hospi
->AbortCpltCallback
= pCallback
;
2007 case HAL_OSPI_FIFO_THRESHOLD_CB_ID
:
2008 hospi
->FifoThresholdCallback
= pCallback
;
2010 case HAL_OSPI_CMD_CPLT_CB_ID
:
2011 hospi
->CmdCpltCallback
= pCallback
;
2013 case HAL_OSPI_RX_CPLT_CB_ID
:
2014 hospi
->RxCpltCallback
= pCallback
;
2016 case HAL_OSPI_TX_CPLT_CB_ID
:
2017 hospi
->TxCpltCallback
= pCallback
;
2019 case HAL_OSPI_RX_HALF_CPLT_CB_ID
:
2020 hospi
->RxHalfCpltCallback
= pCallback
;
2022 case HAL_OSPI_TX_HALF_CPLT_CB_ID
:
2023 hospi
->TxHalfCpltCallback
= pCallback
;
2025 case HAL_OSPI_STATUS_MATCH_CB_ID
:
2026 hospi
->StatusMatchCallback
= pCallback
;
2028 case HAL_OSPI_TIMEOUT_CB_ID
:
2029 hospi
->TimeOutCallback
= pCallback
;
2031 case HAL_OSPI_MSP_INIT_CB_ID
:
2032 hospi
->MspInitCallback
= pCallback
;
2034 case HAL_OSPI_MSP_DEINIT_CB_ID
:
2035 hospi
->MspDeInitCallback
= pCallback
;
2038 /* Update the error code */
2039 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2040 /* update return status */
2045 else if (hospi
->State
== HAL_OSPI_STATE_RESET
)
2049 case HAL_OSPI_MSP_INIT_CB_ID
:
2050 hospi
->MspInitCallback
= pCallback
;
2052 case HAL_OSPI_MSP_DEINIT_CB_ID
:
2053 hospi
->MspDeInitCallback
= pCallback
;
2056 /* Update the error code */
2057 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2058 /* update return status */
2065 /* Update the error code */
2066 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2067 /* update return status */
2075 * @brief Unregister a User OSPI Callback
2076 * OSPI Callback is redirected to the weak (surcharged) predefined callback
2077 * @param hospi : OSPI handle
2078 * @param CallbackID : ID of the callback to be unregistered
2079 * This parameter can be one of the following values:
2080 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
2081 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
2082 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2083 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
2084 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
2085 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
2086 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
2087 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
2088 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
2089 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
2090 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
2091 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
2094 HAL_StatusTypeDef
HAL_OSPI_UnRegisterCallback (OSPI_HandleTypeDef
*hospi
, HAL_OSPI_CallbackIDTypeDef CallbackID
)
2096 HAL_StatusTypeDef status
= HAL_OK
;
2098 if(hospi
->State
== HAL_OSPI_STATE_READY
)
2102 case HAL_OSPI_ERROR_CB_ID
:
2103 hospi
->ErrorCallback
= HAL_OSPI_ErrorCallback
;
2105 case HAL_OSPI_ABORT_CB_ID
:
2106 hospi
->AbortCpltCallback
= HAL_OSPI_AbortCpltCallback
;
2108 case HAL_OSPI_FIFO_THRESHOLD_CB_ID
:
2109 hospi
->FifoThresholdCallback
= HAL_OSPI_FifoThresholdCallback
;
2111 case HAL_OSPI_CMD_CPLT_CB_ID
:
2112 hospi
->CmdCpltCallback
= HAL_OSPI_CmdCpltCallback
;
2114 case HAL_OSPI_RX_CPLT_CB_ID
:
2115 hospi
->RxCpltCallback
= HAL_OSPI_RxCpltCallback
;
2117 case HAL_OSPI_TX_CPLT_CB_ID
:
2118 hospi
->TxCpltCallback
= HAL_OSPI_TxCpltCallback
;
2120 case HAL_OSPI_RX_HALF_CPLT_CB_ID
:
2121 hospi
->RxHalfCpltCallback
= HAL_OSPI_RxHalfCpltCallback
;
2123 case HAL_OSPI_TX_HALF_CPLT_CB_ID
:
2124 hospi
->TxHalfCpltCallback
= HAL_OSPI_TxHalfCpltCallback
;
2126 case HAL_OSPI_STATUS_MATCH_CB_ID
:
2127 hospi
->StatusMatchCallback
= HAL_OSPI_StatusMatchCallback
;
2129 case HAL_OSPI_TIMEOUT_CB_ID
:
2130 hospi
->TimeOutCallback
= HAL_OSPI_TimeOutCallback
;
2132 case HAL_OSPI_MSP_INIT_CB_ID
:
2133 hospi
->MspInitCallback
= HAL_OSPI_MspInit
;
2135 case HAL_OSPI_MSP_DEINIT_CB_ID
:
2136 hospi
->MspDeInitCallback
= HAL_OSPI_MspDeInit
;
2139 /* Update the error code */
2140 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2141 /* update return status */
2146 else if (hospi
->State
== HAL_OSPI_STATE_RESET
)
2150 case HAL_OSPI_MSP_INIT_CB_ID
:
2151 hospi
->MspInitCallback
= HAL_OSPI_MspInit
;
2153 case HAL_OSPI_MSP_DEINIT_CB_ID
:
2154 hospi
->MspDeInitCallback
= HAL_OSPI_MspDeInit
;
2157 /* Update the error code */
2158 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2159 /* update return status */
2166 /* Update the error code */
2167 hospi
->ErrorCode
|= HAL_OSPI_ERROR_INVALID_CALLBACK
;
2168 /* update return status */
2180 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
2181 * @brief OSPI control and State functions
2184 ===============================================================================
2185 ##### Peripheral Control and State functions #####
2186 ===============================================================================
2188 This subsection provides a set of functions allowing to :
2189 (+) Check in run-time the state of the driver.
2190 (+) Check the error code set during last operation.
2191 (+) Abort any operation.
2192 (+) Manage the Fifo threshold.
2193 (+) Configure the timeout duration used in the driver.
2200 * @brief Abort the current transmission.
2201 * @param hospi : OSPI handle
2202 * @retval HAL status
2204 HAL_StatusTypeDef
HAL_OSPI_Abort(OSPI_HandleTypeDef
*hospi
)
2206 HAL_StatusTypeDef status
= HAL_OK
;
2208 uint32_t tickstart
= HAL_GetTick();
2210 /* Check if the state is in one of the busy or configured states */
2211 state
= hospi
->State
;
2212 if (((state
& OSPI_BUSY_STATE_MASK
) != 0U) || ((state
& OSPI_CFG_STATE_MASK
) != 0U))
2214 /* Check if the DMA is enabled */
2215 if ((hospi
->Instance
->CR
& OCTOSPI_CR_DMAEN
) != 0U)
2217 /* Disable the DMA transfer on the OctoSPI side */
2218 CLEAR_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_DMAEN
);
2220 /* Disable the DMA transfer on the DMA side */
2221 status
= HAL_MDMA_Abort(hospi
->hmdma
);
2222 if (status
!= HAL_OK
)
2224 hospi
->ErrorCode
= HAL_OSPI_ERROR_DMA
;
2228 if (__HAL_OSPI_GET_FLAG(hospi
, HAL_OSPI_FLAG_BUSY
) != RESET
)
2230 /* Perform an abort of the OctoSPI */
2231 SET_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_ABORT
);
2233 /* Wait until the transfer complete flag is set to go back in idle state */
2234 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_TC
, SET
, tickstart
, hospi
->Timeout
);
2236 if (status
== HAL_OK
)
2238 /* Clear transfer complete flag */
2239 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
2241 /* Wait until the busy flag is reset to go back in idle state */
2242 status
= OSPI_WaitFlagStateUntilTimeout(hospi
, HAL_OSPI_FLAG_BUSY
, RESET
, tickstart
, hospi
->Timeout
);
2244 if (status
== HAL_OK
)
2247 hospi
->State
= HAL_OSPI_STATE_READY
;
2254 hospi
->State
= HAL_OSPI_STATE_READY
;
2260 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
2263 /* Return function status */
2268 * @brief Abort the current transmission (non-blocking function)
2269 * @param hospi : OSPI handle
2270 * @retval HAL status
2272 HAL_StatusTypeDef
HAL_OSPI_Abort_IT(OSPI_HandleTypeDef
*hospi
)
2274 HAL_StatusTypeDef status
= HAL_OK
;
2277 /* Check if the state is in one of the busy or configured states */
2278 state
= hospi
->State
;
2279 if (((state
& OSPI_BUSY_STATE_MASK
) != 0U) || ((state
& OSPI_CFG_STATE_MASK
) != 0U))
2281 /* Disable all interrupts */
2282 __HAL_OSPI_DISABLE_IT(hospi
, (HAL_OSPI_IT_TO
| HAL_OSPI_IT_SM
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TC
| HAL_OSPI_IT_TE
));
2285 hospi
->State
= HAL_OSPI_STATE_ABORT
;
2287 /* Check if the DMA is enabled */
2288 if ((hospi
->Instance
->CR
& OCTOSPI_CR_DMAEN
) != 0U)
2290 /* Disable the DMA transfer on the OctoSPI side */
2291 CLEAR_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_DMAEN
);
2293 /* Disable the DMA transfer on the DMA side */
2294 hospi
->hmdma
->XferAbortCallback
= OSPI_DMAAbortCplt
;
2295 if (HAL_MDMA_Abort_IT(hospi
->hmdma
) != HAL_OK
)
2298 hospi
->State
= HAL_OSPI_STATE_READY
;
2300 /* Abort callback */
2301 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2302 hospi
->AbortCpltCallback(hospi
);
2304 HAL_OSPI_AbortCpltCallback(hospi
);
2310 if (__HAL_OSPI_GET_FLAG(hospi
, HAL_OSPI_FLAG_BUSY
) != RESET
)
2312 /* Clear transfer complete flag */
2313 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
2315 /* Enable the transfer complete interrupts */
2316 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
);
2318 /* Perform an abort of the OctoSPI */
2319 SET_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_ABORT
);
2324 hospi
->State
= HAL_OSPI_STATE_READY
;
2326 /* Abort callback */
2327 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2328 hospi
->AbortCpltCallback(hospi
);
2330 HAL_OSPI_AbortCpltCallback(hospi
);
2338 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
2341 /* Return function status */
2345 /** @brief Set OSPI Fifo threshold.
2346 * @param hospi : OSPI handle.
2347 * @param Threshold : Threshold of the Fifo.
2348 * @retval HAL status
2350 HAL_StatusTypeDef
HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef
*hospi
, uint32_t Threshold
)
2352 HAL_StatusTypeDef status
= HAL_OK
;
2354 /* Check the state */
2355 if ((hospi
->State
& OSPI_BUSY_STATE_MASK
) == 0U)
2357 /* Synchronize initialization structure with the new fifo threshold value */
2358 hospi
->Init
.FifoThreshold
= Threshold
;
2360 /* Configure new fifo threshold */
2361 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FTHRES
, ((hospi
->Init
.FifoThreshold
-1U) << OCTOSPI_CR_FTHRES_Pos
));
2367 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_SEQUENCE
;
2370 /* Return function status */
2374 /** @brief Get OSPI Fifo threshold.
2375 * @param hospi : OSPI handle.
2376 * @retval Fifo threshold
2378 uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef
*hospi
)
2380 return ((READ_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_FTHRES
) >> OCTOSPI_CR_FTHRES_Pos
) + 1U);
2383 /** @brief Set OSPI timeout.
2384 * @param hospi : OSPI handle.
2385 * @param Timeout : Timeout for the memory access.
2388 HAL_StatusTypeDef
HAL_OSPI_SetTimeout(OSPI_HandleTypeDef
*hospi
, uint32_t Timeout
)
2390 hospi
->Timeout
= Timeout
;
2395 * @brief Return the OSPI error code.
2396 * @param hospi : OSPI handle
2397 * @retval OSPI Error Code
2399 uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef
*hospi
)
2401 return hospi
->ErrorCode
;
2405 * @brief Return the OSPI handle state.
2406 * @param hospi : OSPI handle
2409 uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef
*hospi
)
2411 /* Return OSPI handle state */
2412 return hospi
->State
;
2419 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
2420 * @brief OSPI IO Manager configuration function
2423 ===============================================================================
2424 ##### IO Manager configuration function #####
2425 ===============================================================================
2427 This subsection provides a set of functions allowing to :
2428 (+) Configure the IO manager.
2435 * @brief Configure the OctoSPI IO manager.
2436 * @param hospi : OSPI handle
2437 * @param cfg : Configuration of the IO Manager for the instance
2438 * @param Timeout : Timeout duration
2439 * @retval HAL status
2441 HAL_StatusTypeDef
HAL_OSPIM_Config(OSPI_HandleTypeDef
*hospi
, OSPIM_CfgTypeDef
*cfg
, uint32_t Timeout
)
2443 HAL_StatusTypeDef status
= HAL_OK
;
2445 uint8_t index
, ospi_enabled
= 0U, other_instance
;
2446 OSPIM_CfgTypeDef IOM_cfg
[OSPI_NB_INSTANCE
];
2448 /* Prevent unused argument(s) compilation warning */
2451 /* Check the parameters of the OctoSPI IO Manager configuration structure */
2452 assert_param(IS_OSPIM_PORT(cfg
->ClkPort
));
2453 assert_param(IS_OSPIM_PORT(cfg
->DQSPort
));
2454 assert_param(IS_OSPIM_PORT(cfg
->NCSPort
));
2455 assert_param(IS_OSPIM_IO_PORT(cfg
->IOLowPort
));
2456 assert_param(IS_OSPIM_IO_PORT(cfg
->IOHighPort
));
2457 assert_param(IS_OSPIM_REQ2ACKTIME(cfg
->Req2AckTime
));
2459 if (hospi
->Instance
== OCTOSPI1
)
2462 other_instance
= 1U;
2467 other_instance
= 0U;
2470 /**************** Get current configuration of the instances ****************/
2471 for (index
= 0U; index
< OSPI_NB_INSTANCE
; index
++)
2473 if (OSPIM_GetConfig(index
+1U, &(IOM_cfg
[index
])) != HAL_OK
)
2476 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
2480 if (status
== HAL_OK
)
2482 /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2483 if ((OCTOSPI1
->CR
& OCTOSPI_CR_EN
) != 0U)
2485 CLEAR_BIT(OCTOSPI1
->CR
, OCTOSPI_CR_EN
);
2486 ospi_enabled
|= 0x1U
;
2488 if ((OCTOSPI2
->CR
& OCTOSPI_CR_EN
) != 0U)
2490 CLEAR_BIT(OCTOSPI2
->CR
, OCTOSPI_CR_EN
);
2491 ospi_enabled
|= 0x2U
;
2494 /***************** Deactivation of previous configuration *****************/
2495 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[instance
].NCSPort
-1U)], OCTOSPIM_PCR_NCSEN
);
2496 if ((OCTOSPIM
->CR
& OCTOSPIM_CR_MUXEN
) != 0U)
2498 /* De-multiplexing should be performed */
2499 CLEAR_BIT(OCTOSPIM
->CR
, OCTOSPIM_CR_MUXEN
);
2501 if (other_instance
== 1U)
2503 SET_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[other_instance
].ClkPort
-1U)], OCTOSPIM_PCR_CLKSRC
);
2504 SET_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[other_instance
].DQSPort
-1U)], OCTOSPIM_PCR_DQSSRC
);
2505 SET_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[other_instance
].IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOLSRC_1
);
2506 SET_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[other_instance
].IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOHSRC_1
);
2511 if (IOM_cfg
[instance
].ClkPort
!= 0U)
2513 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[instance
].ClkPort
-1U)], OCTOSPIM_PCR_CLKEN
);
2514 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[instance
].DQSPort
-1U)], OCTOSPIM_PCR_DQSEN
);
2515 CLEAR_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[instance
].IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOLEN
);
2516 CLEAR_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[instance
].IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOHEN
);
2520 /********************* Deactivation of other instance *********************/
2521 if ((cfg
->ClkPort
== IOM_cfg
[other_instance
].ClkPort
) || (cfg
->DQSPort
== IOM_cfg
[other_instance
].DQSPort
) ||
2522 (cfg
->NCSPort
== IOM_cfg
[other_instance
].NCSPort
) || (cfg
->IOLowPort
== IOM_cfg
[other_instance
].IOLowPort
) ||
2523 (cfg
->IOHighPort
== IOM_cfg
[other_instance
].IOHighPort
))
2525 if ((cfg
->ClkPort
== IOM_cfg
[other_instance
].ClkPort
) && (cfg
->DQSPort
== IOM_cfg
[other_instance
].DQSPort
) &&
2526 (cfg
->IOLowPort
== IOM_cfg
[other_instance
].IOLowPort
) && (cfg
->IOHighPort
== IOM_cfg
[other_instance
].IOHighPort
))
2528 /* Multiplexing should be performed */
2529 SET_BIT(OCTOSPIM
->CR
, OCTOSPIM_CR_MUXEN
);
2533 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[other_instance
].ClkPort
-1U)], OCTOSPIM_PCR_CLKEN
);
2534 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[other_instance
].DQSPort
-1U)], OCTOSPIM_PCR_DQSEN
);
2535 CLEAR_BIT(OCTOSPIM
->PCR
[(IOM_cfg
[other_instance
].NCSPort
-1U)], OCTOSPIM_PCR_NCSEN
);
2536 CLEAR_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[other_instance
].IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOLEN
);
2537 CLEAR_BIT(OCTOSPIM
->PCR
[((IOM_cfg
[other_instance
].IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], OCTOSPIM_PCR_IOHEN
);
2541 /******************** Activation of new configuration *********************/
2542 MODIFY_REG(OCTOSPIM
->PCR
[(cfg
->NCSPort
-1U)], (OCTOSPIM_PCR_NCSEN
| OCTOSPIM_PCR_NCSSRC
), (OCTOSPIM_PCR_NCSEN
| (instance
<< OCTOSPIM_PCR_NCSSRC_Pos
)));
2544 if ((cfg
->Req2AckTime
- 1U) > ((OCTOSPIM
->CR
& OCTOSPIM_CR_REQ2ACK_TIME
) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos
))
2546 MODIFY_REG(OCTOSPIM
->CR
, OCTOSPIM_CR_REQ2ACK_TIME
, ((cfg
->Req2AckTime
- 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos
));
2549 if ((OCTOSPIM
->CR
& OCTOSPIM_CR_MUXEN
) != 0U)
2551 MODIFY_REG(OCTOSPIM
->PCR
[(cfg
->ClkPort
-1U)], (OCTOSPIM_PCR_CLKEN
| OCTOSPIM_PCR_CLKSRC
), OCTOSPIM_PCR_CLKEN
);
2552 MODIFY_REG(OCTOSPIM
->PCR
[(cfg
->DQSPort
-1U)], (OCTOSPIM_PCR_DQSEN
| OCTOSPIM_PCR_DQSSRC
), OCTOSPIM_PCR_DQSEN
);
2554 if ((cfg
->IOLowPort
& OCTOSPIM_PCR_IOLEN
) != 0U)
2556 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC
), OCTOSPIM_PCR_IOLEN
);
2560 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC
), OCTOSPIM_PCR_IOHEN
);
2563 if ((cfg
->IOHighPort
& OCTOSPIM_PCR_IOLEN
) != 0U)
2565 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC
), (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC_0
));
2569 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC
), (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC_0
));
2574 MODIFY_REG(OCTOSPIM
->PCR
[(cfg
->ClkPort
-1U)], (OCTOSPIM_PCR_CLKEN
| OCTOSPIM_PCR_CLKSRC
), (OCTOSPIM_PCR_CLKEN
| (instance
<< OCTOSPIM_PCR_CLKSRC_Pos
)));
2575 MODIFY_REG(OCTOSPIM
->PCR
[(cfg
->DQSPort
-1U)], (OCTOSPIM_PCR_DQSEN
| OCTOSPIM_PCR_DQSSRC
), (OCTOSPIM_PCR_DQSEN
| (instance
<< OCTOSPIM_PCR_DQSSRC_Pos
)));
2577 if ((cfg
->IOLowPort
& OCTOSPIM_PCR_IOLEN
) != 0U)
2579 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC
),
2580 (OCTOSPIM_PCR_IOLEN
| (instance
<< (OCTOSPIM_PCR_IOLSRC_Pos
+1U))));
2584 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOLowPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC
),
2585 (OCTOSPIM_PCR_IOHEN
| (instance
<< (OCTOSPIM_PCR_IOHSRC_Pos
+1U))));
2588 if ((cfg
->IOHighPort
& OCTOSPIM_PCR_IOLEN
) != 0U)
2590 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC
),
2591 (OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_IOLSRC_0
| (instance
<< (OCTOSPIM_PCR_IOLSRC_Pos
+1U))));
2595 MODIFY_REG(OCTOSPIM
->PCR
[((cfg
->IOHighPort
-1U)& OSPI_IOM_PORT_MASK
)], (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC
),
2596 (OCTOSPIM_PCR_IOHEN
| OCTOSPIM_PCR_IOHSRC_0
| (instance
<< (OCTOSPIM_PCR_IOHSRC_Pos
+1U))));
2600 /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2601 if ((ospi_enabled
& 0x1U
) != 0U)
2603 SET_BIT(OCTOSPI1
->CR
, OCTOSPI_CR_EN
);
2605 if ((ospi_enabled
& 0x2U
) != 0U)
2607 SET_BIT(OCTOSPI2
->CR
, OCTOSPI_CR_EN
);
2611 /* Return function status */
2623 * @brief DMA OSPI process complete callback.
2624 * @param hdma : DMA handle
2627 static void OSPI_DMACplt(MDMA_HandleTypeDef
*hmdma
)
2629 OSPI_HandleTypeDef
* hospi
= ( OSPI_HandleTypeDef
* )(hmdma
->Parent
);
2630 hospi
->XferCount
= 0;
2632 /* Disable the DMA transfer on the OctoSPI side */
2633 CLEAR_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_DMAEN
);
2635 /* Disable the DMA channel */
2636 __HAL_MDMA_DISABLE(hmdma
);
2638 /* Enable the OSPI transfer complete Interrupt */
2639 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
);
2643 * @brief DMA OSPI communication error callback.
2644 * @param hdma : DMA handle
2647 static void OSPI_DMAError(MDMA_HandleTypeDef
*hmdma
)
2649 OSPI_HandleTypeDef
* hospi
= ( OSPI_HandleTypeDef
* )(hmdma
->Parent
);
2650 hospi
->XferCount
= 0;
2651 hospi
->ErrorCode
= HAL_OSPI_ERROR_DMA
;
2653 /* Disable the DMA transfer on the OctoSPI side */
2654 CLEAR_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_DMAEN
);
2656 /* Abort the OctoSPI */
2657 if (HAL_OSPI_Abort_IT(hospi
) != HAL_OK
)
2659 /* Disable the interrupts */
2660 __HAL_OSPI_DISABLE_IT(hospi
, HAL_OSPI_IT_TC
| HAL_OSPI_IT_FT
| HAL_OSPI_IT_TE
);
2663 hospi
->State
= HAL_OSPI_STATE_READY
;
2665 /* Error callback */
2666 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2667 hospi
->ErrorCallback(hospi
);
2669 HAL_OSPI_ErrorCallback(hospi
);
2675 * @brief DMA OSPI abort complete callback.
2676 * @param hdma : DMA handle
2679 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef
*hmdma
)
2681 OSPI_HandleTypeDef
* hospi
= ( OSPI_HandleTypeDef
* )(hmdma
->Parent
);
2682 hospi
->XferCount
= 0;
2684 /* Check the state */
2685 if (hospi
->State
== HAL_OSPI_STATE_ABORT
)
2687 /* DMA abort called by OctoSPI abort */
2688 if (__HAL_OSPI_GET_FLAG(hospi
, HAL_OSPI_FLAG_BUSY
) != RESET
)
2690 /* Clear transfer complete flag */
2691 __HAL_OSPI_CLEAR_FLAG(hospi
, HAL_OSPI_FLAG_TC
);
2693 /* Enable the transfer complete interrupts */
2694 __HAL_OSPI_ENABLE_IT(hospi
, HAL_OSPI_IT_TC
);
2696 /* Perform an abort of the OctoSPI */
2697 SET_BIT(hospi
->Instance
->CR
, OCTOSPI_CR_ABORT
);
2702 hospi
->State
= HAL_OSPI_STATE_READY
;
2704 /* Abort callback */
2705 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2706 hospi
->AbortCpltCallback(hospi
);
2708 HAL_OSPI_AbortCpltCallback(hospi
);
2714 /* DMA abort called due to a transfer error interrupt */
2716 hospi
->State
= HAL_OSPI_STATE_READY
;
2718 /* Error callback */
2719 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2720 hospi
->ErrorCallback(hospi
);
2722 HAL_OSPI_ErrorCallback(hospi
);
2728 * @brief Wait for a flag state until timeout.
2729 * @param hospi : OSPI handle
2730 * @param Flag : Flag checked
2731 * @param State : Value of the flag expected
2732 * @param Timeout : Duration of the timeout
2733 * @param Tickstart : Tick start value
2734 * @retval HAL status
2736 static HAL_StatusTypeDef
OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef
*hospi
, uint32_t Flag
,
2737 FlagStatus State
, uint32_t Tickstart
, uint32_t Timeout
)
2739 /* Wait until flag is in expected state */
2740 while((__HAL_OSPI_GET_FLAG(hospi
, Flag
)) != State
)
2742 /* Check for the Timeout */
2743 if (Timeout
!= HAL_MAX_DELAY
)
2745 if(((HAL_GetTick() - Tickstart
) > Timeout
) || (Timeout
== 0U))
2747 hospi
->State
= HAL_OSPI_STATE_ERROR
;
2748 hospi
->ErrorCode
|= HAL_OSPI_ERROR_TIMEOUT
;
2758 * @brief Configure the registers for the regular command mode.
2759 * @param hospi : OSPI handle
2760 * @param cmd : structure that contains the command configuration information
2761 * @retval HAL status
2763 static HAL_StatusTypeDef
OSPI_ConfigCmd(OSPI_HandleTypeDef
*hospi
, OSPI_RegularCmdTypeDef
*cmd
)
2765 HAL_StatusTypeDef status
= HAL_OK
;
2766 __IO
uint32_t *ccr_reg
, *tcr_reg
, *ir_reg
, *abr_reg
;
2768 /* Re-initialize the value of the functional mode */
2769 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FMODE
, 0U);
2771 /* Configure the flash ID */
2772 if (hospi
->Init
.DualQuad
== HAL_OSPI_DUALQUAD_DISABLE
)
2774 MODIFY_REG(hospi
->Instance
->CR
, OCTOSPI_CR_FSEL
, cmd
->FlashId
);
2777 if (cmd
->OperationType
== HAL_OSPI_OPTYPE_WRITE_CFG
)
2779 ccr_reg
= &(hospi
->Instance
->WCCR
);
2780 tcr_reg
= &(hospi
->Instance
->WTCR
);
2781 ir_reg
= &(hospi
->Instance
->WIR
);
2782 abr_reg
= &(hospi
->Instance
->WABR
);
2784 else if (cmd
->OperationType
== HAL_OSPI_OPTYPE_WRAP_CFG
)
2786 ccr_reg
= &(hospi
->Instance
->WPCCR
);
2787 tcr_reg
= &(hospi
->Instance
->WPTCR
);
2788 ir_reg
= &(hospi
->Instance
->WPIR
);
2789 abr_reg
= &(hospi
->Instance
->WPABR
);
2793 ccr_reg
= &(hospi
->Instance
->CCR
);
2794 tcr_reg
= &(hospi
->Instance
->TCR
);
2795 ir_reg
= &(hospi
->Instance
->IR
);
2796 abr_reg
= &(hospi
->Instance
->ABR
);
2799 /* Configure the CCR register with DQS and SIOO modes */
2800 *ccr_reg
= (cmd
->DQSMode
| cmd
->SIOOMode
);
2802 if (cmd
->AlternateBytesMode
!= HAL_OSPI_ALTERNATE_BYTES_NONE
)
2804 /* Configure the ABR register with alternate bytes value */
2805 *abr_reg
= cmd
->AlternateBytes
;
2807 /* Configure the CCR register with alternate bytes communication parameters */
2808 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_ABMODE
| OCTOSPI_CCR_ABDTR
| OCTOSPI_CCR_ABSIZE
),
2809 (cmd
->AlternateBytesMode
| cmd
->AlternateBytesDtrMode
| cmd
->AlternateBytesSize
));
2812 /* Configure the TCR register with the number of dummy cycles */
2813 MODIFY_REG((*tcr_reg
), OCTOSPI_TCR_DCYC
, cmd
->DummyCycles
);
2815 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
2817 if (cmd
->OperationType
== HAL_OSPI_OPTYPE_COMMON_CFG
)
2819 /* Configure the DLR register with the number of data */
2820 hospi
->Instance
->DLR
= (cmd
->NbData
- 1U);
2824 if (cmd
->InstructionMode
!= HAL_OSPI_INSTRUCTION_NONE
)
2826 if (cmd
->AddressMode
!= HAL_OSPI_ADDRESS_NONE
)
2828 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
2830 /* ---- Command with instruction, address and data ---- */
2832 /* Configure the CCR register with all communication parameters */
2833 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_IMODE
| OCTOSPI_CCR_IDTR
| OCTOSPI_CCR_ISIZE
|
2834 OCTOSPI_CCR_ADMODE
| OCTOSPI_CCR_ADDTR
| OCTOSPI_CCR_ADSIZE
|
2835 OCTOSPI_CCR_DMODE
| OCTOSPI_CCR_DDTR
),
2836 (cmd
->InstructionMode
| cmd
->InstructionDtrMode
| cmd
->InstructionSize
|
2837 cmd
->AddressMode
| cmd
->AddressDtrMode
| cmd
->AddressSize
|
2838 cmd
->DataMode
| cmd
->DataDtrMode
));
2842 /* ---- Command with instruction and address ---- */
2844 /* Configure the CCR register with all communication parameters */
2845 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_IMODE
| OCTOSPI_CCR_IDTR
| OCTOSPI_CCR_ISIZE
|
2846 OCTOSPI_CCR_ADMODE
| OCTOSPI_CCR_ADDTR
| OCTOSPI_CCR_ADSIZE
),
2847 (cmd
->InstructionMode
| cmd
->InstructionDtrMode
| cmd
->InstructionSize
|
2848 cmd
->AddressMode
| cmd
->AddressDtrMode
| cmd
->AddressSize
));
2850 /* The DHQC bit is linked with DDTR bit which should be activated */
2851 if ((hospi
->Init
.DelayHoldQuarterCycle
== HAL_OSPI_DHQC_ENABLE
) &&
2852 (cmd
->InstructionDtrMode
== HAL_OSPI_INSTRUCTION_DTR_ENABLE
))
2854 MODIFY_REG((*ccr_reg
), OCTOSPI_CCR_DDTR
, HAL_OSPI_DATA_DTR_ENABLE
);
2858 /* Configure the IR register with the instruction value */
2859 *ir_reg
= cmd
->Instruction
;
2861 /* Configure the AR register with the address value */
2862 hospi
->Instance
->AR
= cmd
->Address
;
2866 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
2868 /* ---- Command with instruction and data ---- */
2870 /* Configure the CCR register with all communication parameters */
2871 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_IMODE
| OCTOSPI_CCR_IDTR
| OCTOSPI_CCR_ISIZE
|
2872 OCTOSPI_CCR_DMODE
| OCTOSPI_CCR_DDTR
),
2873 (cmd
->InstructionMode
| cmd
->InstructionDtrMode
| cmd
->InstructionSize
|
2874 cmd
->DataMode
| cmd
->DataDtrMode
));
2878 /* ---- Command with only instruction ---- */
2880 /* Configure the CCR register with all communication parameters */
2881 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_IMODE
| OCTOSPI_CCR_IDTR
| OCTOSPI_CCR_ISIZE
),
2882 (cmd
->InstructionMode
| cmd
->InstructionDtrMode
| cmd
->InstructionSize
));
2884 /* The DHQC bit is linked with DDTR bit which should be activated */
2885 if ((hospi
->Init
.DelayHoldQuarterCycle
== HAL_OSPI_DHQC_ENABLE
) &&
2886 (cmd
->InstructionDtrMode
== HAL_OSPI_INSTRUCTION_DTR_ENABLE
))
2888 MODIFY_REG((*ccr_reg
), OCTOSPI_CCR_DDTR
, HAL_OSPI_DATA_DTR_ENABLE
);
2892 /* Configure the IR register with the instruction value */
2893 *ir_reg
= cmd
->Instruction
;
2899 if (cmd
->AddressMode
!= HAL_OSPI_ADDRESS_NONE
)
2901 if (cmd
->DataMode
!= HAL_OSPI_DATA_NONE
)
2903 /* ---- Command with address and data ---- */
2905 /* Configure the CCR register with all communication parameters */
2906 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_ADMODE
| OCTOSPI_CCR_ADDTR
| OCTOSPI_CCR_ADSIZE
|
2907 OCTOSPI_CCR_DMODE
| OCTOSPI_CCR_DDTR
),
2908 (cmd
->AddressMode
| cmd
->AddressDtrMode
| cmd
->AddressSize
|
2909 cmd
->DataMode
| cmd
->DataDtrMode
));
2913 /* ---- Command with only address ---- */
2915 /* Configure the CCR register with all communication parameters */
2916 MODIFY_REG((*ccr_reg
), (OCTOSPI_CCR_ADMODE
| OCTOSPI_CCR_ADDTR
| OCTOSPI_CCR_ADSIZE
),
2917 (cmd
->AddressMode
| cmd
->AddressDtrMode
| cmd
->AddressSize
));
2920 /* Configure the AR register with the instruction value */
2921 hospi
->Instance
->AR
= cmd
->Address
;
2925 /* ---- Invalid command configuration (no instruction, no address) ---- */
2927 hospi
->ErrorCode
= HAL_OSPI_ERROR_INVALID_PARAM
;
2931 /* Return function status */
2936 * @brief Get the current IOM configuration for an OctoSPI instance.
2937 * @param instance_nb : number of the instance
2938 * @param cfg : configuration of the IO Manager for the instance
2939 * @retval HAL status
2941 static HAL_StatusTypeDef
OSPIM_GetConfig(uint8_t instance_nb
, OSPIM_CfgTypeDef
*cfg
)
2943 HAL_StatusTypeDef status
= HAL_OK
;
2944 uint32_t reg
, value
= 0U;
2947 if ((instance_nb
== 0U) || (instance_nb
> OSPI_NB_INSTANCE
) || (cfg
== NULL
))
2949 /* Invalid parameter -> error returned */
2954 /* Initialize the structure */
2958 cfg
->IOLowPort
= 0U;
2959 cfg
->IOHighPort
= 0U;
2961 if (instance_nb
== 2U)
2963 if ((OCTOSPIM
->CR
& OCTOSPIM_CR_MUXEN
) == 0U)
2965 value
= (OCTOSPIM_PCR_CLKSRC
| OCTOSPIM_PCR_DQSSRC
| OCTOSPIM_PCR_NCSSRC
| OCTOSPIM_PCR_IOLSRC_1
| OCTOSPIM_PCR_IOHSRC_1
);
2969 value
= OCTOSPIM_PCR_NCSSRC
;
2973 /* Get the information about the instance */
2974 for (index
= 0U; index
< OSPI_IOM_NB_PORTS
; index
++)
2976 reg
= OCTOSPIM
->PCR
[index
];
2978 if ((reg
& OCTOSPIM_PCR_CLKEN
) != 0U)
2980 /* The clock is enabled on this port */
2981 if ((reg
& OCTOSPIM_PCR_CLKSRC
) == (value
& OCTOSPIM_PCR_CLKSRC
))
2983 /* The clock correspond to the instance passed as parameter */
2984 cfg
->ClkPort
= index
+1U;
2988 if ((reg
& OCTOSPIM_PCR_DQSEN
) != 0U)
2990 /* The DQS is enabled on this port */
2991 if ((reg
& OCTOSPIM_PCR_DQSSRC
) == (value
& OCTOSPIM_PCR_DQSSRC
))
2993 /* The DQS correspond to the instance passed as parameter */
2994 cfg
->DQSPort
= index
+1U;
2998 if ((reg
& OCTOSPIM_PCR_NCSEN
) != 0U)
3000 /* The nCS is enabled on this port */
3001 if ((reg
& OCTOSPIM_PCR_NCSSRC
) == (value
& OCTOSPIM_PCR_NCSSRC
))
3003 /* The nCS correspond to the instance passed as parameter */
3004 cfg
->NCSPort
= index
+1U;
3008 if ((reg
& OCTOSPIM_PCR_IOLEN
) != 0U)
3010 /* The IO Low is enabled on this port */
3011 if ((reg
& OCTOSPIM_PCR_IOLSRC_1
) == (value
& OCTOSPIM_PCR_IOLSRC_1
))
3013 /* The IO Low correspond to the instance passed as parameter */
3014 if ((reg
& OCTOSPIM_PCR_IOLSRC_0
) == 0U)
3016 cfg
->IOLowPort
= (OCTOSPIM_PCR_IOLEN
| (index
+1U));
3020 cfg
->IOLowPort
= (OCTOSPIM_PCR_IOHEN
| (index
+1U));
3025 if ((reg
& OCTOSPIM_PCR_IOHEN
) != 0U)
3027 /* The IO High is enabled on this port */
3028 if ((reg
& OCTOSPIM_PCR_IOHSRC_1
) == (value
& OCTOSPIM_PCR_IOHSRC_1
))
3030 /* The IO High correspond to the instance passed as parameter */
3031 if ((reg
& OCTOSPIM_PCR_IOHSRC_0
) == 0U)
3033 cfg
->IOHighPort
= (OCTOSPIM_PCR_IOLEN
| (index
+1U));
3037 cfg
->IOHighPort
= (OCTOSPIM_PCR_IOHEN
| (index
+1U));
3044 /* Return function status */
3056 #endif /* HAL_OSPI_MODULE_ENABLED */
3066 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3068 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/