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