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