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 }
1152 while (hospi->XferCount > 0U);
1153
1154 if (status == HAL_OK)
1155 {
1156 /* Wait till transfer complete flag is set to go back in idle state */
1157 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1158
1159 if (status == HAL_OK)
1160 {
1161 /* Clear transfer complete flag */
1162 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1163
1164 /* Update state */
1165 hospi->State = HAL_OSPI_STATE_READY;
1166 }
1167 }
1168 }
1169 else
1170 {
1171 status = HAL_ERROR;
1172 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1173 }
1174 }
1175
1176 /* Return function status */
1177 return status;
1178 }
1179
1180 /**
1181 * @brief Receive an amount of data in blocking mode.
1182 * @param hospi : OSPI handle
1183 * @param pData : pointer to data buffer
1184 * @param Timeout : Timeout duration
1185 * @note This function is used only in Indirect Read Mode
1186 * @retval HAL status
1187 */
HAL_OSPI_Receive(OSPI_HandleTypeDef * hospi,uint8_t * pData,uint32_t Timeout)1188 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1189 {
1190 HAL_StatusTypeDef status;
1191 uint32_t tickstart = HAL_GetTick();
1192 __IO uint32_t *data_reg = &hospi->Instance->DR;
1193 uint32_t addr_reg = hospi->Instance->AR;
1194 uint32_t ir_reg = hospi->Instance->IR;
1195
1196 /* Check the data pointer allocation */
1197 if (pData == NULL)
1198 {
1199 status = HAL_ERROR;
1200 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1201 }
1202 else
1203 {
1204 /* Check the state */
1205 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1206 {
1207 /* Configure counters and size */
1208 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1209 hospi->XferSize = hospi->XferCount;
1210 hospi->pBuffPtr = pData;
1211
1212 /* Configure CR register with functional mode as indirect read */
1213 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1214
1215 /* Trig the transfer by re-writing address or instruction register */
1216 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1217 {
1218 WRITE_REG(hospi->Instance->AR, addr_reg);
1219 }
1220 else
1221 {
1222 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1223 {
1224 WRITE_REG(hospi->Instance->AR, addr_reg);
1225 }
1226 else
1227 {
1228 WRITE_REG(hospi->Instance->IR, ir_reg);
1229 }
1230 }
1231
1232 do
1233 {
1234 /* Wait till fifo threshold or transfer complete flags are set to read received data */
1235 status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
1236
1237 if (status != HAL_OK)
1238 {
1239 break;
1240 }
1241
1242 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
1243 hospi->pBuffPtr++;
1244 hospi->XferCount--;
1245 }
1246 while (hospi->XferCount > 0U);
1247
1248 if (status == HAL_OK)
1249 {
1250 /* Wait till transfer complete flag is set to go back in idle state */
1251 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1252
1253 if (status == HAL_OK)
1254 {
1255 /* Clear transfer complete flag */
1256 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1257
1258 /* Update state */
1259 hospi->State = HAL_OSPI_STATE_READY;
1260 }
1261 }
1262 }
1263 else
1264 {
1265 status = HAL_ERROR;
1266 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1267 }
1268 }
1269
1270 /* Return function status */
1271 return status;
1272 }
1273
1274 /**
1275 * @brief Send an amount of data in non-blocking mode with interrupt.
1276 * @param hospi : OSPI handle
1277 * @param pData : pointer to data buffer
1278 * @note This function is used only in Indirect Write Mode
1279 * @retval HAL status
1280 */
HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef * hospi,uint8_t * pData)1281 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1282 {
1283 HAL_StatusTypeDef status = HAL_OK;
1284
1285 /* Check the data pointer allocation */
1286 if (pData == NULL)
1287 {
1288 status = HAL_ERROR;
1289 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1290 }
1291 else
1292 {
1293 /* Check the state */
1294 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1295 {
1296 /* Configure counters and size */
1297 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1298 hospi->XferSize = hospi->XferCount;
1299 hospi->pBuffPtr = pData;
1300
1301 /* Configure CR register with functional mode as indirect write */
1302 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1303
1304 /* Clear flags related to interrupt */
1305 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1306
1307 /* Update the state */
1308 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1309
1310 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1311 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1312 }
1313 else
1314 {
1315 status = HAL_ERROR;
1316 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1317 }
1318 }
1319
1320 /* Return function status */
1321 return status;
1322 }
1323
1324 /**
1325 * @brief Receive an amount of data in non-blocking mode with interrupt.
1326 * @param hospi : OSPI handle
1327 * @param pData : pointer to data buffer
1328 * @note This function is used only in Indirect Read Mode
1329 * @retval HAL status
1330 */
HAL_OSPI_Receive_IT(OSPI_HandleTypeDef * hospi,uint8_t * pData)1331 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1332 {
1333 HAL_StatusTypeDef status = HAL_OK;
1334 uint32_t addr_reg = hospi->Instance->AR;
1335 uint32_t ir_reg = hospi->Instance->IR;
1336
1337 /* Check the data pointer allocation */
1338 if (pData == NULL)
1339 {
1340 status = HAL_ERROR;
1341 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1342 }
1343 else
1344 {
1345 /* Check the state */
1346 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1347 {
1348 /* Configure counters and size */
1349 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1350 hospi->XferSize = hospi->XferCount;
1351 hospi->pBuffPtr = pData;
1352
1353 /* Configure CR register with functional mode as indirect read */
1354 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1355
1356 /* Clear flags related to interrupt */
1357 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1358
1359 /* Update the state */
1360 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1361
1362 /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1363 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1364
1365 /* Trig the transfer by re-writing address or instruction register */
1366 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1367 {
1368 WRITE_REG(hospi->Instance->AR, addr_reg);
1369 }
1370 else
1371 {
1372 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1373 {
1374 WRITE_REG(hospi->Instance->AR, addr_reg);
1375 }
1376 else
1377 {
1378 WRITE_REG(hospi->Instance->IR, ir_reg);
1379 }
1380 }
1381 }
1382 else
1383 {
1384 status = HAL_ERROR;
1385 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1386 }
1387 }
1388
1389 /* Return function status */
1390 return status;
1391 }
1392
1393 /**
1394 * @brief Send an amount of data in non-blocking mode with DMA.
1395 * @param hospi : OSPI handle
1396 * @param pData : pointer to data buffer
1397 * @note This function is used only in Indirect Write Mode
1398 * @note If DMA peripheral access is configured as halfword, the number
1399 * of data and the fifo threshold should be aligned on halfword
1400 * @note If DMA peripheral access is configured as word, the number
1401 * of data and the fifo threshold should be aligned on word
1402 * @retval HAL status
1403 */
HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef * hospi,uint8_t * pData)1404 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1405 {
1406 HAL_StatusTypeDef status = HAL_OK;
1407 uint32_t data_size = hospi->Instance->DLR + 1U;
1408 DMA_QListTypeDef *p_queue = {NULL};
1409 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1410
1411 /* Check the data pointer allocation */
1412 if (pData == NULL)
1413 {
1414 status = HAL_ERROR;
1415 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1416 }
1417 else
1418 {
1419 /* Check the state */
1420 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1421 {
1422 if ((hospi->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1423 {
1424 p_queue = hospi->hdma->LinkedListQueue;
1425 if ((p_queue != NULL) && (p_queue->Head != NULL))
1426 {
1427 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1428 }
1429 else
1430 {
1431 /* Set Error Code */
1432 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1433
1434 /* Return function status */
1435 status = HAL_ERROR;
1436 }
1437 }
1438 else
1439 {
1440 data_width = hospi->hdma->Init.DestDataWidth;
1441 }
1442 /* Configure counters and size */
1443 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1444 {
1445 hospi->XferCount = data_size;
1446 }
1447 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1448 {
1449 if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
1450 {
1451 /* The number of data or the fifo threshold is not aligned on halfword
1452 => no transfer possible with DMA peripheral access configured as halfword */
1453 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1454 status = HAL_ERROR;
1455 }
1456 else
1457 {
1458 hospi->XferCount = data_size;
1459 }
1460 }
1461 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1462 {
1463 if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
1464 {
1465 /* The number of data or the fifo threshold is not aligned on word
1466 => no transfer possible with DMA peripheral access configured as word */
1467 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1468 status = HAL_ERROR;
1469 }
1470 else
1471 {
1472 hospi->XferCount = data_size;
1473 }
1474 }
1475 else
1476 {
1477 /* Nothing to do */
1478 }
1479
1480 if (status == HAL_OK)
1481 {
1482 hospi->XferSize = hospi->XferCount;
1483 hospi->pBuffPtr = pData;
1484
1485 /* Configure CR register with functional mode as indirect write */
1486 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1487
1488 /* Clear flags related to interrupt */
1489 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1490
1491 /* Update the state */
1492 hospi->State = HAL_OSPI_STATE_BUSY_TX;
1493
1494 /* Set the DMA transfer complete callback */
1495 hospi->hdma->XferCpltCallback = OSPI_DMACplt;
1496
1497 /* Set the DMA Half transfer complete callback */
1498 hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
1499
1500 /* Set the DMA error callback */
1501 hospi->hdma->XferErrorCallback = OSPI_DMAError;
1502
1503 /* Clear the DMA abort callback */
1504 hospi->hdma->XferAbortCallback = NULL;
1505
1506 /* Enable the transmit DMA Channel */
1507 if ((hospi->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1508 {
1509 if (hospi->hdma->LinkedListQueue != NULL)
1510 {
1511 /* Enable the DMA channel */
1512 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1513 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_INCREMENTED | DMA_DINC_FIXED));
1514 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1515 DMA_CTR2_DREQ, DMA_MEMORY_TO_PERIPH);
1516 /* Set DMA data size*/
1517 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hospi->XferSize;
1518 /* Set DMA source address */
1519 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
1520 /* Set DMA destination address */
1521 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hospi->Instance->DR;
1522 status = HAL_DMAEx_List_Start_IT(hospi->hdma);
1523 }
1524 else
1525 {
1526 /* Set Error Code */
1527 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1528
1529 /* Change OSPI state */
1530 hospi->State = HAL_OSPI_STATE_READY;
1531
1532 /* Return function status */
1533 status = HAL_ERROR;
1534 }
1535 }
1536 else
1537 {
1538 /* Configure the direction of the DMA */
1539 MODIFY_REG(hospi->hdma->Instance->CTR1, (DMA_CTR1_SINC | DMA_CTR1_DINC), \
1540 (DMA_SINC_INCREMENTED | DMA_DINC_FIXED));
1541 MODIFY_REG(hospi->hdma->Instance->CTR2, DMA_CTR2_DREQ, DMA_MEMORY_TO_PERIPH);
1542
1543 status = HAL_DMA_Start_IT(hospi->hdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize);
1544 }
1545
1546 if (status == HAL_OK)
1547 {
1548 /* Enable the transfer error interrupt */
1549 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1550
1551 /* Enable the DMA transfer by setting the DMAEN bit */
1552 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1553 }
1554 else
1555 {
1556 status = HAL_ERROR;
1557 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1558 hospi->State = HAL_OSPI_STATE_READY;
1559 }
1560 }
1561 }
1562 else
1563 {
1564 status = HAL_ERROR;
1565 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1566 }
1567 }
1568
1569 /* Return function status */
1570 return status;
1571 }
1572
1573 /**
1574 * @brief Receive an amount of data in non-blocking mode with DMA.
1575 * @param hospi : OSPI handle
1576 * @param pData : pointer to data buffer.
1577 * @note This function is used only in Indirect Read Mode
1578 * @note If DMA peripheral access is configured as halfword, the number
1579 * of data and the fifo threshold should be aligned on halfword
1580 * @note If DMA peripheral access is configured as word, the number
1581 * of data and the fifo threshold should be aligned on word
1582 * @retval HAL status
1583 */
HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef * hospi,uint8_t * pData)1584 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1585 {
1586 HAL_StatusTypeDef status = HAL_OK;
1587 uint32_t data_size = hospi->Instance->DLR + 1U;
1588 uint32_t addr_reg = hospi->Instance->AR;
1589 uint32_t ir_reg = hospi->Instance->IR;
1590 DMA_QListTypeDef *p_queue = {NULL};
1591 uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE;
1592 /* Check the data pointer allocation */
1593 if (pData == NULL)
1594 {
1595 status = HAL_ERROR;
1596 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1597 }
1598 else
1599 {
1600 /* Check the state */
1601 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1602 {
1603 if ((hospi->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1604 {
1605 p_queue = hospi->hdma->LinkedListQueue;
1606 if ((p_queue != NULL) && (p_queue->Head != NULL))
1607 {
1608 data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
1609 }
1610 else
1611 {
1612 /* Set Error Code */
1613 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1614
1615 /* Return function status */
1616 status = HAL_ERROR;
1617 }
1618 }
1619 else
1620 {
1621 data_width = hospi->hdma->Init.DestDataWidth;
1622 }
1623
1624 /* Configure counters and size */
1625 if (data_width == DMA_DEST_DATAWIDTH_BYTE)
1626 {
1627 hospi->XferCount = data_size;
1628 }
1629 else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
1630 {
1631 if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
1632 {
1633 /* The number of data or the fifo threshold is not aligned on halfword
1634 => no transfer possible with DMA peripheral access configured as halfword */
1635 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1636 status = HAL_ERROR;
1637 }
1638 else
1639 {
1640 hospi->XferCount = data_size;
1641 }
1642 }
1643 else if (data_width == DMA_DEST_DATAWIDTH_WORD)
1644 {
1645 if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
1646 {
1647 /* The number of data or the fifo threshold is not aligned on word
1648 => no transfer possible with DMA peripheral access configured as word */
1649 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1650 status = HAL_ERROR;
1651 }
1652 else
1653 {
1654 hospi->XferCount = data_size;
1655 }
1656 }
1657 else
1658 {
1659 /* Nothing to do */
1660 }
1661
1662 if (status == HAL_OK)
1663 {
1664 hospi->XferSize = hospi->XferCount;
1665 hospi->pBuffPtr = pData;
1666
1667 /* Configure CR register with functional mode as indirect read */
1668 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1669
1670 /* Clear flags related to interrupt */
1671 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1672
1673 /* Update the state */
1674 hospi->State = HAL_OSPI_STATE_BUSY_RX;
1675
1676 /* Set the DMA transfer complete callback */
1677 hospi->hdma->XferCpltCallback = OSPI_DMACplt;
1678
1679 /* Set the DMA Half transfer complete callback */
1680 hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
1681
1682 /* Set the DMA error callback */
1683 hospi->hdma->XferErrorCallback = OSPI_DMAError;
1684
1685 /* Clear the DMA abort callback */
1686 hospi->hdma->XferAbortCallback = NULL;
1687
1688 /* Enable the transmit DMA Channel */
1689 if ((hospi->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1690 {
1691 if (hospi->hdma->LinkedListQueue != NULL)
1692 {
1693 /* Enable the DMA channel */
1694 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \
1695 (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_FIXED | DMA_DINC_INCREMENTED));
1696 MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \
1697 DMA_CTR2_DREQ, DMA_PERIPH_TO_MEMORY);
1698 /* Set DMA data size */
1699 p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hospi->XferSize;
1700 /* Set DMA source address */
1701 p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hospi->Instance->DR;
1702 /* Set DMA destination address */
1703 p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
1704
1705 status = HAL_DMAEx_List_Start_IT(hospi->hdma);
1706 }
1707 else
1708 {
1709 /* Set Error Code */
1710 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1711
1712 /* Change OSPI state */
1713 hospi->State = HAL_OSPI_STATE_READY;
1714
1715 /* Return function status */
1716 status = HAL_ERROR;
1717 }
1718 }
1719
1720
1721 else
1722 {
1723 /* Configure the direction of the DMA */
1724 MODIFY_REG(hospi->hdma->Instance->CTR1, (DMA_CTR1_SINC | DMA_CTR1_DINC), \
1725 (DMA_SINC_FIXED | DMA_DINC_INCREMENTED));
1726 MODIFY_REG(hospi->hdma->Instance->CTR2, DMA_CTR2_DREQ, DMA_PERIPH_TO_MEMORY);
1727
1728 status = HAL_DMA_Start_IT(hospi->hdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize);
1729 }
1730 if (status == HAL_OK)
1731 {
1732 /* Enable the transfer error interrupt */
1733 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1734
1735 /* Trig the transfer by re-writing address or instruction register */
1736 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1737 {
1738 WRITE_REG(hospi->Instance->AR, addr_reg);
1739 }
1740 else
1741 {
1742 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1743 {
1744 WRITE_REG(hospi->Instance->AR, addr_reg);
1745 }
1746 else
1747 {
1748 WRITE_REG(hospi->Instance->IR, ir_reg);
1749 }
1750 }
1751
1752 /* Enable the DMA transfer by setting the DMAEN bit */
1753 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1754 }
1755 else
1756 {
1757 status = HAL_ERROR;
1758 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1759 hospi->State = HAL_OSPI_STATE_READY;
1760 }
1761 }
1762 }
1763 else
1764 {
1765 status = HAL_ERROR;
1766 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1767 }
1768 }
1769
1770 /* Return function status */
1771 return status;
1772 }
1773
1774 /**
1775 * @brief Configure the OSPI Automatic Polling Mode in blocking mode.
1776 * @param hospi : OSPI handle
1777 * @param cfg : structure that contains the polling configuration information.
1778 * @param Timeout : Timeout duration
1779 * @note This function is used only in Automatic Polling Mode
1780 * @retval HAL status
1781 */
HAL_OSPI_AutoPolling(OSPI_HandleTypeDef * hospi,OSPI_AutoPollingTypeDef * cfg,uint32_t Timeout)1782 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1783 {
1784 HAL_StatusTypeDef status;
1785 uint32_t tickstart = HAL_GetTick();
1786 uint32_t addr_reg = hospi->Instance->AR;
1787 uint32_t ir_reg = hospi->Instance->IR;
1788 #ifdef USE_FULL_ASSERT
1789 uint32_t dlr_reg = hospi->Instance->DLR;
1790 #endif /* USE_FULL_ASSERT */
1791
1792 /* Check the parameters of the autopolling configuration structure */
1793 assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
1794 assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1795 assert_param(IS_OSPI_INTERVAL(cfg->Interval));
1796 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1797
1798 /* Check the state */
1799 if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
1800 {
1801 /* Wait till busy flag is reset */
1802 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1803
1804 if (status == HAL_OK)
1805 {
1806 /* Configure registers */
1807 WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
1808 WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
1809 WRITE_REG(hospi->Instance->PIR, cfg->Interval);
1810 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1811 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1812
1813 /* Trig the transfer by re-writing address or instruction register */
1814 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1815 {
1816 WRITE_REG(hospi->Instance->AR, addr_reg);
1817 }
1818 else
1819 {
1820 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1821 {
1822 WRITE_REG(hospi->Instance->AR, addr_reg);
1823 }
1824 else
1825 {
1826 WRITE_REG(hospi->Instance->IR, ir_reg);
1827 }
1828 }
1829
1830 /* Wait till status match flag is set to go back in idle state */
1831 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
1832
1833 if (status == HAL_OK)
1834 {
1835 /* Clear status match flag */
1836 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
1837
1838 /* Update state */
1839 hospi->State = HAL_OSPI_STATE_READY;
1840 }
1841 }
1842 }
1843 else
1844 {
1845 status = HAL_ERROR;
1846 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1847 }
1848
1849 /* Return function status */
1850 return status;
1851 }
1852
1853 /**
1854 * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode.
1855 * @param hospi : OSPI handle
1856 * @param cfg : structure that contains the polling configuration information.
1857 * @note This function is used only in Automatic Polling Mode
1858 * @retval HAL status
1859 */
HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef * hospi,OSPI_AutoPollingTypeDef * cfg)1860 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
1861 {
1862 HAL_StatusTypeDef status;
1863 uint32_t tickstart = HAL_GetTick();
1864 uint32_t addr_reg = hospi->Instance->AR;
1865 uint32_t ir_reg = hospi->Instance->IR;
1866 #ifdef USE_FULL_ASSERT
1867 uint32_t dlr_reg = hospi->Instance->DLR;
1868 #endif /* USE_FULL_ASSERT */
1869
1870 /* Check the parameters of the autopolling configuration structure */
1871 assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
1872 assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
1873 assert_param(IS_OSPI_INTERVAL(cfg->Interval));
1874 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
1875
1876 /* Check the state */
1877 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1878 {
1879 /* Wait till busy flag is reset */
1880 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1881
1882 if (status == HAL_OK)
1883 {
1884 /* Configure registers */
1885 WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
1886 WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
1887 WRITE_REG(hospi->Instance->PIR, cfg->Interval);
1888 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1889 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1890
1891 /* Clear flags related to interrupt */
1892 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
1893
1894 /* Update state */
1895 hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
1896
1897 /* Enable the status match and transfer error interrupts */
1898 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
1899
1900 /* Trig the transfer by re-writing address or instruction register */
1901 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1902 {
1903 WRITE_REG(hospi->Instance->AR, addr_reg);
1904 }
1905 else
1906 {
1907 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1908 {
1909 WRITE_REG(hospi->Instance->AR, addr_reg);
1910 }
1911 else
1912 {
1913 WRITE_REG(hospi->Instance->IR, ir_reg);
1914 }
1915 }
1916 }
1917 }
1918 else
1919 {
1920 status = HAL_ERROR;
1921 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1922 }
1923
1924 /* Return function status */
1925 return status;
1926 }
1927
1928 /**
1929 * @brief Configure the Memory Mapped mode.
1930 * @param hospi : OSPI handle
1931 * @param cfg : structure that contains the memory mapped configuration information.
1932 * @note This function is used only in Memory mapped Mode
1933 * @retval HAL status
1934 */
HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef * hospi,OSPI_MemoryMappedTypeDef * cfg)1935 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
1936 {
1937 HAL_StatusTypeDef status;
1938 uint32_t tickstart = HAL_GetTick();
1939
1940 /* Check the parameters of the memory-mapped configuration structure */
1941 assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1942
1943 /* Check the state */
1944 if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1945 {
1946 /* Wait till busy flag is reset */
1947 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1948
1949 if (status == HAL_OK)
1950 {
1951 /* Update state */
1952 hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
1953
1954 if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
1955 {
1956 assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1957
1958 /* Configure register */
1959 WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
1960
1961 /* Clear flags related to interrupt */
1962 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
1963
1964 /* Enable the timeout interrupt */
1965 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
1966 }
1967
1968 /* Configure CR register with functional mode as memory-mapped */
1969 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
1970 (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1971 }
1972 }
1973 else
1974 {
1975 status = HAL_ERROR;
1976 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1977 }
1978
1979 /* Return function status */
1980 return status;
1981 }
1982
1983 /**
1984 * @brief Transfer Error callback.
1985 * @param hospi : OSPI handle
1986 * @retval None
1987 */
HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef * hospi)1988 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
1989 {
1990 /* Prevent unused argument(s) compilation warning */
1991 UNUSED(hospi);
1992
1993 /* NOTE : This function should not be modified, when the callback is needed,
1994 the HAL_OSPI_ErrorCallback could be implemented in the user file
1995 */
1996 }
1997
1998 /**
1999 * @brief Abort completed callback.
2000 * @param hospi : OSPI handle
2001 * @retval None
2002 */
HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef * hospi)2003 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
2004 {
2005 /* Prevent unused argument(s) compilation warning */
2006 UNUSED(hospi);
2007
2008 /* NOTE: This function should not be modified, when the callback is needed,
2009 the HAL_OSPI_AbortCpltCallback could be implemented in the user file
2010 */
2011 }
2012
2013 /**
2014 * @brief FIFO Threshold callback.
2015 * @param hospi : OSPI handle
2016 * @retval None
2017 */
HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef * hospi)2018 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
2019 {
2020 /* Prevent unused argument(s) compilation warning */
2021 UNUSED(hospi);
2022
2023 /* NOTE : This function should not be modified, when the callback is needed,
2024 the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
2025 */
2026 }
2027
2028 /**
2029 * @brief Command completed callback.
2030 * @param hospi : OSPI handle
2031 * @retval None
2032 */
HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef * hospi)2033 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
2034 {
2035 /* Prevent unused argument(s) compilation warning */
2036 UNUSED(hospi);
2037
2038 /* NOTE: This function should not be modified, when the callback is needed,
2039 the HAL_OSPI_CmdCpltCallback could be implemented in the user file
2040 */
2041 }
2042
2043 /**
2044 * @brief Rx Transfer completed callback.
2045 * @param hospi : OSPI handle
2046 * @retval None
2047 */
HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef * hospi)2048 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
2049 {
2050 /* Prevent unused argument(s) compilation warning */
2051 UNUSED(hospi);
2052
2053 /* NOTE: This function should not be modified, when the callback is needed,
2054 the HAL_OSPI_RxCpltCallback could be implemented in the user file
2055 */
2056 }
2057
2058 /**
2059 * @brief Tx Transfer completed callback.
2060 * @param hospi : OSPI handle
2061 * @retval None
2062 */
HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef * hospi)2063 __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
2064 {
2065 /* Prevent unused argument(s) compilation warning */
2066 UNUSED(hospi);
2067
2068 /* NOTE: This function should not be modified, when the callback is needed,
2069 the HAL_OSPI_TxCpltCallback could be implemented in the user file
2070 */
2071 }
2072
2073 /**
2074 * @brief Rx Half Transfer completed callback.
2075 * @param hospi : OSPI handle
2076 * @retval None
2077 */
HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef * hospi)2078 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
2079 {
2080 /* Prevent unused argument(s) compilation warning */
2081 UNUSED(hospi);
2082
2083 /* NOTE: This function should not be modified, when the callback is needed,
2084 the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
2085 */
2086 }
2087
2088 /**
2089 * @brief Tx Half Transfer completed callback.
2090 * @param hospi : OSPI handle
2091 * @retval None
2092 */
HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef * hospi)2093 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
2094 {
2095 /* Prevent unused argument(s) compilation warning */
2096 UNUSED(hospi);
2097
2098 /* NOTE: This function should not be modified, when the callback is needed,
2099 the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
2100 */
2101 }
2102
2103 /**
2104 * @brief Status Match callback.
2105 * @param hospi : OSPI handle
2106 * @retval None
2107 */
HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef * hospi)2108 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
2109 {
2110 /* Prevent unused argument(s) compilation warning */
2111 UNUSED(hospi);
2112
2113 /* NOTE : This function should not be modified, when the callback is needed,
2114 the HAL_OSPI_StatusMatchCallback could be implemented in the user file
2115 */
2116 }
2117
2118 /**
2119 * @brief Timeout callback.
2120 * @param hospi : OSPI handle
2121 * @retval None
2122 */
HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef * hospi)2123 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
2124 {
2125 /* Prevent unused argument(s) compilation warning */
2126 UNUSED(hospi);
2127
2128 /* NOTE : This function should not be modified, when the callback is needed,
2129 the HAL_OSPI_TimeOutCallback could be implemented in the user file
2130 */
2131 }
2132
2133 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2134 /**
2135 * @brief Register a User OSPI Callback
2136 * To be used to override the weak predefined callback
2137 * @param hospi : OSPI handle
2138 * @param CallbackID : ID of the callback to be registered
2139 * This parameter can be one of the following values:
2140 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
2141 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
2142 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2143 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
2144 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
2145 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
2146 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
2147 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
2148 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
2149 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
2150 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
2151 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
2152 * @param pCallback : pointer to the Callback function
2153 * @retval status
2154 */
HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef * hospi,HAL_OSPI_CallbackIDTypeDef CallbackID,pOSPI_CallbackTypeDef pCallback)2155 HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID,
2156 pOSPI_CallbackTypeDef pCallback)
2157 {
2158 HAL_StatusTypeDef status = HAL_OK;
2159
2160 if (pCallback == NULL)
2161 {
2162 /* Update the error code */
2163 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2164 return HAL_ERROR;
2165 }
2166
2167 if (hospi->State == HAL_OSPI_STATE_READY)
2168 {
2169 switch (CallbackID)
2170 {
2171 case HAL_OSPI_ERROR_CB_ID :
2172 hospi->ErrorCallback = pCallback;
2173 break;
2174 case HAL_OSPI_ABORT_CB_ID :
2175 hospi->AbortCpltCallback = pCallback;
2176 break;
2177 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2178 hospi->FifoThresholdCallback = pCallback;
2179 break;
2180 case HAL_OSPI_CMD_CPLT_CB_ID :
2181 hospi->CmdCpltCallback = pCallback;
2182 break;
2183 case HAL_OSPI_RX_CPLT_CB_ID :
2184 hospi->RxCpltCallback = pCallback;
2185 break;
2186 case HAL_OSPI_TX_CPLT_CB_ID :
2187 hospi->TxCpltCallback = pCallback;
2188 break;
2189 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2190 hospi->RxHalfCpltCallback = pCallback;
2191 break;
2192 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2193 hospi->TxHalfCpltCallback = pCallback;
2194 break;
2195 case HAL_OSPI_STATUS_MATCH_CB_ID :
2196 hospi->StatusMatchCallback = pCallback;
2197 break;
2198 case HAL_OSPI_TIMEOUT_CB_ID :
2199 hospi->TimeOutCallback = pCallback;
2200 break;
2201 case HAL_OSPI_MSP_INIT_CB_ID :
2202 hospi->MspInitCallback = pCallback;
2203 break;
2204 case HAL_OSPI_MSP_DEINIT_CB_ID :
2205 hospi->MspDeInitCallback = pCallback;
2206 break;
2207 default :
2208 /* Update the error code */
2209 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2210 /* update return status */
2211 status = HAL_ERROR;
2212 break;
2213 }
2214 }
2215 else if (hospi->State == HAL_OSPI_STATE_RESET)
2216 {
2217 switch (CallbackID)
2218 {
2219 case HAL_OSPI_MSP_INIT_CB_ID :
2220 hospi->MspInitCallback = pCallback;
2221 break;
2222 case HAL_OSPI_MSP_DEINIT_CB_ID :
2223 hospi->MspDeInitCallback = pCallback;
2224 break;
2225 default :
2226 /* Update the error code */
2227 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2228 /* update return status */
2229 status = HAL_ERROR;
2230 break;
2231 }
2232 }
2233 else
2234 {
2235 /* Update the error code */
2236 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2237 /* update return status */
2238 status = HAL_ERROR;
2239 }
2240
2241 return status;
2242 }
2243
2244 /**
2245 * @brief Unregister a User OSPI Callback
2246 * OSPI Callback is redirected to the weak predefined callback
2247 * @param hospi : OSPI handle
2248 * @param CallbackID : ID of the callback to be unregistered
2249 * This parameter can be one of the following values:
2250 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
2251 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
2252 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
2253 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
2254 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
2255 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
2256 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
2257 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
2258 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
2259 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
2260 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
2261 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
2262 * @retval status
2263 */
HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef * hospi,HAL_OSPI_CallbackIDTypeDef CallbackID)2264 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
2265 {
2266 HAL_StatusTypeDef status = HAL_OK;
2267
2268 if (hospi->State == HAL_OSPI_STATE_READY)
2269 {
2270 switch (CallbackID)
2271 {
2272 case HAL_OSPI_ERROR_CB_ID :
2273 hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
2274 break;
2275 case HAL_OSPI_ABORT_CB_ID :
2276 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
2277 break;
2278 case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
2279 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
2280 break;
2281 case HAL_OSPI_CMD_CPLT_CB_ID :
2282 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
2283 break;
2284 case HAL_OSPI_RX_CPLT_CB_ID :
2285 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
2286 break;
2287 case HAL_OSPI_TX_CPLT_CB_ID :
2288 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
2289 break;
2290 case HAL_OSPI_RX_HALF_CPLT_CB_ID :
2291 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
2292 break;
2293 case HAL_OSPI_TX_HALF_CPLT_CB_ID :
2294 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
2295 break;
2296 case HAL_OSPI_STATUS_MATCH_CB_ID :
2297 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
2298 break;
2299 case HAL_OSPI_TIMEOUT_CB_ID :
2300 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
2301 break;
2302 case HAL_OSPI_MSP_INIT_CB_ID :
2303 hospi->MspInitCallback = HAL_OSPI_MspInit;
2304 break;
2305 case HAL_OSPI_MSP_DEINIT_CB_ID :
2306 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2307 break;
2308 default :
2309 /* Update the error code */
2310 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2311 /* update return status */
2312 status = HAL_ERROR;
2313 break;
2314 }
2315 }
2316 else if (hospi->State == HAL_OSPI_STATE_RESET)
2317 {
2318 switch (CallbackID)
2319 {
2320 case HAL_OSPI_MSP_INIT_CB_ID :
2321 hospi->MspInitCallback = HAL_OSPI_MspInit;
2322 break;
2323 case HAL_OSPI_MSP_DEINIT_CB_ID :
2324 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
2325 break;
2326 default :
2327 /* Update the error code */
2328 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2329 /* update return status */
2330 status = HAL_ERROR;
2331 break;
2332 }
2333 }
2334 else
2335 {
2336 /* Update the error code */
2337 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2338 /* update return status */
2339 status = HAL_ERROR;
2340 }
2341
2342 return status;
2343 }
2344 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2345
2346 /**
2347 * @}
2348 */
2349
2350 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
2351 * @brief OSPI control and State functions
2352 *
2353 @verbatim
2354 ===============================================================================
2355 ##### Peripheral Control and State functions #####
2356 ===============================================================================
2357 [..]
2358 This subsection provides a set of functions allowing to :
2359 (+) Check in run-time the state of the driver.
2360 (+) Check the error code set during last operation.
2361 (+) Abort any operation.
2362 (+) Manage the Fifo threshold.
2363 (+) Configure the timeout duration used in the driver.
2364
2365 @endverbatim
2366 * @{
2367 */
2368
2369 /**
2370 * @brief Abort the current transmission.
2371 * @param hospi : OSPI handle
2372 * @retval HAL status
2373 */
HAL_OSPI_Abort(OSPI_HandleTypeDef * hospi)2374 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
2375 {
2376 HAL_StatusTypeDef status = HAL_OK;
2377 uint32_t state;
2378 uint32_t tickstart = HAL_GetTick();
2379
2380 /* Check if the state is in one of the busy or configured states */
2381 state = hospi->State;
2382 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2383 {
2384 /* Check if the DMA is enabled */
2385 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2386 {
2387 /* Disable the DMA transfer on the OctoSPI side */
2388 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2389
2390 /* Disable the DMA transfer on the DMA side */
2391 status = HAL_DMA_Abort(hospi->hdma);
2392 if (status != HAL_OK)
2393 {
2394 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2395 }
2396 }
2397
2398 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2399 {
2400 /* Perform an abort of the OctoSPI */
2401 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2402
2403 /* Wait until the transfer complete flag is set to go back in idle state */
2404 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
2405
2406 if (status == HAL_OK)
2407 {
2408 /* Clear transfer complete flag */
2409 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2410
2411 /* Wait until the busy flag is reset to go back in idle state */
2412 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
2413
2414 if (status == HAL_OK)
2415 {
2416 /* Update state */
2417 hospi->State = HAL_OSPI_STATE_READY;
2418 }
2419 }
2420 }
2421 else
2422 {
2423 /* Update state */
2424 hospi->State = HAL_OSPI_STATE_READY;
2425 }
2426 }
2427 else
2428 {
2429 status = HAL_ERROR;
2430 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2431 }
2432
2433 /* Return function status */
2434 return status;
2435 }
2436
2437 /**
2438 * @brief Abort the current transmission (non-blocking function)
2439 * @param hospi : OSPI handle
2440 * @retval HAL status
2441 */
HAL_OSPI_Abort_IT(OSPI_HandleTypeDef * hospi)2442 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
2443 {
2444 HAL_StatusTypeDef status = HAL_OK;
2445 uint32_t state;
2446
2447 /* Check if the state is in one of the busy or configured states */
2448 state = hospi->State;
2449 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2450 {
2451 /* Disable all interrupts */
2452 __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));
2453
2454 /* Update state */
2455 hospi->State = HAL_OSPI_STATE_ABORT;
2456
2457 /* Check if the DMA is enabled */
2458 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2459 {
2460 /* Disable the DMA transfer on the OctoSPI side */
2461 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2462
2463 /* Disable the DMA transfer on the DMA side */
2464 hospi->hdma->XferAbortCallback = OSPI_DMAAbortCplt;
2465 if (HAL_DMA_Abort_IT(hospi->hdma) != HAL_OK)
2466 {
2467 /* Update state */
2468 hospi->State = HAL_OSPI_STATE_READY;
2469
2470 /* Abort callback */
2471 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2472 hospi->AbortCpltCallback(hospi);
2473 #else
2474 HAL_OSPI_AbortCpltCallback(hospi);
2475 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
2476 }
2477 }
2478 else
2479 {
2480 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2481 {
2482 /* Clear transfer complete flag */
2483 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2484
2485 /* Enable the transfer complete interrupts */
2486 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2487
2488 /* Perform an abort of the OctoSPI */
2489 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2490 }
2491 else
2492 {
2493 /* Update state */
2494 hospi->State = HAL_OSPI_STATE_READY;
2495
2496 /* Abort callback */
2497 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2498 hospi->AbortCpltCallback(hospi);
2499 #else
2500 HAL_OSPI_AbortCpltCallback(hospi);
2501 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2502 }
2503 }
2504 }
2505 else
2506 {
2507 status = HAL_ERROR;
2508 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2509 }
2510
2511 /* Return function status */
2512 return status;
2513 }
2514
2515 /** @brief Set OSPI Fifo threshold.
2516 * @param hospi : OSPI handle.
2517 * @param Threshold : Threshold of the Fifo.
2518 * @retval HAL status
2519 */
HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef * hospi,uint32_t Threshold)2520 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
2521 {
2522 HAL_StatusTypeDef status = HAL_OK;
2523
2524 /* Check the state */
2525 if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
2526 {
2527 /* Synchronize initialization structure with the new fifo threshold value */
2528 hospi->Init.FifoThreshold = Threshold;
2529
2530 /* Configure new fifo threshold */
2531 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
2532
2533 }
2534 else
2535 {
2536 status = HAL_ERROR;
2537 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2538 }
2539
2540 /* Return function status */
2541 return status;
2542 }
2543
2544 /** @brief Get OSPI Fifo threshold.
2545 * @param hospi : OSPI handle.
2546 * @retval Fifo threshold
2547 */
HAL_OSPI_GetFifoThreshold(const OSPI_HandleTypeDef * hospi)2548 uint32_t HAL_OSPI_GetFifoThreshold(const OSPI_HandleTypeDef *hospi)
2549 {
2550 return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
2551 }
2552
2553 /** @brief Set OSPI timeout.
2554 * @param hospi : OSPI handle.
2555 * @param Timeout : Timeout for the memory access.
2556 * @retval None
2557 */
HAL_OSPI_SetTimeout(OSPI_HandleTypeDef * hospi,uint32_t Timeout)2558 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
2559 {
2560 hospi->Timeout = Timeout;
2561 return HAL_OK;
2562 }
2563
2564 /**
2565 * @brief Return the OSPI error code.
2566 * @param hospi : OSPI handle
2567 * @retval OSPI Error Code
2568 */
HAL_OSPI_GetError(const OSPI_HandleTypeDef * hospi)2569 uint32_t HAL_OSPI_GetError(const OSPI_HandleTypeDef *hospi)
2570 {
2571 return hospi->ErrorCode;
2572 }
2573
2574 /**
2575 * @brief Return the OSPI handle state.
2576 * @param hospi : OSPI handle
2577 * @retval HAL state
2578 */
HAL_OSPI_GetState(const OSPI_HandleTypeDef * hospi)2579 uint32_t HAL_OSPI_GetState(const OSPI_HandleTypeDef *hospi)
2580 {
2581 /* Return OSPI handle state */
2582 return hospi->State;
2583 }
2584
2585 /**
2586 * @}
2587 */
2588
2589 #if defined (OCTOSPIM)
2590 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
2591 * @brief OSPI IO Manager configuration function
2592 *
2593 @verbatim
2594 ===============================================================================
2595 ##### IO Manager configuration function #####
2596 ===============================================================================
2597 [..]
2598 This subsection provides a set of functions allowing to :
2599 (+) Configure the IO manager.
2600
2601 @endverbatim
2602 * @{
2603 */
2604
2605 /**
2606 * @brief Configure the OctoSPI IO manager.
2607 * @param hospi : OSPI handle
2608 * @param cfg : Configuration of the IO Manager for the instance
2609 * @param Timeout : Timeout duration
2610 * @retval HAL status
2611 */
HAL_OSPIM_Config(OSPI_HandleTypeDef * hospi,OSPIM_CfgTypeDef * cfg,uint32_t Timeout)2612 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
2613 {
2614 HAL_StatusTypeDef status = HAL_OK;
2615 uint32_t instance;
2616 uint8_t index;
2617 uint8_t ospi_enabled = 0U;
2618 uint8_t other_instance;
2619 OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2620
2621 /* Prevent unused argument(s) compilation warning */
2622 UNUSED(Timeout);
2623
2624 /* Check the parameters of the OctoSPI IO Manager configuration structure */
2625 assert_param(IS_OSPIM_PORT(cfg->ClkPort));
2626 assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
2627 assert_param(IS_OSPIM_PORT(cfg->NCSPort));
2628 assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
2629 assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
2630
2631 if (hospi->Instance == (OCTOSPI_TypeDef *)OCTOSPI1)
2632 {
2633 instance = 0U;
2634 other_instance = 1U;
2635 }
2636 else
2637 {
2638 instance = 1U;
2639 other_instance = 0U;
2640 }
2641
2642 /**************** Get current configuration of the instances ****************/
2643 for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2644 {
2645 if (OSPIM_GetConfig(index + 1U, &(IOM_cfg[index])) != HAL_OK)
2646 {
2647 status = HAL_ERROR;
2648 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2649 }
2650 }
2651
2652 if (status == HAL_OK)
2653 {
2654 /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2655 if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
2656 {
2657 CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2658 ospi_enabled |= 0x1U;
2659 }
2660 if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
2661 {
2662 CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2663 ospi_enabled |= 0x2U;
2664 }
2665
2666 /***************** Deactivation of previous configuration *****************/
2667 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
2668 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2669 {
2670 /* De-multiplexing should be performed */
2671 CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2672
2673 if (other_instance == 1U)
2674 {
2675 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
2676 if (IOM_cfg[other_instance].DQSPort != 0U)
2677 {
2678 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
2679 }
2680 if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2681 {
2682 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], \
2683 OCTOSPIM_PCR_IOLSRC_1);
2684 }
2685 if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2686 {
2687 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], \
2688 OCTOSPIM_PCR_IOHSRC_1);
2689 }
2690 }
2691 }
2692 else
2693 {
2694 if (IOM_cfg[instance].ClkPort != 0U)
2695 {
2696 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
2697 if (IOM_cfg[instance].DQSPort != 0U)
2698 {
2699 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
2700 }
2701 if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2702 {
2703 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2704 }
2705 if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2706 {
2707 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2708 }
2709 }
2710 }
2711
2712 /********************* Deactivation of other instance *********************/
2713 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) ||
2714 ((cfg->DQSPort == IOM_cfg[other_instance].DQSPort) && (cfg->DQSPort != 0U)) ||
2715 (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
2716 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2717 {
2718 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) &&
2719 (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) &&
2720 (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
2721 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2722 {
2723 /* Multiplexing should be performed */
2724 SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
2725 }
2726 else
2727 {
2728 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
2729 if (IOM_cfg[other_instance].DQSPort != 0U)
2730 {
2731 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
2732 }
2733 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
2734 if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
2735 {
2736 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2737 OCTOSPIM_PCR_IOLEN);
2738 }
2739 if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
2740 {
2741 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2742 OCTOSPIM_PCR_IOHEN);
2743 }
2744 }
2745 }
2746
2747 /******************** Activation of new configuration *********************/
2748 MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
2749 (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
2750
2751 if (((cfg->Req2AckTime) >= 1U) && ((cfg->Req2AckTime) <= 256U))
2752 {
2753 if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
2754 {
2755 MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
2756 }
2757 else
2758 {
2759 /* Nothing to do */
2760 }
2761 }
2762
2763 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
2764 {
2765 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
2766 if (cfg->DQSPort != 0U)
2767 {
2768 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
2769 }
2770
2771 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2772 {
2773 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2774 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
2775 }
2776 else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
2777 {
2778 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2779 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
2780 }
2781 else
2782 {
2783 /* Nothing to do */
2784 }
2785
2786 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2787 {
2788 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2789 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
2790 }
2791 else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
2792 {
2793 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2794 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
2795 }
2796 else
2797 {
2798 /* Nothing to do */
2799 }
2800 }
2801 else
2802 {
2803 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
2804 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
2805 if (cfg->DQSPort != 0U)
2806 {
2807 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
2808 (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
2809 }
2810
2811 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2812 {
2813 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2814 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2815 (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
2816 }
2817 else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
2818 {
2819 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
2820 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2821 (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
2822 }
2823 else
2824 {
2825 /* Nothing to do */
2826 }
2827
2828 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2829 {
2830 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2831 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2832 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
2833 }
2834 else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
2835 {
2836 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
2837 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2838 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
2839 }
2840 else
2841 {
2842 /* Nothing to do */
2843 }
2844 }
2845
2846 /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2847 if ((ospi_enabled & 0x1U) != 0U)
2848 {
2849 SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2850 }
2851 if ((ospi_enabled & 0x2U) != 0U)
2852 {
2853 SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2854 }
2855 }
2856
2857 /* Return function status */
2858 return status;
2859 }
2860
2861 /**
2862 * @}
2863 */
2864 #endif /* OCTOSPIM */
2865
2866 /**
2867 @cond 0
2868 */
2869 /**
2870 * @brief DMA OSPI process complete callback.
2871 * @param hdma : DMA handle
2872 * @retval None
2873 */
OSPI_DMACplt(DMA_HandleTypeDef * hdma)2874 static void OSPI_DMACplt(DMA_HandleTypeDef *hdma)
2875 {
2876 OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
2877 hospi->XferCount = 0;
2878
2879 /* Disable the DMA transfer on the OctoSPI side */
2880 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2881
2882 /* Disable the DMA channel */
2883 __HAL_DMA_DISABLE(hdma);
2884
2885 /* Enable the OSPI transfer complete Interrupt */
2886 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2887 }
2888
2889 /**
2890 * @brief DMA OSPI process half complete callback.
2891 * @param hdma : DMA handle
2892 * @retval None
2893 */
OSPI_DMAHalfCplt(DMA_HandleTypeDef * hdma)2894 static void OSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
2895 {
2896 OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
2897 hospi->XferCount = (hospi->XferCount >> 1);
2898
2899 if (hospi->State == HAL_OSPI_STATE_BUSY_RX)
2900 {
2901 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2902 hospi->RxHalfCpltCallback(hospi);
2903 #else
2904 HAL_OSPI_RxHalfCpltCallback(hospi);
2905 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2906 }
2907 else
2908 {
2909 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2910 hospi->TxHalfCpltCallback(hospi);
2911 #else
2912 HAL_OSPI_TxHalfCpltCallback(hospi);
2913 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
2914 }
2915 }
2916
2917 /**
2918 * @brief DMA OSPI communication error callback.
2919 * @param hdma : DMA handle
2920 * @retval None
2921 */
OSPI_DMAError(DMA_HandleTypeDef * hdma)2922 static void OSPI_DMAError(DMA_HandleTypeDef *hdma)
2923 {
2924 OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
2925 hospi->XferCount = 0;
2926 hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2927
2928 /* Disable the DMA transfer on the OctoSPI side */
2929 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2930
2931 /* Abort the OctoSPI */
2932 if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
2933 {
2934 /* Disable the interrupts */
2935 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
2936
2937 /* Update state */
2938 hospi->State = HAL_OSPI_STATE_READY;
2939
2940 /* Error callback */
2941 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2942 hospi->ErrorCallback(hospi);
2943 #else
2944 HAL_OSPI_ErrorCallback(hospi);
2945 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2946 }
2947 }
2948
2949 /**
2950 * @brief DMA OSPI abort complete callback.
2951 * @param hdma : DMA handle
2952 * @retval None
2953 */
OSPI_DMAAbortCplt(DMA_HandleTypeDef * hdma)2954 static void OSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2955 {
2956 OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
2957 hospi->XferCount = 0;
2958
2959 /* Check the state */
2960 if (hospi->State == HAL_OSPI_STATE_ABORT)
2961 {
2962 /* DMA abort called by OctoSPI abort */
2963 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2964 {
2965 /* Clear transfer complete flag */
2966 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2967
2968 /* Enable the transfer complete interrupts */
2969 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2970
2971 /* Perform an abort of the OctoSPI */
2972 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2973 }
2974 else
2975 {
2976 /* Update state */
2977 hospi->State = HAL_OSPI_STATE_READY;
2978
2979 /* Abort callback */
2980 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2981 hospi->AbortCpltCallback(hospi);
2982 #else
2983 HAL_OSPI_AbortCpltCallback(hospi);
2984 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
2985 }
2986 }
2987 else
2988 {
2989 /* DMA abort called due to a transfer error interrupt */
2990 /* Update state */
2991 hospi->State = HAL_OSPI_STATE_READY;
2992
2993 /* Error callback */
2994 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2995 hospi->ErrorCallback(hospi);
2996 #else
2997 HAL_OSPI_ErrorCallback(hospi);
2998 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
2999 }
3000 }
3001
3002 /**
3003 * @brief Wait for a flag state until timeout.
3004 * @param hospi : OSPI handle
3005 * @param Flag : Flag checked
3006 * @param State : Value of the flag expected
3007 * @param Timeout : Duration of the timeout
3008 * @param Tickstart : Tick start value
3009 * @retval HAL status
3010 */
OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef * hospi,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)3011 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
3012 FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
3013 {
3014 /* Wait until flag is in expected state */
3015 while ((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
3016 {
3017 /* Check for the Timeout */
3018 if (Timeout != HAL_MAX_DELAY)
3019 {
3020 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3021 {
3022 /* New check to avoid false timeout detection in case of preemption */
3023 if ((hospi->Instance->SR & Flag) != (uint32_t)State)
3024 {
3025 hospi->State = HAL_OSPI_STATE_ERROR;
3026 hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
3027
3028 return HAL_ERROR;
3029 }
3030 }
3031 }
3032 }
3033 return HAL_OK;
3034 }
3035
3036 /**
3037 * @brief Configure the registers for the regular command mode.
3038 * @param hospi : OSPI handle
3039 * @param cmd : structure that contains the command configuration information
3040 * @retval HAL status
3041 */
OSPI_ConfigCmd(OSPI_HandleTypeDef * hospi,OSPI_RegularCmdTypeDef * cmd)3042 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
3043 {
3044 HAL_StatusTypeDef status = HAL_OK;
3045 __IO uint32_t *ccr_reg;
3046 __IO uint32_t *tcr_reg;
3047 __IO uint32_t *ir_reg;
3048 __IO uint32_t *abr_reg;
3049
3050 /* Re-initialize the value of the functional mode */
3051 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
3052
3053 /* Configure the flash ID */
3054 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
3055 {
3056 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_MSEL, cmd->FlashId);
3057 }
3058
3059 if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
3060 {
3061 ccr_reg = &(hospi->Instance->WCCR);
3062 tcr_reg = &(hospi->Instance->WTCR);
3063 ir_reg = &(hospi->Instance->WIR);
3064 abr_reg = &(hospi->Instance->WABR);
3065 }
3066 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)
3067 {
3068 ccr_reg = &(hospi->Instance->WPCCR);
3069 tcr_reg = &(hospi->Instance->WPTCR);
3070 ir_reg = &(hospi->Instance->WPIR);
3071 abr_reg = &(hospi->Instance->WPABR);
3072 }
3073 else
3074 {
3075 ccr_reg = &(hospi->Instance->CCR);
3076 tcr_reg = &(hospi->Instance->TCR);
3077 ir_reg = &(hospi->Instance->IR);
3078 abr_reg = &(hospi->Instance->ABR);
3079 }
3080
3081 /* Configure the CCR register with DQS and SIOO modes */
3082 *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
3083
3084 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
3085 {
3086 /* Configure the ABR register with alternate bytes value */
3087 *abr_reg = cmd->AlternateBytes;
3088
3089 /* Configure the CCR register with alternate bytes communication parameters */
3090 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
3091 (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
3092 }
3093
3094 /* Configure the TCR register with the number of dummy cycles */
3095 MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
3096
3097 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3098 {
3099 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
3100 {
3101 /* Configure the DLR register with the number of data */
3102 hospi->Instance->DLR = (cmd->NbData - 1U);
3103 }
3104 }
3105
3106 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
3107 {
3108 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
3109 {
3110 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3111 {
3112 /* ---- Command with instruction, address and data ---- */
3113
3114 /* Configure the CCR register with all communication parameters */
3115 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
3116 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
3117 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
3118 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
3119 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
3120 cmd->DataMode | cmd->DataDtrMode));
3121 }
3122 else
3123 {
3124 /* ---- Command with instruction and address ---- */
3125
3126 /* Configure the CCR register with all communication parameters */
3127 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
3128 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
3129 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
3130 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
3131
3132 /* The DHQC bit is linked with DDTR bit which should be activated */
3133 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
3134 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
3135 {
3136 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
3137 }
3138 }
3139
3140 /* Configure the IR register with the instruction value */
3141 *ir_reg = cmd->Instruction;
3142
3143 /* Configure the AR register with the address value */
3144 hospi->Instance->AR = cmd->Address;
3145 }
3146 else
3147 {
3148 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3149 {
3150 /* ---- Command with instruction and data ---- */
3151
3152 /* Configure the CCR register with all communication parameters */
3153 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
3154 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
3155 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
3156 cmd->DataMode | cmd->DataDtrMode));
3157 }
3158 else
3159 {
3160 /* ---- Command with only instruction ---- */
3161
3162 /* Configure the CCR register with all communication parameters */
3163 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
3164 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
3165
3166 /* The DHQC bit is linked with DDTR bit which should be activated */
3167 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
3168 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
3169 {
3170 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
3171 }
3172 }
3173
3174 /* Configure the IR register with the instruction value */
3175 *ir_reg = cmd->Instruction;
3176
3177 }
3178 }
3179 else
3180 {
3181 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
3182 {
3183 if (cmd->DataMode != HAL_OSPI_DATA_NONE)
3184 {
3185 /* ---- Command with address and data ---- */
3186
3187 /* Configure the CCR register with all communication parameters */
3188 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
3189 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
3190 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | cmd->DataMode |
3191 cmd->DataDtrMode));
3192 }
3193 else
3194 {
3195 /* ---- Command with only address ---- */
3196
3197 /* Configure the CCR register with all communication parameters */
3198 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
3199 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
3200 }
3201
3202 /* Configure the AR register with the instruction value */
3203 hospi->Instance->AR = cmd->Address;
3204 }
3205 else
3206 {
3207 /* ---- Invalid command configuration (no instruction, no address) ---- */
3208 status = HAL_ERROR;
3209 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
3210 }
3211 }
3212
3213 /* Return function status */
3214 return status;
3215 }
3216
3217 #if defined (OCTOSPIM)
3218 /**
3219 * @brief Get the current IOM configuration for an OctoSPI instance.
3220 * @param instance_nb : number of the instance
3221 * @param cfg : configuration of the IO Manager for the instance
3222 * @retval HAL status
3223 */
OSPIM_GetConfig(uint8_t instance_nb,OSPIM_CfgTypeDef * cfg)3224 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
3225 {
3226 HAL_StatusTypeDef status = HAL_OK;
3227 uint32_t reg;
3228 uint32_t value = 0U;
3229 uint32_t index;
3230
3231 if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
3232 {
3233 /* Invalid parameter -> error returned */
3234 status = HAL_ERROR;
3235 }
3236 else
3237 {
3238 /* Initialize the structure */
3239 cfg->ClkPort = 0U;
3240 cfg->DQSPort = 0U;
3241 cfg->NCSPort = 0U;
3242 cfg->IOLowPort = 0U;
3243 cfg->IOHighPort = 0U;
3244
3245 if (instance_nb == 2U)
3246 {
3247 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
3248 {
3249 value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC
3250 | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
3251 }
3252 else
3253 {
3254 value = OCTOSPIM_PCR_NCSSRC;
3255 }
3256 }
3257
3258 /* Get the information about the instance */
3259 for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
3260 {
3261 reg = OCTOSPIM->PCR[index];
3262
3263 if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
3264 {
3265 /* The clock is enabled on this port */
3266 if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
3267 {
3268 /* The clock correspond to the instance passed as parameter */
3269 cfg->ClkPort = index + 1U;
3270 }
3271 }
3272
3273 if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
3274 {
3275 /* The DQS is enabled on this port */
3276 if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
3277 {
3278 /* The DQS correspond to the instance passed as parameter */
3279 cfg->DQSPort = index + 1U;
3280 }
3281 }
3282
3283 if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
3284 {
3285 /* The nCS is enabled on this port */
3286 if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
3287 {
3288 /* The nCS correspond to the instance passed as parameter */
3289 cfg->NCSPort = index + 1U;
3290 }
3291 }
3292
3293 if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
3294 {
3295 /* The IO Low is enabled on this port */
3296 if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
3297 {
3298 /* The IO Low correspond to the instance passed as parameter */
3299 if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
3300 {
3301 cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3302 }
3303 else
3304 {
3305 cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3306 }
3307 }
3308 }
3309
3310 if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
3311 {
3312 /* The IO High is enabled on this port */
3313 if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
3314 {
3315 /* The IO High correspond to the instance passed as parameter */
3316 if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
3317 {
3318 cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
3319 }
3320 else
3321 {
3322 cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
3323 }
3324 }
3325 }
3326 }
3327 }
3328
3329 /* Return function status */
3330 return status;
3331 }
3332 #endif /* OCTOSPIM */
3333
3334
3335 /** @defgroup OSPI_Exported_Functions_Group5 Delay Block function
3336 * @brief Delay block function
3337 *
3338 @verbatim
3339 ===============================================================================
3340 ##### Delay Block function #####
3341 ===============================================================================
3342 [..]
3343 This subsection provides a set of functions allowing to :
3344 (+) Configure the delay block.
3345
3346 @endverbatim
3347 * @{
3348 */
3349
3350 /**
3351 * @brief Set the Delay Block configuration.
3352 * @param hospi : OSPI handle.
3353 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
3354 * @retval HAL status.
3355 */
HAL_OSPI_DLYB_SetConfig(OSPI_HandleTypeDef * hospi,HAL_OSPI_DLYB_CfgTypeDef * pdlyb_cfg)3356 HAL_StatusTypeDef HAL_OSPI_DLYB_SetConfig(OSPI_HandleTypeDef *hospi, HAL_OSPI_DLYB_CfgTypeDef *pdlyb_cfg)
3357 {
3358 HAL_StatusTypeDef status = HAL_ERROR;
3359
3360 /* Enable OCTOSPI Free Running Clock (mandatory) */
3361 SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
3362
3363 /* Update OCTOSPI state */
3364 hospi->State = HAL_OSPI_STATE_BUSY_CMD;
3365
3366 if (hospi->Instance == OCTOSPI1)
3367 {
3368 /* Enable the DelayBlock */
3369 LL_DLYB_Enable(DLYB_OCTOSPI1);
3370
3371 /* Set the Delay Block configuration */
3372 LL_DLYB_SetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
3373 status = HAL_OK;
3374 }
3375
3376 #if defined (OCTOSPI2)
3377 else if (hospi->Instance == OCTOSPI2)
3378 {
3379 /* Enable the DelayBlock */
3380 LL_DLYB_Enable(DLYB_OCTOSPI2);
3381
3382 /* Set the Delay Block configuration */
3383 LL_DLYB_SetDelay(DLYB_OCTOSPI2, pdlyb_cfg);
3384 status = HAL_OK;
3385 }
3386 #endif /* OCTOSPI2 */
3387
3388 else
3389 {
3390 /* Nothing to do */
3391 }
3392
3393 /* Abort the current OCTOSPI operation if exist */
3394 (void)HAL_OSPI_Abort(hospi);
3395
3396 /* Disable Free Running Clock */
3397 CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
3398
3399 /* Return function status */
3400 return status;
3401 }
3402
3403 /**
3404 * @brief Get the Delay Block configuration.
3405 * @param hospi : OSPI handle.
3406 * @param pdlyb_cfg: Pointer to DLYB configuration structure.
3407 * @retval HAL status.
3408 */
HAL_OSPI_DLYB_GetConfig(const OSPI_HandleTypeDef * hospi,HAL_OSPI_DLYB_CfgTypeDef * pdlyb_cfg)3409 HAL_StatusTypeDef HAL_OSPI_DLYB_GetConfig(const OSPI_HandleTypeDef *hospi, HAL_OSPI_DLYB_CfgTypeDef *pdlyb_cfg)
3410 {
3411 HAL_StatusTypeDef status = HAL_ERROR;
3412
3413 if (hospi->Instance == OCTOSPI1)
3414 {
3415 LL_DLYB_GetDelay(DLYB_OCTOSPI1, pdlyb_cfg);
3416 status = HAL_OK;
3417 }
3418 #if defined (OCTOSPI2)
3419 else if (hospi->Instance == OCTOSPI2)
3420 {
3421 LL_DLYB_GetDelay(DLYB_OCTOSPI2, pdlyb_cfg);
3422 status = HAL_OK;
3423 }
3424 #endif /* OCTOSPI2 */
3425
3426 else
3427 {
3428 /* Nothing to do */
3429 }
3430
3431 /* Return function status */
3432 return status;
3433 }
3434
3435 /**
3436 * @brief Get the Delay line length value.
3437 * @param hospi : OSPI handle.
3438 * @retval HAL status.
3439 */
HAL_OSPI_DLYB_GetClockPeriod(OSPI_HandleTypeDef * hospi,HAL_OSPI_DLYB_CfgTypeDef * pdlyb_cfg)3440 HAL_StatusTypeDef HAL_OSPI_DLYB_GetClockPeriod(OSPI_HandleTypeDef *hospi, HAL_OSPI_DLYB_CfgTypeDef *pdlyb_cfg)
3441 {
3442 HAL_StatusTypeDef status = HAL_ERROR;
3443
3444 /* Enable OCTOSPI Free Running Clock (mandatory) */
3445 SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
3446
3447 /* Update OCTOSPI state */
3448 hospi->State = HAL_OSPI_STATE_BUSY_CMD;
3449
3450 if (hospi->Instance == OCTOSPI1)
3451 {
3452 /* Enable the DelayBlock */
3453 LL_DLYB_Enable(DLYB_OCTOSPI1);
3454
3455 /* try to detect Period */
3456 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI1, pdlyb_cfg) == (uint32_t)SUCCESS)
3457 {
3458 status = HAL_OK;
3459 }
3460
3461 /* Disable the DelayBlock */
3462 LL_DLYB_Disable(DLYB_OCTOSPI1);
3463 }
3464
3465 #if defined (OCTOSPI2)
3466 else if (hospi->Instance == OCTOSPI2)
3467 {
3468 /* Enable the DelayBlock */
3469 LL_DLYB_Enable(DLYB_OCTOSPI2);
3470
3471 /* try to detect Period */
3472 if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI2, pdlyb_cfg) == (uint32_t)SUCCESS)
3473 {
3474 status = HAL_OK;
3475 }
3476
3477 /* Disable the DelayBlock */
3478 LL_DLYB_Disable(DLYB_OCTOSPI2);
3479 }
3480 #endif /* OCTOSPI2 */
3481
3482 else
3483 {
3484 /* Nothing to do */
3485 }
3486
3487 /* Abort the current OctoSPI operation if exist */
3488 (void)HAL_OSPI_Abort(hospi);
3489
3490 /* Disable Free Running Clock */
3491 CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
3492
3493 /* Return function status */
3494 return status;
3495 }
3496 /**
3497 @endcond
3498 */
3499
3500 /**
3501 * @}
3502 */
3503
3504 #endif /* HAL_OSPI_MODULE_ENABLED */
3505
3506 /**
3507 * @}
3508 */
3509
3510 /**
3511 * @}
3512 */
3513
3514 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3515