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