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