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