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