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