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