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