STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_ospi.c 00004 * @author MCD Application Team 00005 * @brief OSPI HAL module driver. 00006 This file provides firmware functions to manage the following 00007 functionalities of the OctoSPI interface (OSPI). 00008 + Initialization and de-initialization functions 00009 + Hyperbus configuration 00010 + Indirect functional mode management 00011 + Memory-mapped functional mode management 00012 + Auto-polling functional mode management 00013 + Interrupts and flags management 00014 + DMA channel configuration for indirect functional mode 00015 + Errors management and abort functionality 00016 + IO manager configuration 00017 00018 ****************************************************************************** 00019 * @attention 00020 * 00021 * Copyright (c) 2017 STMicroelectronics. 00022 * All rights reserved. 00023 * 00024 * This software is licensed under terms that can be found in the LICENSE file 00025 * in the root directory of this software component. 00026 * If no LICENSE file comes with this software, it is provided AS-IS. 00027 * 00028 ****************************************************************************** 00029 @verbatim 00030 =============================================================================== 00031 ##### How to use this driver ##### 00032 =============================================================================== 00033 [..] 00034 *** Initialization *** 00035 ====================== 00036 [..] 00037 As prerequisite, fill in the HAL_OSPI_MspInit() : 00038 (+) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE(). 00039 (+) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET(). 00040 (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). 00041 (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init(). 00042 (+) If interrupt or DMA mode is used, enable and configure OctoSPI global 00043 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). 00044 (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel 00045 with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), 00046 link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure 00047 DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). 00048 [..] 00049 Configure the fifo threshold, the dual-quad mode, the memory type, the 00050 device size, the CS high time, the free running clock, the clock mode, 00051 the wrap size, the clock prescaler, the sample shifting, the hold delay 00052 and the CS boundary using the HAL_OSPI_Init() function. 00053 [..] 00054 When using Hyperbus, configure the RW recovery time, the access time, 00055 the write latency and the latency mode unsing the HAL_OSPI_HyperbusCfg() 00056 function. 00057 00058 *** Indirect functional mode *** 00059 ================================ 00060 [..] 00061 In regular mode, configure the command sequence using the HAL_OSPI_Command() 00062 or HAL_OSPI_Command_IT() functions : 00063 (+) Instruction phase : the mode used and if present the size, the instruction 00064 opcode and the DTR mode. 00065 (+) Address phase : the mode used and if present the size, the address 00066 value and the DTR mode. 00067 (+) Alternate-bytes phase : the mode used and if present the size, the 00068 alternate bytes values and the DTR mode. 00069 (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). 00070 (+) Data phase : the mode used and if present the number of bytes and the DTR mode. 00071 (+) Data strobe (DQS) mode : the activation (or not) of this mode 00072 (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. 00073 (+) Flash identifier : in dual-quad mode, indicates which flash is concerned 00074 (+) Operation type : always common configuration 00075 [..] 00076 In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd() 00077 function : 00078 (+) Address space : indicate if the access will be done in register or memory 00079 (+) Address size 00080 (+) Number of data 00081 (+) Data strobe (DQS) mode : the activation (or not) of this mode 00082 [..] 00083 If no data is required for the command (only for regular mode, not for 00084 Hyperbus mode), it is sent directly to the memory : 00085 (+) In polling mode, the output of the function is done when the transfer is complete. 00086 (+) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete. 00087 [..] 00088 For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or 00089 HAL_OSPI_Transmit_IT() after the command configuration : 00090 (+) In polling mode, the output of the function is done when the transfer is complete. 00091 (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold 00092 is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete. 00093 (+) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and 00094 HAL_OSPI_TxCpltCallback() will be called when the transfer is complete. 00095 [..] 00096 For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or 00097 HAL_OSPI_Receive_IT() after the command configuration : 00098 (+) In polling mode, the output of the function is done when the transfer is complete. 00099 (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold 00100 is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete. 00101 (+) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and 00102 HAL_OSPI_RxCpltCallback() will be called when the transfer is complete. 00103 00104 *** Auto-polling functional mode *** 00105 ==================================== 00106 [..] 00107 Configure the command sequence by the same way than the indirect mode 00108 [..] 00109 Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling() 00110 or HAL_OSPI_AutoPolling_IT() functions : 00111 (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND), 00112 the polling interval and the automatic stop activation. 00113 [..] 00114 After the configuration : 00115 (+) In polling mode, the output of the function is done when the status match is reached. The 00116 automatic stop is activated to avoid an infinite loop. 00117 (+) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached. 00118 00119 *** MDMA functional mode *** 00120 ==================================== 00121 [..] 00122 Configure the SourceInc and DestinationInc of MDMA paramters in the HAL_OSPI_MspInit() function : 00123 (+) MDMA settings for write operation : 00124 (++) The DestinationInc should be MDMA_DEST_INC_DISABLE 00125 (++) The SourceInc must be a value of @ref MDMA_Source_increment_mode (Except the MDMA_SRC_INC_DOUBLEWORD). 00126 (++) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) 00127 aligned with @ref MDMA_Source_increment_mode . 00128 (++) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD) 00129 (+) MDMA settings for read operation : 00130 (++) The SourceInc should be MDMA_SRC_INC_DISABLE 00131 (++) The DestinationInc must be a value of @ref MDMA_Destination_increment_mode (Except the MDMA_DEST_INC_DOUBLEWORD). 00132 (++) The SourceDataSize must be a value of @ref MDMA Source data size (Except the MDMA_SRC_DATASIZE_DOUBLEWORD) . 00133 (++) The DestDataSize must be a value of @ref MDMA Destination data size (Except the MDMA_DEST_DATASIZE_DOUBLEWORD) 00134 aligned with @ref MDMA_Destination_increment_mode. 00135 (+) The buffer Transfer Length (BufferTransferLength) = number of bytes in the FIFO (FifoThreshold) of the Octospi. 00136 [..] 00137 In case of wrong MDMA setting 00138 (+) For write operation : 00139 (++) If the DestinationInc is different to MDMA_DEST_INC_DISABLE , it will be disabled by the HAL_OSPI_Transmit_DMA(). 00140 (+) For read operation : 00141 (++) If the SourceInc is not set to MDMA_SRC_INC_DISABLE , it will be disabled by the HAL_OSPI_Receive_DMA(). 00142 00143 *** Memory-mapped functional mode *** 00144 ===================================== 00145 [..] 00146 Configure the command sequence by the same way than the indirect mode except 00147 for the operation type in regular mode : 00148 (+) Operation type equals to read configuration : the command configuration 00149 applies to read access in memory-mapped mode 00150 (+) Operation type equals to write configuration : the command configuration 00151 applies to write access in memory-mapped mode 00152 (+) Both read and write configuration should be performed before activating 00153 memory-mapped mode 00154 [..] 00155 Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped() 00156 functions : 00157 (+) The timeout activation and the timeout period. 00158 [..] 00159 After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on 00160 the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires. 00161 00162 *** Errors management and abort functionality *** 00163 ================================================= 00164 [..] 00165 HAL_OSPI_GetError() function gives the error raised during the last operation. 00166 [..] 00167 HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and 00168 flushes the fifo : 00169 (+) In polling mode, the output of the function is done when the transfer 00170 complete bit is set and the busy bit cleared. 00171 (+) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when 00172 the transfer complete bit is set. 00173 00174 *** Control functions *** 00175 ========================= 00176 [..] 00177 HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver. 00178 [..] 00179 HAL_OSPI_SetTimeout() function configures the timeout value used in the driver. 00180 [..] 00181 HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral. 00182 [..] 00183 HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold 00184 00185 *** IO manager configuration functions *** 00186 ========================================== 00187 [..] 00188 HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance. 00189 00190 *** Callback registration *** 00191 ============================================= 00192 [..] 00193 The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1 00194 allows the user to configure dynamically the driver callbacks. 00195 00196 [..] 00197 Use function HAL_OSPI_RegisterCallback() to register a user callback, 00198 it allows to register following callbacks: 00199 (+) ErrorCallback : callback when error occurs. 00200 (+) AbortCpltCallback : callback when abort is completed. 00201 (+) FifoThresholdCallback : callback when the fifo threshold is reached. 00202 (+) CmdCpltCallback : callback when a command without data is completed. 00203 (+) RxCpltCallback : callback when a reception transfer is completed. 00204 (+) TxCpltCallback : callback when a transmission transfer is completed. 00205 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed. 00206 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed. 00207 (+) StatusMatchCallback : callback when a status match occurs. 00208 (+) TimeOutCallback : callback when the timeout perioed expires. 00209 (+) MspInitCallback : OSPI MspInit. 00210 (+) MspDeInitCallback : OSPI MspDeInit. 00211 [..] 00212 This function takes as parameters the HAL peripheral handle, the Callback ID 00213 and a pointer to the user callback function. 00214 00215 [..] 00216 Use function HAL_OSPI_UnRegisterCallback() to reset a callback to the default 00217 weak (surcharged) function. It allows to reset following callbacks: 00218 (+) ErrorCallback : callback when error occurs. 00219 (+) AbortCpltCallback : callback when abort is completed. 00220 (+) FifoThresholdCallback : callback when the fifo threshold is reached. 00221 (+) CmdCpltCallback : callback when a command without data is completed. 00222 (+) RxCpltCallback : callback when a reception transfer is completed. 00223 (+) TxCpltCallback : callback when a transmission transfer is completed. 00224 (+) RxHalfCpltCallback : callback when half of the reception transfer is completed. 00225 (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed. 00226 (+) StatusMatchCallback : callback when a status match occurs. 00227 (+) TimeOutCallback : callback when the timeout perioed expires. 00228 (+) MspInitCallback : OSPI MspInit. 00229 (+) MspDeInitCallback : OSPI MspDeInit. 00230 [..] 00231 This function) takes as parameters the HAL peripheral handle and the Callback ID. 00232 00233 [..] 00234 By default, after the HAL_OSPI_Init() and if the state is HAL_OSPI_STATE_RESET 00235 all callbacks are reset to the corresponding legacy weak (surcharged) functions. 00236 Exception done for MspInit and MspDeInit callbacks that are respectively 00237 reset to the legacy weak (surcharged) functions in the HAL_OSPI_Init() 00238 and HAL_OSPI_DeInit() only when these callbacks are null (not registered beforehand). 00239 If not, MspInit or MspDeInit are not null, the HAL_OSPI_Init() and HAL_OSPI_DeInit() 00240 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) 00241 00242 [..] 00243 Callbacks can be registered/unregistered in READY state only. 00244 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00245 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00246 during the Init/DeInit. 00247 In that case first register the MspInit/MspDeInit user callbacks 00248 using HAL_OSPI_RegisterCallback() before calling HAL_OSPI_DeInit() 00249 or HAL_OSPI_Init() function. 00250 00251 [..] 00252 When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or 00253 not defined, the callback registering feature is not available 00254 and weak (surcharged) callbacks are used. 00255 00256 @endverbatim 00257 ****************************************************************************** 00258 */ 00259 00260 /* Includes ------------------------------------------------------------------*/ 00261 #include "stm32h7xx_hal.h" 00262 00263 #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2) 00264 00265 /** @addtogroup STM32H7xx_HAL_Driver 00266 * @{ 00267 */ 00268 00269 /** @defgroup OSPI OSPI 00270 * @brief OSPI HAL module driver 00271 * @{ 00272 */ 00273 00274 #ifdef HAL_OSPI_MODULE_ENABLED 00275 00276 /** 00277 @cond 0 00278 */ 00279 /* Private typedef -----------------------------------------------------------*/ 00280 00281 /* Private define ------------------------------------------------------------*/ 00282 #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!< Indirect write mode */ 00283 #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode */ 00284 #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */ 00285 #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)OCTOSPI_CR_FMODE) /*!< Memory-mapped mode */ 00286 00287 #define OSPI_CFG_STATE_MASK 0x00000004U 00288 #define OSPI_BUSY_STATE_MASK 0x00000008U 00289 00290 #define OSPI_NB_INSTANCE 2U 00291 #define OSPI_IOM_NB_PORTS 2U 00292 #define OSPI_IOM_PORT_MASK 0x1U 00293 00294 /* Private macro -------------------------------------------------------------*/ 00295 #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \ 00296 ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \ 00297 ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \ 00298 ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)) 00299 00300 /* Private variables ---------------------------------------------------------*/ 00301 00302 /* Private function prototypes -----------------------------------------------*/ 00303 static void OSPI_DMACplt (MDMA_HandleTypeDef *hmdma); 00304 static void OSPI_DMAError (MDMA_HandleTypeDef *hmdma); 00305 static void OSPI_DMAAbortCplt (MDMA_HandleTypeDef *hmdma); 00306 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State, 00307 uint32_t Tickstart, uint32_t Timeout); 00308 static HAL_StatusTypeDef OSPI_ConfigCmd (OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd); 00309 static HAL_StatusTypeDef OSPIM_GetConfig (uint8_t instance_nb, OSPIM_CfgTypeDef *cfg); 00310 /** 00311 @endcond 00312 */ 00313 00314 /* Exported functions --------------------------------------------------------*/ 00315 00316 /** @defgroup OSPI_Exported_Functions OSPI Exported Functions 00317 * @{ 00318 */ 00319 00320 /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions 00321 * @brief Initialization and Configuration functions 00322 * 00323 @verbatim 00324 =============================================================================== 00325 ##### Initialization and Configuration functions ##### 00326 =============================================================================== 00327 [..] 00328 This subsection provides a set of functions allowing to : 00329 (+) Initialize the OctoSPI. 00330 (+) De-initialize the OctoSPI. 00331 00332 @endverbatim 00333 * @{ 00334 */ 00335 00336 /** 00337 * @brief Initialize the OSPI mode according to the specified parameters 00338 * in the OSPI_InitTypeDef and initialize the associated handle. 00339 * @param hospi : OSPI handle 00340 * @retval HAL status 00341 */ 00342 HAL_StatusTypeDef HAL_OSPI_Init (OSPI_HandleTypeDef *hospi) 00343 { 00344 HAL_StatusTypeDef status = HAL_OK; 00345 uint32_t tickstart = HAL_GetTick(); 00346 00347 /* Check the OSPI handle allocation */ 00348 if (hospi == NULL) 00349 { 00350 status = HAL_ERROR; 00351 /* No error code can be set set as the handler is null */ 00352 } 00353 else 00354 { 00355 /* Check the parameters of the initialization structure */ 00356 assert_param(IS_OSPI_FIFO_THRESHOLD (hospi->Init.FifoThreshold)); 00357 assert_param(IS_OSPI_DUALQUAD_MODE (hospi->Init.DualQuad)); 00358 assert_param(IS_OSPI_MEMORY_TYPE (hospi->Init.MemoryType)); 00359 assert_param(IS_OSPI_DEVICE_SIZE (hospi->Init.DeviceSize)); 00360 assert_param(IS_OSPI_CS_HIGH_TIME (hospi->Init.ChipSelectHighTime)); 00361 assert_param(IS_OSPI_FREE_RUN_CLK (hospi->Init.FreeRunningClock)); 00362 assert_param(IS_OSPI_CLOCK_MODE (hospi->Init.ClockMode)); 00363 assert_param(IS_OSPI_WRAP_SIZE (hospi->Init.WrapSize)); 00364 assert_param(IS_OSPI_CLK_PRESCALER (hospi->Init.ClockPrescaler)); 00365 assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting)); 00366 assert_param(IS_OSPI_DHQC (hospi->Init.DelayHoldQuarterCycle)); 00367 assert_param(IS_OSPI_CS_BOUNDARY (hospi->Init.ChipSelectBoundary)); 00368 assert_param(IS_OSPI_CKCSHT (hospi->Init.ClkChipSelectHighTime)); 00369 assert_param(IS_OSPI_MAXTRAN (hospi->Init.MaxTran)); 00370 00371 /* Initialize error code */ 00372 hospi->ErrorCode = HAL_OSPI_ERROR_NONE; 00373 00374 /* Check if the state is the reset state */ 00375 if (hospi->State == HAL_OSPI_STATE_RESET) 00376 { 00377 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00378 /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */ 00379 hospi->ErrorCallback = HAL_OSPI_ErrorCallback; 00380 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback; 00381 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback; 00382 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback; 00383 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback; 00384 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback; 00385 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback; 00386 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback; 00387 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback; 00388 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback; 00389 00390 if(hospi->MspInitCallback == NULL) 00391 { 00392 hospi->MspInitCallback = HAL_OSPI_MspInit; 00393 } 00394 00395 /* Init the low level hardware */ 00396 hospi->MspInitCallback(hospi); 00397 #else 00398 /* Initialization of the low level hardware */ 00399 HAL_OSPI_MspInit(hospi); 00400 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00401 00402 /* Configure the default timeout for the OSPI memory access */ 00403 (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE); 00404 00405 /* Configure memory type, device size, chip select high time, clocked chip select high time, free running clock, clock mode */ 00406 MODIFY_REG(hospi->Instance->DCR1, 00407 (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_CKCSHT | 00408 OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE), 00409 (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) | 00410 ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) | 00411 (hospi->Init.ClkChipSelectHighTime << OCTOSPI_DCR1_CKCSHT_Pos) | hospi->Init.ClockMode)); 00412 00413 /* Configure wrap size */ 00414 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize); 00415 00416 /* Configure chip select boundary and maximum transfer */ 00417 hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) | 00418 (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos)); 00419 00420 /* Configure refresh */ 00421 hospi->Instance->DCR4 = hospi->Init.Refresh; 00422 00423 /* Configure FIFO threshold */ 00424 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos)); 00425 00426 /* Wait till busy flag is reset */ 00427 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); 00428 00429 if (status == HAL_OK) 00430 { 00431 /* Configure clock prescaler */ 00432 MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, 00433 ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos)); 00434 00435 /* Configure Dual Quad mode */ 00436 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad); 00437 00438 /* Configure sample shifting and delay hold quarter cycle */ 00439 MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), 00440 (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle)); 00441 00442 /* Enable OctoSPI */ 00443 __HAL_OSPI_ENABLE(hospi); 00444 00445 /* Enable free running clock if needed : must be done after OSPI enable */ 00446 if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE) 00447 { 00448 SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK); 00449 } 00450 00451 /* Initialize the OSPI state */ 00452 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 00453 { 00454 hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT; 00455 } 00456 else 00457 { 00458 hospi->State = HAL_OSPI_STATE_READY; 00459 } 00460 } 00461 } 00462 } 00463 00464 /* Return function status */ 00465 return status; 00466 } 00467 00468 /** 00469 * @brief Initialize the OSPI MSP. 00470 * @param hospi : OSPI handle 00471 * @retval None 00472 */ 00473 __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi) 00474 { 00475 /* Prevent unused argument(s) compilation warning */ 00476 UNUSED(hospi); 00477 00478 /* NOTE : This function should not be modified, when the callback is needed, 00479 the HAL_OSPI_MspInit can be implemented in the user file 00480 */ 00481 } 00482 00483 /** 00484 * @brief De-Initialize the OSPI peripheral. 00485 * @param hospi : OSPI handle 00486 * @retval HAL status 00487 */ 00488 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi) 00489 { 00490 HAL_StatusTypeDef status = HAL_OK; 00491 00492 /* Check the OSPI handle allocation */ 00493 if (hospi == NULL) 00494 { 00495 status = HAL_ERROR; 00496 /* No error code can be set set as the handler is null */ 00497 } 00498 else 00499 { 00500 /* Disable OctoSPI */ 00501 __HAL_OSPI_DISABLE(hospi); 00502 00503 /* Disable free running clock if needed : must be done after OSPI disable */ 00504 CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK); 00505 00506 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00507 if(hospi->MspDeInitCallback == NULL) 00508 { 00509 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit; 00510 } 00511 00512 /* DeInit the low level hardware */ 00513 hospi->MspDeInitCallback(hospi); 00514 #else 00515 /* De-initialize the low-level hardware */ 00516 HAL_OSPI_MspDeInit(hospi); 00517 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00518 00519 /* Reset the driver state */ 00520 hospi->State = HAL_OSPI_STATE_RESET; 00521 } 00522 00523 return status; 00524 } 00525 00526 /** 00527 * @brief DeInitialize the OSPI MSP. 00528 * @param hospi : OSPI handle 00529 * @retval None 00530 */ 00531 __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi) 00532 { 00533 /* Prevent unused argument(s) compilation warning */ 00534 UNUSED(hospi); 00535 00536 /* NOTE : This function should not be modified, when the callback is needed, 00537 the HAL_OSPI_MspDeInit can be implemented in the user file 00538 */ 00539 } 00540 00541 /** 00542 * @} 00543 */ 00544 00545 /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions 00546 * @brief OSPI Transmit/Receive functions 00547 * 00548 @verbatim 00549 =============================================================================== 00550 ##### IO operation functions ##### 00551 =============================================================================== 00552 [..] 00553 This subsection provides a set of functions allowing to : 00554 (+) Handle the interrupts. 00555 (+) Handle the command sequence (regular and Hyperbus). 00556 (+) Handle the Hyperbus configuration. 00557 (+) Transmit data in blocking, interrupt or DMA mode. 00558 (+) Receive data in blocking, interrupt or DMA mode. 00559 (+) Manage the auto-polling functional mode. 00560 (+) Manage the memory-mapped functional mode. 00561 00562 @endverbatim 00563 * @{ 00564 */ 00565 00566 /** 00567 * @brief Handle OSPI interrupt request. 00568 * @param hospi : OSPI handle 00569 * @retval None 00570 */ 00571 void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi) 00572 { 00573 __IO uint32_t *data_reg = &hospi->Instance->DR; 00574 uint32_t flag = hospi->Instance->SR; 00575 uint32_t itsource = hospi->Instance->CR; 00576 uint32_t currentstate = hospi->State; 00577 00578 /* OctoSPI fifo threshold interrupt occurred -------------------------------*/ 00579 if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U)) 00580 { 00581 if (currentstate == HAL_OSPI_STATE_BUSY_TX) 00582 { 00583 /* Write a data in the fifo */ 00584 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr; 00585 hospi->pBuffPtr++; 00586 hospi->XferCount--; 00587 } 00588 else if (currentstate == HAL_OSPI_STATE_BUSY_RX) 00589 { 00590 /* Read a data from the fifo */ 00591 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg); 00592 hospi->pBuffPtr++; 00593 hospi->XferCount--; 00594 } 00595 else 00596 { 00597 /* Nothing to do */ 00598 } 00599 00600 if (hospi->XferCount == 0U) 00601 { 00602 /* All data have been received or transmitted for the transfer */ 00603 /* Disable fifo threshold interrupt */ 00604 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT); 00605 } 00606 00607 /* Fifo threshold callback */ 00608 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00609 hospi->FifoThresholdCallback(hospi); 00610 #else 00611 HAL_OSPI_FifoThresholdCallback(hospi); 00612 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/ 00613 } 00614 /* OctoSPI transfer complete interrupt occurred ----------------------------*/ 00615 else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U)) 00616 { 00617 if (currentstate == HAL_OSPI_STATE_BUSY_RX) 00618 { 00619 if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U)) 00620 { 00621 /* Read the last data received in the fifo */ 00622 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg); 00623 hospi->pBuffPtr++; 00624 hospi->XferCount--; 00625 } 00626 else if(hospi->XferCount == 0U) 00627 { 00628 /* Clear flag */ 00629 hospi->Instance->FCR = HAL_OSPI_FLAG_TC; 00630 00631 /* Disable the interrupts */ 00632 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE); 00633 00634 /* Update state */ 00635 hospi->State = HAL_OSPI_STATE_READY; 00636 00637 /* RX complete callback */ 00638 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00639 hospi->RxCpltCallback(hospi); 00640 #else 00641 HAL_OSPI_RxCpltCallback(hospi); 00642 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00643 } 00644 else 00645 { 00646 /* Nothing to do */ 00647 } 00648 } 00649 else 00650 { 00651 /* Clear flag */ 00652 hospi->Instance->FCR = HAL_OSPI_FLAG_TC; 00653 00654 /* Disable the interrupts */ 00655 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE); 00656 00657 /* Update state */ 00658 hospi->State = HAL_OSPI_STATE_READY; 00659 00660 if (currentstate == HAL_OSPI_STATE_BUSY_TX) 00661 { 00662 /* TX complete callback */ 00663 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00664 hospi->TxCpltCallback(hospi); 00665 #else 00666 HAL_OSPI_TxCpltCallback(hospi); 00667 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00668 } 00669 else if (currentstate == HAL_OSPI_STATE_BUSY_CMD) 00670 { 00671 /* Command complete callback */ 00672 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00673 hospi->CmdCpltCallback(hospi); 00674 #else 00675 HAL_OSPI_CmdCpltCallback(hospi); 00676 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00677 } 00678 else if (currentstate == HAL_OSPI_STATE_ABORT) 00679 { 00680 if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE) 00681 { 00682 /* Abort called by the user */ 00683 /* Abort complete callback */ 00684 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00685 hospi->AbortCpltCallback(hospi); 00686 #else 00687 HAL_OSPI_AbortCpltCallback(hospi); 00688 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/ 00689 } 00690 else 00691 { 00692 /* Abort due to an error (eg : DMA error) */ 00693 /* Error callback */ 00694 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00695 hospi->ErrorCallback(hospi); 00696 #else 00697 HAL_OSPI_ErrorCallback(hospi); 00698 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00699 } 00700 } 00701 else 00702 { 00703 /* Nothing to do */ 00704 } 00705 } 00706 } 00707 /* OctoSPI status match interrupt occurred ---------------------------------*/ 00708 else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U)) 00709 { 00710 /* Clear flag */ 00711 hospi->Instance->FCR = HAL_OSPI_FLAG_SM; 00712 00713 /* Check if automatic poll mode stop is activated */ 00714 if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U) 00715 { 00716 /* Disable the interrupts */ 00717 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE); 00718 00719 /* Update state */ 00720 hospi->State = HAL_OSPI_STATE_READY; 00721 } 00722 00723 /* Status match callback */ 00724 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00725 hospi->StatusMatchCallback(hospi); 00726 #else 00727 HAL_OSPI_StatusMatchCallback(hospi); 00728 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00729 } 00730 /* OctoSPI transfer error interrupt occurred -------------------------------*/ 00731 else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U)) 00732 { 00733 /* Clear flag */ 00734 hospi->Instance->FCR = HAL_OSPI_FLAG_TE; 00735 00736 /* Disable all interrupts */ 00737 __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)); 00738 00739 /* Set error code */ 00740 hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER; 00741 00742 /* Check if the DMA is enabled */ 00743 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U) 00744 { 00745 /* Disable the DMA transfer on the OctoSPI side */ 00746 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN); 00747 00748 /* Disable the DMA transfer on the DMA side */ 00749 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt; 00750 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK) 00751 { 00752 /* Update state */ 00753 hospi->State = HAL_OSPI_STATE_READY; 00754 00755 /* Error callback */ 00756 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00757 hospi->ErrorCallback(hospi); 00758 #else 00759 HAL_OSPI_ErrorCallback(hospi); 00760 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/ 00761 } 00762 } 00763 else 00764 { 00765 /* Update state */ 00766 hospi->State = HAL_OSPI_STATE_READY; 00767 00768 /* Error callback */ 00769 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00770 hospi->ErrorCallback(hospi); 00771 #else 00772 HAL_OSPI_ErrorCallback(hospi); 00773 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00774 } 00775 } 00776 /* OctoSPI timeout interrupt occurred --------------------------------------*/ 00777 else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U)) 00778 { 00779 /* Clear flag */ 00780 hospi->Instance->FCR = HAL_OSPI_FLAG_TO; 00781 00782 /* Timeout callback */ 00783 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 00784 hospi->TimeOutCallback(hospi); 00785 #else 00786 HAL_OSPI_TimeOutCallback(hospi); 00787 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 00788 } 00789 else 00790 { 00791 /* Nothing to do */ 00792 } 00793 } 00794 00795 /** 00796 * @brief Set the command configuration. 00797 * @param hospi : OSPI handle 00798 * @param cmd : structure that contains the command configuration information 00799 * @param Timeout : Timeout duration 00800 * @retval HAL status 00801 */ 00802 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout) 00803 { 00804 HAL_StatusTypeDef status; 00805 uint32_t state; 00806 uint32_t tickstart = HAL_GetTick(); 00807 00808 /* Check the parameters of the command structure */ 00809 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType)); 00810 00811 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE) 00812 { 00813 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId)); 00814 } 00815 00816 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 00817 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) 00818 { 00819 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize)); 00820 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode)); 00821 } 00822 00823 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode)); 00824 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) 00825 { 00826 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize)); 00827 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode)); 00828 } 00829 00830 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode)); 00831 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) 00832 { 00833 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize)); 00834 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode)); 00835 } 00836 00837 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode)); 00838 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 00839 { 00840 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) 00841 { 00842 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData)); 00843 } 00844 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode)); 00845 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles)); 00846 } 00847 00848 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode)); 00849 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode)); 00850 00851 /* Check the state of the driver */ 00852 state = hospi->State; 00853 if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || 00854 ((state == HAL_OSPI_STATE_READ_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) 00855 || (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG))) || 00856 ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && ((cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) || 00857 (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG)))) 00858 { 00859 /* Wait till busy flag is reset */ 00860 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); 00861 00862 if (status == HAL_OK) 00863 { 00864 /* Initialize error code */ 00865 hospi->ErrorCode = HAL_OSPI_ERROR_NONE; 00866 00867 /* Configure the registers */ 00868 status = OSPI_ConfigCmd(hospi, cmd); 00869 00870 if (status == HAL_OK) 00871 { 00872 if (cmd->DataMode == HAL_OSPI_DATA_NONE) 00873 { 00874 /* When there is no data phase, the transfer start as soon as the configuration is done 00875 so wait until TC flag is set to go back in idle state */ 00876 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); 00877 00878 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 00879 } 00880 else 00881 { 00882 /* Update the state */ 00883 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) 00884 { 00885 hospi->State = HAL_OSPI_STATE_CMD_CFG; 00886 } 00887 else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) 00888 { 00889 if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG) 00890 { 00891 hospi->State = HAL_OSPI_STATE_CMD_CFG; 00892 } 00893 else 00894 { 00895 hospi->State = HAL_OSPI_STATE_READ_CMD_CFG; 00896 } 00897 } 00898 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) 00899 { 00900 if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG) 00901 { 00902 hospi->State = HAL_OSPI_STATE_CMD_CFG; 00903 } 00904 else 00905 { 00906 hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG; 00907 } 00908 } 00909 else 00910 { 00911 /* Wrap configuration, no state change */ 00912 } 00913 } 00914 } 00915 } 00916 } 00917 else 00918 { 00919 status = HAL_ERROR; 00920 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 00921 } 00922 00923 /* Return function status */ 00924 return status; 00925 } 00926 00927 /** 00928 * @brief Set the command configuration in interrupt mode. 00929 * @param hospi : OSPI handle 00930 * @param cmd : structure that contains the command configuration information 00931 * @note This function is used only in Indirect Read or Write Modes 00932 * @retval HAL status 00933 */ 00934 HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd) 00935 { 00936 HAL_StatusTypeDef status; 00937 uint32_t tickstart = HAL_GetTick(); 00938 00939 /* Check the parameters of the command structure */ 00940 assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType)); 00941 00942 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE) 00943 { 00944 assert_param(IS_OSPI_FLASH_ID(cmd->FlashId)); 00945 } 00946 00947 assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode)); 00948 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) 00949 { 00950 assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize)); 00951 assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode)); 00952 } 00953 00954 assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode)); 00955 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) 00956 { 00957 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize)); 00958 assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode)); 00959 } 00960 00961 assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode)); 00962 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) 00963 { 00964 assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize)); 00965 assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode)); 00966 } 00967 00968 assert_param(IS_OSPI_DATA_MODE(cmd->DataMode)); 00969 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 00970 { 00971 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData)); 00972 assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode)); 00973 assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles)); 00974 } 00975 00976 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode)); 00977 assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode)); 00978 00979 /* Check the state of the driver */ 00980 if ((hospi->State == HAL_OSPI_STATE_READY) && (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) && 00981 (cmd->DataMode == HAL_OSPI_DATA_NONE) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) 00982 { 00983 /* Wait till busy flag is reset */ 00984 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); 00985 00986 if (status == HAL_OK) 00987 { 00988 /* Initialize error code */ 00989 hospi->ErrorCode = HAL_OSPI_ERROR_NONE; 00990 00991 /* Clear flags related to interrupt */ 00992 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC); 00993 00994 /* Configure the registers */ 00995 status = OSPI_ConfigCmd(hospi, cmd); 00996 00997 if (status == HAL_OK) 00998 { 00999 /* Update the state */ 01000 hospi->State = HAL_OSPI_STATE_BUSY_CMD; 01001 01002 /* Enable the transfer complete and transfer error interrupts */ 01003 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE); 01004 } 01005 } 01006 } 01007 else 01008 { 01009 status = HAL_ERROR; 01010 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01011 } 01012 01013 /* Return function status */ 01014 return status; 01015 } 01016 01017 /** 01018 * @brief Configure the Hyperbus parameters. 01019 * @param hospi : OSPI handle 01020 * @param cfg : Structure containing the Hyperbus configuration 01021 * @param Timeout : Timeout duration 01022 * @retval HAL status 01023 */ 01024 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout) 01025 { 01026 HAL_StatusTypeDef status; 01027 uint32_t state; 01028 uint32_t tickstart = HAL_GetTick(); 01029 01030 /* Check the parameters of the hyperbus configuration structure */ 01031 assert_param(IS_OSPI_RW_RECOVERY_TIME (cfg->RWRecoveryTime)); 01032 assert_param(IS_OSPI_ACCESS_TIME (cfg->AccessTime)); 01033 assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency)); 01034 assert_param(IS_OSPI_LATENCY_MODE (cfg->LatencyMode)); 01035 01036 /* Check the state of the driver */ 01037 state = hospi->State; 01038 if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY)) 01039 { 01040 /* Wait till busy flag is reset */ 01041 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); 01042 01043 if (status == HAL_OK) 01044 { 01045 /* Configure Hyperbus configuration Latency register */ 01046 WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) | 01047 (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos) | 01048 cfg->WriteZeroLatency | cfg->LatencyMode)); 01049 01050 /* Update the state */ 01051 hospi->State = HAL_OSPI_STATE_READY; 01052 } 01053 } 01054 else 01055 { 01056 status = HAL_ERROR; 01057 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01058 } 01059 01060 /* Return function status */ 01061 return status; 01062 } 01063 01064 /** 01065 * @brief Set the Hyperbus command configuration. 01066 * @param hospi : OSPI handle 01067 * @param cmd : Structure containing the Hyperbus command 01068 * @param Timeout : Timeout duration 01069 * @retval HAL status 01070 */ 01071 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout) 01072 { 01073 HAL_StatusTypeDef status; 01074 uint32_t tickstart = HAL_GetTick(); 01075 01076 /* Check the parameters of the hyperbus command structure */ 01077 assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace)); 01078 assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize)); 01079 assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData)); 01080 assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode)); 01081 01082 /* Check the state of the driver */ 01083 if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)) 01084 { 01085 /* Wait till busy flag is reset */ 01086 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); 01087 01088 if (status == HAL_OK) 01089 { 01090 /* Re-initialize the value of the functional mode */ 01091 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); 01092 01093 /* Configure the address space in the DCR1 register */ 01094 MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace); 01095 01096 /* Configure the CCR and WCCR registers with the address size and the following configuration : 01097 - DQS signal enabled (used as RWDS) 01098 - DTR mode enabled on address and data 01099 - address and data on 8 lines */ 01100 WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 | 01101 cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2)); 01102 WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 | 01103 cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2)); 01104 01105 /* Configure the DLR register with the number of data */ 01106 WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U)); 01107 01108 /* Configure the AR register with the address value */ 01109 WRITE_REG(hospi->Instance->AR, cmd->Address); 01110 01111 /* Update the state */ 01112 hospi->State = HAL_OSPI_STATE_CMD_CFG; 01113 } 01114 } 01115 else 01116 { 01117 status = HAL_ERROR; 01118 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01119 } 01120 01121 /* Return function status */ 01122 return status; 01123 } 01124 01125 /** 01126 * @brief Transmit an amount of data in blocking mode. 01127 * @param hospi : OSPI handle 01128 * @param pData : pointer to data buffer 01129 * @param Timeout : Timeout duration 01130 * @note This function is used only in Indirect Write Mode 01131 * @retval HAL status 01132 */ 01133 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout) 01134 { 01135 HAL_StatusTypeDef status; 01136 uint32_t tickstart = HAL_GetTick(); 01137 __IO uint32_t *data_reg = &hospi->Instance->DR; 01138 01139 /* Check the data pointer allocation */ 01140 if (pData == NULL) 01141 { 01142 status = HAL_ERROR; 01143 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01144 } 01145 else 01146 { 01147 /* Check the state */ 01148 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01149 { 01150 /* Configure counters and size */ 01151 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; 01152 hospi->XferSize = hospi->XferCount; 01153 hospi->pBuffPtr = pData; 01154 01155 /* Configure CR register with functional mode as indirect write */ 01156 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 01157 01158 do 01159 { 01160 /* Wait till fifo threshold flag is set to send data */ 01161 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout); 01162 01163 if (status != HAL_OK) 01164 { 01165 break; 01166 } 01167 01168 *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr; 01169 hospi->pBuffPtr++; 01170 hospi->XferCount--; 01171 } while (hospi->XferCount > 0U); 01172 01173 if (status == HAL_OK) 01174 { 01175 /* Wait till transfer complete flag is set to go back in idle state */ 01176 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); 01177 01178 if (status == HAL_OK) 01179 { 01180 /* Clear transfer complete flag */ 01181 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 01182 01183 /* Update state */ 01184 hospi->State = HAL_OSPI_STATE_READY; 01185 } 01186 } 01187 } 01188 else 01189 { 01190 status = HAL_ERROR; 01191 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01192 } 01193 } 01194 01195 /* Return function status */ 01196 return status; 01197 } 01198 01199 /** 01200 * @brief Receive an amount of data in blocking mode. 01201 * @param hospi : OSPI handle 01202 * @param pData : pointer to data buffer 01203 * @param Timeout : Timeout duration 01204 * @note This function is used only in Indirect Read Mode 01205 * @retval HAL status 01206 */ 01207 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout) 01208 { 01209 HAL_StatusTypeDef status; 01210 uint32_t tickstart = HAL_GetTick(); 01211 __IO uint32_t *data_reg = &hospi->Instance->DR; 01212 uint32_t addr_reg = hospi->Instance->AR; 01213 uint32_t ir_reg = hospi->Instance->IR; 01214 01215 /* Check the data pointer allocation */ 01216 if (pData == NULL) 01217 { 01218 status = HAL_ERROR; 01219 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01220 } 01221 else 01222 { 01223 /* Check the state */ 01224 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01225 { 01226 /* Configure counters and size */ 01227 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; 01228 hospi->XferSize = hospi->XferCount; 01229 hospi->pBuffPtr = pData; 01230 01231 /* Configure CR register with functional mode as indirect read */ 01232 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); 01233 01234 /* Trig the transfer by re-writing address or instruction register */ 01235 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 01236 { 01237 WRITE_REG(hospi->Instance->AR, addr_reg); 01238 } 01239 else 01240 { 01241 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) 01242 { 01243 WRITE_REG(hospi->Instance->AR, addr_reg); 01244 } 01245 else 01246 { 01247 WRITE_REG(hospi->Instance->IR, ir_reg); 01248 } 01249 } 01250 01251 do 01252 { 01253 /* Wait till fifo threshold or transfer complete flags are set to read received data */ 01254 status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout); 01255 01256 if (status != HAL_OK) 01257 { 01258 break; 01259 } 01260 01261 *hospi->pBuffPtr = *((__IO uint8_t *)data_reg); 01262 hospi->pBuffPtr++; 01263 hospi->XferCount--; 01264 } while(hospi->XferCount > 0U); 01265 01266 if (status == HAL_OK) 01267 { 01268 /* Wait till transfer complete flag is set to go back in idle state */ 01269 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); 01270 01271 if (status == HAL_OK) 01272 { 01273 /* Clear transfer complete flag */ 01274 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 01275 01276 /* Update state */ 01277 hospi->State = HAL_OSPI_STATE_READY; 01278 } 01279 } 01280 } 01281 else 01282 { 01283 status = HAL_ERROR; 01284 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01285 } 01286 } 01287 01288 /* Return function status */ 01289 return status; 01290 } 01291 01292 /** 01293 * @brief Send an amount of data in non-blocking mode with interrupt. 01294 * @param hospi : OSPI handle 01295 * @param pData : pointer to data buffer 01296 * @note This function is used only in Indirect Write Mode 01297 * @retval HAL status 01298 */ 01299 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData) 01300 { 01301 HAL_StatusTypeDef status = HAL_OK; 01302 01303 /* Check the data pointer allocation */ 01304 if (pData == NULL) 01305 { 01306 status = HAL_ERROR; 01307 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01308 } 01309 else 01310 { 01311 /* Check the state */ 01312 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01313 { 01314 /* Configure counters and size */ 01315 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; 01316 hospi->XferSize = hospi->XferCount; 01317 hospi->pBuffPtr = pData; 01318 01319 /* Configure CR register with functional mode as indirect write */ 01320 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 01321 01322 /* Clear flags related to interrupt */ 01323 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC); 01324 01325 /* Update the state */ 01326 hospi->State = HAL_OSPI_STATE_BUSY_TX; 01327 01328 /* Enable the transfer complete, fifo threshold and transfer error interrupts */ 01329 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE); 01330 } 01331 else 01332 { 01333 status = HAL_ERROR; 01334 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01335 } 01336 } 01337 01338 /* Return function status */ 01339 return status; 01340 } 01341 01342 /** 01343 * @brief Receive an amount of data in non-blocking mode with interrupt. 01344 * @param hospi : OSPI handle 01345 * @param pData : pointer to data buffer 01346 * @note This function is used only in Indirect Read Mode 01347 * @retval HAL status 01348 */ 01349 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData) 01350 { 01351 HAL_StatusTypeDef status = HAL_OK; 01352 uint32_t addr_reg = hospi->Instance->AR; 01353 uint32_t ir_reg = hospi->Instance->IR; 01354 01355 /* Check the data pointer allocation */ 01356 if (pData == NULL) 01357 { 01358 status = HAL_ERROR; 01359 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01360 } 01361 else 01362 { 01363 /* Check the state */ 01364 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01365 { 01366 /* Configure counters and size */ 01367 hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; 01368 hospi->XferSize = hospi->XferCount; 01369 hospi->pBuffPtr = pData; 01370 01371 /* Configure CR register with functional mode as indirect read */ 01372 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); 01373 01374 /* Clear flags related to interrupt */ 01375 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC); 01376 01377 /* Update the state */ 01378 hospi->State = HAL_OSPI_STATE_BUSY_RX; 01379 01380 /* Enable the transfer complete, fifo threshold and transfer error interrupts */ 01381 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE); 01382 01383 /* Trig the transfer by re-writing address or instruction register */ 01384 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 01385 { 01386 WRITE_REG(hospi->Instance->AR, addr_reg); 01387 } 01388 else 01389 { 01390 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) 01391 { 01392 WRITE_REG(hospi->Instance->AR, addr_reg); 01393 } 01394 else 01395 { 01396 WRITE_REG(hospi->Instance->IR, ir_reg); 01397 } 01398 } 01399 } 01400 else 01401 { 01402 status = HAL_ERROR; 01403 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01404 } 01405 } 01406 01407 /* Return function status */ 01408 return status; 01409 } 01410 01411 /** 01412 * @brief Send an amount of data in non-blocking mode with DMA. 01413 * @param hospi : OSPI handle 01414 * @param pData : pointer to data buffer 01415 * @note This function is used only in Indirect Write Mode 01416 * @note If DMA peripheral access is configured as halfword, the number 01417 * of data and the fifo threshold should be aligned on halfword 01418 * @note If DMA peripheral access is configured as word, the number 01419 * of data and the fifo threshold should be aligned on word 01420 * @retval HAL status 01421 */ 01422 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData) 01423 { 01424 HAL_StatusTypeDef status = HAL_OK; 01425 uint32_t data_size = hospi->Instance->DLR + 1U; 01426 01427 /* Check the data pointer allocation */ 01428 if (pData == NULL) 01429 { 01430 status = HAL_ERROR; 01431 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01432 } 01433 else 01434 { 01435 /* Check the state */ 01436 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01437 { 01438 hospi->XferCount = data_size; 01439 01440 { 01441 hospi->XferSize = hospi->XferCount; 01442 hospi->pBuffPtr = pData; 01443 01444 /* Configure CR register with functional mode as indirect write */ 01445 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); 01446 01447 /* Clear flags related to interrupt */ 01448 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC); 01449 01450 /* Update the state */ 01451 hospi->State = HAL_OSPI_STATE_BUSY_TX; 01452 01453 /* Set the MDMA transfer complete callback */ 01454 hospi->hmdma->XferCpltCallback = OSPI_DMACplt; 01455 01456 /* Set the MDMA error callback */ 01457 hospi->hmdma->XferErrorCallback = OSPI_DMAError; 01458 01459 /* Clear the MDMA abort callback */ 01460 hospi->hmdma->XferAbortCallback = NULL; 01461 01462 /* In Transmit mode , the MDMA destination is the OSPI DR register : Force the MDMA Destination Increment to disable */ 01463 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) ,MDMA_DEST_INC_DISABLE); 01464 01465 /* Update MDMA configuration with the correct SourceInc field for Write operation */ 01466 if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_BYTE) 01467 { 01468 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_BYTE); 01469 } 01470 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_HALFWORD) 01471 { 01472 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_HALFWORD); 01473 } 01474 else if (hospi->hmdma->Init.SourceDataSize == MDMA_SRC_DATASIZE_WORD) 01475 { 01476 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_WORD); 01477 } 01478 else 01479 { 01480 /* in case of incorrect source data size */ 01481 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA; 01482 status = HAL_ERROR; 01483 } 01484 01485 /* Enable the transmit MDMA Channel */ 01486 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize,1) == HAL_OK) 01487 { 01488 /* Enable the transfer error interrupt */ 01489 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE); 01490 01491 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/ 01492 } 01493 else 01494 { 01495 status = HAL_ERROR; 01496 hospi->ErrorCode = HAL_OSPI_ERROR_DMA; 01497 hospi->State = HAL_OSPI_STATE_READY; 01498 } 01499 } 01500 } 01501 else 01502 { 01503 status = HAL_ERROR; 01504 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01505 } 01506 } 01507 01508 /* Return function status */ 01509 return status; 01510 } 01511 01512 /** 01513 * @brief Receive an amount of data in non-blocking mode with DMA. 01514 * @param hospi : OSPI handle 01515 * @param pData : pointer to data buffer. 01516 * @note This function is used only in Indirect Read Mode 01517 * @note If DMA peripheral access is configured as halfword, the number 01518 * of data and the fifo threshold should be aligned on halfword 01519 * @note If DMA peripheral access is configured as word, the number 01520 * of data and the fifo threshold should be aligned on word 01521 * @retval HAL status 01522 */ 01523 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData) 01524 { 01525 HAL_StatusTypeDef status = HAL_OK; 01526 uint32_t data_size = hospi->Instance->DLR + 1U; 01527 uint32_t addr_reg = hospi->Instance->AR; 01528 uint32_t ir_reg = hospi->Instance->IR; 01529 /* Check the data pointer allocation */ 01530 if (pData == NULL) 01531 { 01532 status = HAL_ERROR; 01533 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 01534 } 01535 else 01536 { 01537 /* Check the state */ 01538 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01539 { 01540 hospi->XferCount = data_size; 01541 01542 { 01543 hospi->XferSize = hospi->XferCount; 01544 hospi->pBuffPtr = pData; 01545 01546 /* Configure CR register with functional mode as indirect read */ 01547 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); 01548 01549 /* Clear flags related to interrupt */ 01550 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC); 01551 01552 /* Update the state */ 01553 hospi->State = HAL_OSPI_STATE_BUSY_RX; 01554 01555 /* Set the DMA transfer complete callback */ 01556 hospi->hmdma->XferCpltCallback = OSPI_DMACplt; 01557 01558 /* Set the DMA error callback */ 01559 hospi->hmdma->XferErrorCallback = OSPI_DMAError; 01560 01561 /* Clear the DMA abort callback */ 01562 hospi->hmdma->XferAbortCallback = NULL; 01563 01564 /* In Receive mode , the MDMA source is the OSPI DR register : Force the MDMA Source Increment to disable */ 01565 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_SINC | MDMA_CTCR_SINCOS) , MDMA_SRC_INC_DISABLE); 01566 01567 /* Update MDMA configuration with the correct DestinationInc field for read operation */ 01568 if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_BYTE) 01569 { 01570 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_BYTE); 01571 } 01572 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_HALFWORD) 01573 { 01574 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_HALFWORD); 01575 } 01576 else if (hospi->hmdma->Init.DestDataSize == MDMA_DEST_DATASIZE_WORD) 01577 { 01578 MODIFY_REG(hospi->hmdma->Instance->CTCR, (MDMA_CTCR_DINC | MDMA_CTCR_DINCOS) , MDMA_DEST_INC_WORD); 01579 } 01580 else 01581 { 01582 /* in case of incorrect destination data size */ 01583 hospi->ErrorCode |= HAL_OSPI_ERROR_DMA; 01584 status = HAL_ERROR; 01585 } 01586 01587 /* Enable the transmit MDMA Channel */ 01588 if (HAL_MDMA_Start_IT(hospi->hmdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize, 1) == HAL_OK) 01589 { 01590 /* Enable the transfer error interrupt */ 01591 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE); 01592 01593 /* Trig the transfer by re-writing address or instruction register */ 01594 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 01595 { 01596 WRITE_REG(hospi->Instance->AR, addr_reg); 01597 } 01598 else 01599 { 01600 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) 01601 { 01602 WRITE_REG(hospi->Instance->AR, addr_reg); 01603 } 01604 else 01605 { 01606 WRITE_REG(hospi->Instance->IR, ir_reg); 01607 } 01608 } 01609 01610 /* Enable the MDMA transfer by setting the DMAEN bit not needed for MDMA*/ 01611 } 01612 else 01613 { 01614 status = HAL_ERROR; 01615 hospi->ErrorCode = HAL_OSPI_ERROR_DMA; 01616 hospi->State = HAL_OSPI_STATE_READY; 01617 } 01618 } 01619 } 01620 else 01621 { 01622 status = HAL_ERROR; 01623 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01624 } 01625 } 01626 01627 /* Return function status */ 01628 return status; 01629 } 01630 01631 /** 01632 * @brief Configure the OSPI Automatic Polling Mode in blocking mode. 01633 * @param hospi : OSPI handle 01634 * @param cfg : structure that contains the polling configuration information. 01635 * @param Timeout : Timeout duration 01636 * @note This function is used only in Automatic Polling Mode 01637 * @retval HAL status 01638 */ 01639 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout) 01640 { 01641 HAL_StatusTypeDef status; 01642 uint32_t tickstart = HAL_GetTick(); 01643 uint32_t addr_reg = hospi->Instance->AR; 01644 uint32_t ir_reg = hospi->Instance->IR; 01645 #ifdef USE_FULL_ASSERT 01646 uint32_t dlr_reg = hospi->Instance->DLR; 01647 #endif /* USE_FULL_ASSERT */ 01648 01649 /* Check the parameters of the autopolling configuration structure */ 01650 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode)); 01651 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop)); 01652 assert_param(IS_OSPI_INTERVAL (cfg->Interval)); 01653 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U)); 01654 01655 /* Check the state */ 01656 if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE)) 01657 { 01658 /* Wait till busy flag is reset */ 01659 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); 01660 01661 if (status == HAL_OK) 01662 { 01663 /* Configure registers */ 01664 WRITE_REG (hospi->Instance->PSMAR, cfg->Match); 01665 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); 01666 WRITE_REG (hospi->Instance->PIR, cfg->Interval); 01667 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), 01668 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING)); 01669 01670 /* Trig the transfer by re-writing address or instruction register */ 01671 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 01672 { 01673 WRITE_REG(hospi->Instance->AR, addr_reg); 01674 } 01675 else 01676 { 01677 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) 01678 { 01679 WRITE_REG(hospi->Instance->AR, addr_reg); 01680 } 01681 else 01682 { 01683 WRITE_REG(hospi->Instance->IR, ir_reg); 01684 } 01685 } 01686 01687 /* Wait till status match flag is set to go back in idle state */ 01688 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout); 01689 01690 if (status == HAL_OK) 01691 { 01692 /* Clear status match flag */ 01693 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM); 01694 01695 /* Update state */ 01696 hospi->State = HAL_OSPI_STATE_READY; 01697 } 01698 } 01699 } 01700 else 01701 { 01702 status = HAL_ERROR; 01703 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01704 } 01705 01706 /* Return function status */ 01707 return status; 01708 } 01709 01710 /** 01711 * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode. 01712 * @param hospi : OSPI handle 01713 * @param cfg : structure that contains the polling configuration information. 01714 * @note This function is used only in Automatic Polling Mode 01715 * @retval HAL status 01716 */ 01717 HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg) 01718 { 01719 HAL_StatusTypeDef status; 01720 uint32_t tickstart = HAL_GetTick(); 01721 uint32_t addr_reg = hospi->Instance->AR; 01722 uint32_t ir_reg = hospi->Instance->IR; 01723 #ifdef USE_FULL_ASSERT 01724 uint32_t dlr_reg = hospi->Instance->DLR; 01725 #endif /* USE_FULL_ASSERT */ 01726 01727 /* Check the parameters of the autopolling configuration structure */ 01728 assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode)); 01729 assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop)); 01730 assert_param(IS_OSPI_INTERVAL (cfg->Interval)); 01731 assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U)); 01732 01733 /* Check the state */ 01734 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01735 { 01736 /* Wait till busy flag is reset */ 01737 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); 01738 01739 if (status == HAL_OK) 01740 { 01741 /* Configure registers */ 01742 WRITE_REG (hospi->Instance->PSMAR, cfg->Match); 01743 WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); 01744 WRITE_REG (hospi->Instance->PIR, cfg->Interval); 01745 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), 01746 (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING)); 01747 01748 /* Clear flags related to interrupt */ 01749 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM); 01750 01751 /* Update state */ 01752 hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING; 01753 01754 /* Enable the status match and transfer error interrupts */ 01755 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE); 01756 01757 /* Trig the transfer by re-writing address or instruction register */ 01758 if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) 01759 { 01760 WRITE_REG(hospi->Instance->AR, addr_reg); 01761 } 01762 else 01763 { 01764 if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) 01765 { 01766 WRITE_REG(hospi->Instance->AR, addr_reg); 01767 } 01768 else 01769 { 01770 WRITE_REG(hospi->Instance->IR, ir_reg); 01771 } 01772 } 01773 } 01774 } 01775 else 01776 { 01777 status = HAL_ERROR; 01778 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01779 } 01780 01781 /* Return function status */ 01782 return status; 01783 } 01784 01785 /** 01786 * @brief Configure the Memory Mapped mode. 01787 * @param hospi : OSPI handle 01788 * @param cfg : structure that contains the memory mapped configuration information. 01789 * @note This function is used only in Memory mapped Mode 01790 * @retval HAL status 01791 */ 01792 HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg) 01793 { 01794 HAL_StatusTypeDef status; 01795 uint32_t tickstart = HAL_GetTick(); 01796 01797 /* Check the parameters of the memory-mapped configuration structure */ 01798 assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation)); 01799 01800 /* Check the state */ 01801 if (hospi->State == HAL_OSPI_STATE_CMD_CFG) 01802 { 01803 /* Wait till busy flag is reset */ 01804 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); 01805 01806 if (status == HAL_OK) 01807 { 01808 /* Update state */ 01809 hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; 01810 01811 if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) 01812 { 01813 assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod)); 01814 01815 /* Configure register */ 01816 WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod); 01817 01818 /* Clear flags related to interrupt */ 01819 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO); 01820 01821 /* Enable the timeout interrupt */ 01822 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO); 01823 } 01824 01825 /* Configure CR register with functional mode as memory-mapped */ 01826 MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE), 01827 (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)); 01828 } 01829 } 01830 else 01831 { 01832 status = HAL_ERROR; 01833 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 01834 } 01835 01836 /* Return function status */ 01837 return status; 01838 } 01839 01840 /** 01841 * @brief Transfer Error callback. 01842 * @param hospi : OSPI handle 01843 * @retval None 01844 */ 01845 __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi) 01846 { 01847 /* Prevent unused argument(s) compilation warning */ 01848 UNUSED(hospi); 01849 01850 /* NOTE : This function should not be modified, when the callback is needed, 01851 the HAL_OSPI_ErrorCallback could be implemented in the user file 01852 */ 01853 } 01854 01855 /** 01856 * @brief Abort completed callback. 01857 * @param hospi : OSPI handle 01858 * @retval None 01859 */ 01860 __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi) 01861 { 01862 /* Prevent unused argument(s) compilation warning */ 01863 UNUSED(hospi); 01864 01865 /* NOTE: This function should not be modified, when the callback is needed, 01866 the HAL_OSPI_AbortCpltCallback could be implemented in the user file 01867 */ 01868 } 01869 01870 /** 01871 * @brief FIFO Threshold callback. 01872 * @param hospi : OSPI handle 01873 * @retval None 01874 */ 01875 __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi) 01876 { 01877 /* Prevent unused argument(s) compilation warning */ 01878 UNUSED(hospi); 01879 01880 /* NOTE : This function should not be modified, when the callback is needed, 01881 the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file 01882 */ 01883 } 01884 01885 /** 01886 * @brief Command completed callback. 01887 * @param hospi : OSPI handle 01888 * @retval None 01889 */ 01890 __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi) 01891 { 01892 /* Prevent unused argument(s) compilation warning */ 01893 UNUSED(hospi); 01894 01895 /* NOTE: This function should not be modified, when the callback is needed, 01896 the HAL_OSPI_CmdCpltCallback could be implemented in the user file 01897 */ 01898 } 01899 01900 /** 01901 * @brief Rx Transfer completed callback. 01902 * @param hospi : OSPI handle 01903 * @retval None 01904 */ 01905 __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi) 01906 { 01907 /* Prevent unused argument(s) compilation warning */ 01908 UNUSED(hospi); 01909 01910 /* NOTE: This function should not be modified, when the callback is needed, 01911 the HAL_OSPI_RxCpltCallback could be implemented in the user file 01912 */ 01913 } 01914 01915 /** 01916 * @brief Tx Transfer completed callback. 01917 * @param hospi : OSPI handle 01918 * @retval None 01919 */ 01920 __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi) 01921 { 01922 /* Prevent unused argument(s) compilation warning */ 01923 UNUSED(hospi); 01924 01925 /* NOTE: This function should not be modified, when the callback is needed, 01926 the HAL_OSPI_TxCpltCallback could be implemented in the user file 01927 */ 01928 } 01929 01930 /** 01931 * @brief Rx Half Transfer completed callback. 01932 * @param hospi : OSPI handle 01933 * @retval None 01934 */ 01935 __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi) 01936 { 01937 /* Prevent unused argument(s) compilation warning */ 01938 UNUSED(hospi); 01939 01940 /* NOTE: This function should not be modified, when the callback is needed, 01941 the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file 01942 */ 01943 } 01944 01945 /** 01946 * @brief Tx Half Transfer completed callback. 01947 * @param hospi : OSPI handle 01948 * @retval None 01949 */ 01950 __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi) 01951 { 01952 /* Prevent unused argument(s) compilation warning */ 01953 UNUSED(hospi); 01954 01955 /* NOTE: This function should not be modified, when the callback is needed, 01956 the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file 01957 */ 01958 } 01959 01960 /** 01961 * @brief Status Match callback. 01962 * @param hospi : OSPI handle 01963 * @retval None 01964 */ 01965 __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi) 01966 { 01967 /* Prevent unused argument(s) compilation warning */ 01968 UNUSED(hospi); 01969 01970 /* NOTE : This function should not be modified, when the callback is needed, 01971 the HAL_OSPI_StatusMatchCallback could be implemented in the user file 01972 */ 01973 } 01974 01975 /** 01976 * @brief Timeout callback. 01977 * @param hospi : OSPI handle 01978 * @retval None 01979 */ 01980 __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi) 01981 { 01982 /* Prevent unused argument(s) compilation warning */ 01983 UNUSED(hospi); 01984 01985 /* NOTE : This function should not be modified, when the callback is needed, 01986 the HAL_OSPI_TimeOutCallback could be implemented in the user file 01987 */ 01988 } 01989 01990 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 01991 /** 01992 * @brief Register a User OSPI Callback 01993 * To be used instead of the weak (surcharged) predefined callback 01994 * @param hospi : OSPI handle 01995 * @param CallbackID : ID of the callback to be registered 01996 * This parameter can be one of the following values: 01997 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID 01998 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID 01999 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID 02000 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID 02001 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID 02002 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID 02003 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID 02004 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID 02005 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID 02006 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID 02007 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID 02008 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID 02009 * @param pCallback : pointer to the Callback function 02010 * @retval status 02011 */ 02012 HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID, 02013 pOSPI_CallbackTypeDef pCallback) 02014 { 02015 HAL_StatusTypeDef status = HAL_OK; 02016 02017 if(pCallback == NULL) 02018 { 02019 /* Update the error code */ 02020 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02021 return HAL_ERROR; 02022 } 02023 02024 if(hospi->State == HAL_OSPI_STATE_READY) 02025 { 02026 switch (CallbackID) 02027 { 02028 case HAL_OSPI_ERROR_CB_ID : 02029 hospi->ErrorCallback = pCallback; 02030 break; 02031 case HAL_OSPI_ABORT_CB_ID : 02032 hospi->AbortCpltCallback = pCallback; 02033 break; 02034 case HAL_OSPI_FIFO_THRESHOLD_CB_ID : 02035 hospi->FifoThresholdCallback = pCallback; 02036 break; 02037 case HAL_OSPI_CMD_CPLT_CB_ID : 02038 hospi->CmdCpltCallback = pCallback; 02039 break; 02040 case HAL_OSPI_RX_CPLT_CB_ID : 02041 hospi->RxCpltCallback = pCallback; 02042 break; 02043 case HAL_OSPI_TX_CPLT_CB_ID : 02044 hospi->TxCpltCallback = pCallback; 02045 break; 02046 case HAL_OSPI_RX_HALF_CPLT_CB_ID : 02047 hospi->RxHalfCpltCallback = pCallback; 02048 break; 02049 case HAL_OSPI_TX_HALF_CPLT_CB_ID : 02050 hospi->TxHalfCpltCallback = pCallback; 02051 break; 02052 case HAL_OSPI_STATUS_MATCH_CB_ID : 02053 hospi->StatusMatchCallback = pCallback; 02054 break; 02055 case HAL_OSPI_TIMEOUT_CB_ID : 02056 hospi->TimeOutCallback = pCallback; 02057 break; 02058 case HAL_OSPI_MSP_INIT_CB_ID : 02059 hospi->MspInitCallback = pCallback; 02060 break; 02061 case HAL_OSPI_MSP_DEINIT_CB_ID : 02062 hospi->MspDeInitCallback = pCallback; 02063 break; 02064 default : 02065 /* Update the error code */ 02066 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02067 /* update return status */ 02068 status = HAL_ERROR; 02069 break; 02070 } 02071 } 02072 else if (hospi->State == HAL_OSPI_STATE_RESET) 02073 { 02074 switch (CallbackID) 02075 { 02076 case HAL_OSPI_MSP_INIT_CB_ID : 02077 hospi->MspInitCallback = pCallback; 02078 break; 02079 case HAL_OSPI_MSP_DEINIT_CB_ID : 02080 hospi->MspDeInitCallback = pCallback; 02081 break; 02082 default : 02083 /* Update the error code */ 02084 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02085 /* update return status */ 02086 status = HAL_ERROR; 02087 break; 02088 } 02089 } 02090 else 02091 { 02092 /* Update the error code */ 02093 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02094 /* update return status */ 02095 status = HAL_ERROR; 02096 } 02097 02098 return status; 02099 } 02100 02101 /** 02102 * @brief Unregister a User OSPI Callback 02103 * OSPI Callback is redirected to the weak (surcharged) predefined callback 02104 * @param hospi : OSPI handle 02105 * @param CallbackID : ID of the callback to be unregistered 02106 * This parameter can be one of the following values: 02107 * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID 02108 * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID 02109 * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID 02110 * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID 02111 * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID 02112 * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID 02113 * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID 02114 * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID 02115 * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID 02116 * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID 02117 * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID 02118 * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID 02119 * @retval status 02120 */ 02121 HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback (OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID) 02122 { 02123 HAL_StatusTypeDef status = HAL_OK; 02124 02125 if(hospi->State == HAL_OSPI_STATE_READY) 02126 { 02127 switch (CallbackID) 02128 { 02129 case HAL_OSPI_ERROR_CB_ID : 02130 hospi->ErrorCallback = HAL_OSPI_ErrorCallback; 02131 break; 02132 case HAL_OSPI_ABORT_CB_ID : 02133 hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback; 02134 break; 02135 case HAL_OSPI_FIFO_THRESHOLD_CB_ID : 02136 hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback; 02137 break; 02138 case HAL_OSPI_CMD_CPLT_CB_ID : 02139 hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback; 02140 break; 02141 case HAL_OSPI_RX_CPLT_CB_ID : 02142 hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback; 02143 break; 02144 case HAL_OSPI_TX_CPLT_CB_ID : 02145 hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback; 02146 break; 02147 case HAL_OSPI_RX_HALF_CPLT_CB_ID : 02148 hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback; 02149 break; 02150 case HAL_OSPI_TX_HALF_CPLT_CB_ID : 02151 hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback; 02152 break; 02153 case HAL_OSPI_STATUS_MATCH_CB_ID : 02154 hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback; 02155 break; 02156 case HAL_OSPI_TIMEOUT_CB_ID : 02157 hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback; 02158 break; 02159 case HAL_OSPI_MSP_INIT_CB_ID : 02160 hospi->MspInitCallback = HAL_OSPI_MspInit; 02161 break; 02162 case HAL_OSPI_MSP_DEINIT_CB_ID : 02163 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit; 02164 break; 02165 default : 02166 /* Update the error code */ 02167 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02168 /* update return status */ 02169 status = HAL_ERROR; 02170 break; 02171 } 02172 } 02173 else if (hospi->State == HAL_OSPI_STATE_RESET) 02174 { 02175 switch (CallbackID) 02176 { 02177 case HAL_OSPI_MSP_INIT_CB_ID : 02178 hospi->MspInitCallback = HAL_OSPI_MspInit; 02179 break; 02180 case HAL_OSPI_MSP_DEINIT_CB_ID : 02181 hospi->MspDeInitCallback = HAL_OSPI_MspDeInit; 02182 break; 02183 default : 02184 /* Update the error code */ 02185 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02186 /* update return status */ 02187 status = HAL_ERROR; 02188 break; 02189 } 02190 } 02191 else 02192 { 02193 /* Update the error code */ 02194 hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK; 02195 /* update return status */ 02196 status = HAL_ERROR; 02197 } 02198 02199 return status; 02200 } 02201 #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 02202 02203 /** 02204 * @} 02205 */ 02206 02207 /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions 02208 * @brief OSPI control and State functions 02209 * 02210 @verbatim 02211 =============================================================================== 02212 ##### Peripheral Control and State functions ##### 02213 =============================================================================== 02214 [..] 02215 This subsection provides a set of functions allowing to : 02216 (+) Check in run-time the state of the driver. 02217 (+) Check the error code set during last operation. 02218 (+) Abort any operation. 02219 (+) Manage the Fifo threshold. 02220 (+) Configure the timeout duration used in the driver. 02221 02222 @endverbatim 02223 * @{ 02224 */ 02225 02226 /** 02227 * @brief Abort the current transmission. 02228 * @param hospi : OSPI handle 02229 * @retval HAL status 02230 */ 02231 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi) 02232 { 02233 HAL_StatusTypeDef status = HAL_OK; 02234 uint32_t state; 02235 uint32_t tickstart = HAL_GetTick(); 02236 02237 /* Check if the state is in one of the busy or configured states */ 02238 state = hospi->State; 02239 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U)) 02240 { 02241 /* Check if the DMA is enabled */ 02242 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U) 02243 { 02244 /* Disable the DMA transfer on the OctoSPI side */ 02245 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN); 02246 02247 /* Disable the DMA transfer on the DMA side */ 02248 status = HAL_MDMA_Abort(hospi->hmdma); 02249 if (status != HAL_OK) 02250 { 02251 hospi->ErrorCode = HAL_OSPI_ERROR_DMA; 02252 } 02253 } 02254 02255 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET) 02256 { 02257 /* Perform an abort of the OctoSPI */ 02258 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT); 02259 02260 /* Wait until the transfer complete flag is set to go back in idle state */ 02261 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout); 02262 02263 if (status == HAL_OK) 02264 { 02265 /* Clear transfer complete flag */ 02266 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 02267 02268 /* Wait until the busy flag is reset to go back in idle state */ 02269 status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); 02270 02271 if (status == HAL_OK) 02272 { 02273 /* Update state */ 02274 hospi->State = HAL_OSPI_STATE_READY; 02275 } 02276 } 02277 } 02278 else 02279 { 02280 /* Update state */ 02281 hospi->State = HAL_OSPI_STATE_READY; 02282 } 02283 } 02284 else 02285 { 02286 status = HAL_ERROR; 02287 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 02288 } 02289 02290 /* Return function status */ 02291 return status; 02292 } 02293 02294 /** 02295 * @brief Abort the current transmission (non-blocking function) 02296 * @param hospi : OSPI handle 02297 * @retval HAL status 02298 */ 02299 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi) 02300 { 02301 HAL_StatusTypeDef status = HAL_OK; 02302 uint32_t state; 02303 02304 /* Check if the state is in one of the busy or configured states */ 02305 state = hospi->State; 02306 if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U)) 02307 { 02308 /* Disable all interrupts */ 02309 __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)); 02310 02311 /* Update state */ 02312 hospi->State = HAL_OSPI_STATE_ABORT; 02313 02314 /* Check if the DMA is enabled */ 02315 if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U) 02316 { 02317 /* Disable the DMA transfer on the OctoSPI side */ 02318 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN); 02319 02320 /* Disable the DMA transfer on the DMA side */ 02321 hospi->hmdma->XferAbortCallback = OSPI_DMAAbortCplt; 02322 if (HAL_MDMA_Abort_IT(hospi->hmdma) != HAL_OK) 02323 { 02324 /* Update state */ 02325 hospi->State = HAL_OSPI_STATE_READY; 02326 02327 /* Abort callback */ 02328 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 02329 hospi->AbortCpltCallback(hospi); 02330 #else 02331 HAL_OSPI_AbortCpltCallback(hospi); 02332 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/ 02333 } 02334 } 02335 else 02336 { 02337 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET) 02338 { 02339 /* Clear transfer complete flag */ 02340 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 02341 02342 /* Enable the transfer complete interrupts */ 02343 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC); 02344 02345 /* Perform an abort of the OctoSPI */ 02346 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT); 02347 } 02348 else 02349 { 02350 /* Update state */ 02351 hospi->State = HAL_OSPI_STATE_READY; 02352 02353 /* Abort callback */ 02354 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 02355 hospi->AbortCpltCallback(hospi); 02356 #else 02357 HAL_OSPI_AbortCpltCallback(hospi); 02358 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 02359 } 02360 } 02361 } 02362 else 02363 { 02364 status = HAL_ERROR; 02365 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 02366 } 02367 02368 /* Return function status */ 02369 return status; 02370 } 02371 02372 /** @brief Set OSPI Fifo threshold. 02373 * @param hospi : OSPI handle. 02374 * @param Threshold : Threshold of the Fifo. 02375 * @retval HAL status 02376 */ 02377 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold) 02378 { 02379 HAL_StatusTypeDef status = HAL_OK; 02380 02381 /* Check the state */ 02382 if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U) 02383 { 02384 /* Synchronize initialization structure with the new fifo threshold value */ 02385 hospi->Init.FifoThreshold = Threshold; 02386 02387 /* Configure new fifo threshold */ 02388 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos)); 02389 02390 } 02391 else 02392 { 02393 status = HAL_ERROR; 02394 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; 02395 } 02396 02397 /* Return function status */ 02398 return status; 02399 } 02400 02401 /** @brief Get OSPI Fifo threshold. 02402 * @param hospi : OSPI handle. 02403 * @retval Fifo threshold 02404 */ 02405 uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef *hospi) 02406 { 02407 return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U); 02408 } 02409 02410 /** @brief Set OSPI timeout. 02411 * @param hospi : OSPI handle. 02412 * @param Timeout : Timeout for the memory access. 02413 * @retval None 02414 */ 02415 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout) 02416 { 02417 hospi->Timeout = Timeout; 02418 return HAL_OK; 02419 } 02420 02421 /** 02422 * @brief Return the OSPI error code. 02423 * @param hospi : OSPI handle 02424 * @retval OSPI Error Code 02425 */ 02426 uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef *hospi) 02427 { 02428 return hospi->ErrorCode; 02429 } 02430 02431 /** 02432 * @brief Return the OSPI handle state. 02433 * @param hospi : OSPI handle 02434 * @retval HAL state 02435 */ 02436 uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef *hospi) 02437 { 02438 /* Return OSPI handle state */ 02439 return hospi->State; 02440 } 02441 02442 /** 02443 * @} 02444 */ 02445 02446 /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function 02447 * @brief OSPI IO Manager configuration function 02448 * 02449 @verbatim 02450 =============================================================================== 02451 ##### IO Manager configuration function ##### 02452 =============================================================================== 02453 [..] 02454 This subsection provides a set of functions allowing to : 02455 (+) Configure the IO manager. 02456 02457 @endverbatim 02458 * @{ 02459 */ 02460 02461 /** 02462 * @brief Configure the OctoSPI IO manager. 02463 * @param hospi : OSPI handle 02464 * @param cfg : Configuration of the IO Manager for the instance 02465 * @param Timeout : Timeout duration 02466 * @retval HAL status 02467 */ 02468 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout) 02469 { 02470 HAL_StatusTypeDef status = HAL_OK; 02471 uint32_t instance; 02472 uint8_t index; 02473 uint8_t ospi_enabled = 0U; 02474 uint8_t other_instance; 02475 OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE]; 02476 02477 /* Prevent unused argument(s) compilation warning */ 02478 UNUSED(Timeout); 02479 02480 /* Check the parameters of the OctoSPI IO Manager configuration structure */ 02481 assert_param(IS_OSPIM_PORT(cfg->ClkPort)); 02482 assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort)); 02483 assert_param(IS_OSPIM_PORT(cfg->NCSPort)); 02484 assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort)); 02485 assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort)); 02486 assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime)); 02487 02488 if (hospi->Instance == OCTOSPI1) 02489 { 02490 instance = 0U; 02491 other_instance = 1U; 02492 } 02493 else 02494 { 02495 instance = 1U; 02496 other_instance = 0U; 02497 } 02498 02499 /**************** Get current configuration of the instances ****************/ 02500 for (index = 0U; index < OSPI_NB_INSTANCE; index++) 02501 { 02502 if (OSPIM_GetConfig(index+1U, &(IOM_cfg[index])) != HAL_OK) 02503 { 02504 status = HAL_ERROR; 02505 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 02506 } 02507 } 02508 02509 if (status == HAL_OK) 02510 { 02511 /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/ 02512 if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U) 02513 { 02514 CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); 02515 ospi_enabled |= 0x1U; 02516 } 02517 if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U) 02518 { 02519 CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); 02520 ospi_enabled |= 0x2U; 02521 } 02522 02523 /***************** Deactivation of previous configuration *****************/ 02524 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); 02525 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U) 02526 { 02527 /* De-multiplexing should be performed */ 02528 CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN); 02529 02530 if (other_instance == 1U) 02531 { 02532 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKSRC); 02533 if (IOM_cfg[other_instance].DQSPort != 0U) 02534 { 02535 SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSSRC); 02536 } 02537 if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) 02538 { 02539 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLSRC_1); 02540 } 02541 if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) 02542 { 02543 SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHSRC_1); 02544 } 02545 } 02546 } 02547 else 02548 { 02549 if (IOM_cfg[instance].ClkPort != 0U) 02550 { 02551 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); 02552 if (IOM_cfg[instance].DQSPort != 0U) 02553 { 02554 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); 02555 } 02556 if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) 02557 { 02558 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN); 02559 } 02560 if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) 02561 { 02562 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN); 02563 } 02564 } 02565 } 02566 02567 /********************* Deactivation of other instance *********************/ 02568 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || 02569 (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) || 02570 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) 02571 { 02572 if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) && 02573 (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) && 02574 (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) && 02575 (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) 02576 { 02577 /* Multiplexing should be performed */ 02578 SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN); 02579 } 02580 else 02581 { 02582 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); 02583 if (IOM_cfg[other_instance].DQSPort != 0U) 02584 { 02585 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); 02586 } 02587 CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); 02588 if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) 02589 { 02590 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], 02591 OCTOSPIM_PCR_IOLEN); 02592 } 02593 if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) 02594 { 02595 CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], 02596 OCTOSPIM_PCR_IOHEN); 02597 } 02598 } 02599 } 02600 02601 /******************** Activation of new configuration *********************/ 02602 MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), 02603 (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); 02604 02605 if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos)) 02606 { 02607 MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos)); 02608 } 02609 02610 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U) 02611 { 02612 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN); 02613 if (cfg->DQSPort != 0U) 02614 { 02615 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN); 02616 } 02617 02618 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U) 02619 { 02620 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], 02621 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN); 02622 } 02623 else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE) 02624 { 02625 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], 02626 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN); 02627 } 02628 else 02629 { 02630 /* Nothing to do */ 02631 } 02632 02633 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U) 02634 { 02635 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], 02636 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0)); 02637 } 02638 else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE) 02639 { 02640 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], 02641 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0)); 02642 } 02643 else 02644 { 02645 /* Nothing to do */ 02646 } 02647 } 02648 else 02649 { 02650 MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), 02651 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); 02652 if (cfg->DQSPort != 0U) 02653 { 02654 MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), 02655 (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos))); 02656 } 02657 02658 if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U) 02659 { 02660 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], 02661 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), 02662 (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U)))); 02663 } 02664 else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE) 02665 { 02666 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], 02667 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), 02668 (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U)))); 02669 } 02670 else 02671 { 02672 /* Nothing to do */ 02673 } 02674 02675 if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U) 02676 { 02677 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], 02678 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), 02679 (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U)))); 02680 } 02681 else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE) 02682 { 02683 MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], 02684 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), 02685 (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U)))); 02686 } 02687 else 02688 { 02689 /* Nothing to do */ 02690 } 02691 } 02692 02693 /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/ 02694 if ((ospi_enabled & 0x1U) != 0U) 02695 { 02696 SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); 02697 } 02698 if ((ospi_enabled & 0x2U) != 0U) 02699 { 02700 SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); 02701 } 02702 } 02703 02704 /* Return function status */ 02705 return status; 02706 } 02707 02708 /** 02709 * @} 02710 */ 02711 02712 /** 02713 @cond 0 02714 */ 02715 /** 02716 * @brief DMA OSPI process complete callback. 02717 * @param hdma : DMA handle 02718 * @retval None 02719 */ 02720 static void OSPI_DMACplt(MDMA_HandleTypeDef *hmdma) 02721 { 02722 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent); 02723 hospi->XferCount = 0; 02724 02725 /* Disable the DMA transfer on the OctoSPI side */ 02726 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN); 02727 02728 /* Disable the DMA channel */ 02729 __HAL_MDMA_DISABLE(hmdma); 02730 02731 /* Enable the OSPI transfer complete Interrupt */ 02732 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC); 02733 } 02734 02735 /** 02736 * @brief DMA OSPI communication error callback. 02737 * @param hdma : DMA handle 02738 * @retval None 02739 */ 02740 static void OSPI_DMAError(MDMA_HandleTypeDef *hmdma) 02741 { 02742 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent); 02743 hospi->XferCount = 0; 02744 hospi->ErrorCode = HAL_OSPI_ERROR_DMA; 02745 02746 /* Disable the DMA transfer on the OctoSPI side */ 02747 CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN); 02748 02749 /* Abort the OctoSPI */ 02750 if (HAL_OSPI_Abort_IT(hospi) != HAL_OK) 02751 { 02752 /* Disable the interrupts */ 02753 __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE); 02754 02755 /* Update state */ 02756 hospi->State = HAL_OSPI_STATE_READY; 02757 02758 /* Error callback */ 02759 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 02760 hospi->ErrorCallback(hospi); 02761 #else 02762 HAL_OSPI_ErrorCallback(hospi); 02763 #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 02764 } 02765 } 02766 02767 /** 02768 * @brief DMA OSPI abort complete callback. 02769 * @param hdma : DMA handle 02770 * @retval None 02771 */ 02772 static void OSPI_DMAAbortCplt(MDMA_HandleTypeDef *hmdma) 02773 { 02774 OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hmdma->Parent); 02775 hospi->XferCount = 0; 02776 02777 /* Check the state */ 02778 if (hospi->State == HAL_OSPI_STATE_ABORT) 02779 { 02780 /* DMA abort called by OctoSPI abort */ 02781 if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET) 02782 { 02783 /* Clear transfer complete flag */ 02784 __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); 02785 02786 /* Enable the transfer complete interrupts */ 02787 __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC); 02788 02789 /* Perform an abort of the OctoSPI */ 02790 SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT); 02791 } 02792 else 02793 { 02794 /* Update state */ 02795 hospi->State = HAL_OSPI_STATE_READY; 02796 02797 /* Abort callback */ 02798 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 02799 hospi->AbortCpltCallback(hospi); 02800 #else 02801 HAL_OSPI_AbortCpltCallback(hospi); 02802 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */ 02803 } 02804 } 02805 else 02806 { 02807 /* DMA abort called due to a transfer error interrupt */ 02808 /* Update state */ 02809 hospi->State = HAL_OSPI_STATE_READY; 02810 02811 /* Error callback */ 02812 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) 02813 hospi->ErrorCallback(hospi); 02814 #else 02815 HAL_OSPI_ErrorCallback(hospi); 02816 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/ 02817 } 02818 } 02819 02820 /** 02821 * @brief Wait for a flag state until timeout. 02822 * @param hospi : OSPI handle 02823 * @param Flag : Flag checked 02824 * @param State : Value of the flag expected 02825 * @param Timeout : Duration of the timeout 02826 * @param Tickstart : Tick start value 02827 * @retval HAL status 02828 */ 02829 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, 02830 FlagStatus State, uint32_t Tickstart, uint32_t Timeout) 02831 { 02832 /* Wait until flag is in expected state */ 02833 while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State) 02834 { 02835 /* Check for the Timeout */ 02836 if (Timeout != HAL_MAX_DELAY) 02837 { 02838 if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 02839 { 02840 hospi->State = HAL_OSPI_STATE_ERROR; 02841 hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT; 02842 02843 return HAL_ERROR; 02844 } 02845 } 02846 } 02847 return HAL_OK; 02848 } 02849 02850 /** 02851 * @brief Configure the registers for the regular command mode. 02852 * @param hospi : OSPI handle 02853 * @param cmd : structure that contains the command configuration information 02854 * @retval HAL status 02855 */ 02856 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd) 02857 { 02858 HAL_StatusTypeDef status = HAL_OK; 02859 __IO uint32_t *ccr_reg; 02860 __IO uint32_t *tcr_reg; 02861 __IO uint32_t *ir_reg; 02862 __IO uint32_t *abr_reg; 02863 02864 /* Re-initialize the value of the functional mode */ 02865 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); 02866 02867 /* Configure the flash ID */ 02868 if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE) 02869 { 02870 MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId); 02871 } 02872 02873 if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) 02874 { 02875 ccr_reg = &(hospi->Instance->WCCR); 02876 tcr_reg = &(hospi->Instance->WTCR); 02877 ir_reg = &(hospi->Instance->WIR); 02878 abr_reg = &(hospi->Instance->WABR); 02879 } 02880 else if (cmd->OperationType == HAL_OSPI_OPTYPE_WRAP_CFG) 02881 { 02882 ccr_reg = &(hospi->Instance->WPCCR); 02883 tcr_reg = &(hospi->Instance->WPTCR); 02884 ir_reg = &(hospi->Instance->WPIR); 02885 abr_reg = &(hospi->Instance->WPABR); 02886 } 02887 else 02888 { 02889 ccr_reg = &(hospi->Instance->CCR); 02890 tcr_reg = &(hospi->Instance->TCR); 02891 ir_reg = &(hospi->Instance->IR); 02892 abr_reg = &(hospi->Instance->ABR); 02893 } 02894 02895 /* Configure the CCR register with DQS and SIOO modes */ 02896 *ccr_reg = (cmd->DQSMode | cmd->SIOOMode); 02897 02898 if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) 02899 { 02900 /* Configure the ABR register with alternate bytes value */ 02901 *abr_reg = cmd->AlternateBytes; 02902 02903 /* Configure the CCR register with alternate bytes communication parameters */ 02904 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE), 02905 (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize)); 02906 } 02907 02908 /* Configure the TCR register with the number of dummy cycles */ 02909 MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles); 02910 02911 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 02912 { 02913 if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) 02914 { 02915 /* Configure the DLR register with the number of data */ 02916 hospi->Instance->DLR = (cmd->NbData - 1U); 02917 } 02918 } 02919 02920 if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) 02921 { 02922 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) 02923 { 02924 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 02925 { 02926 /* ---- Command with instruction, address and data ---- */ 02927 02928 /* Configure the CCR register with all communication parameters */ 02929 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | 02930 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE | 02931 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR), 02932 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize | 02933 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | 02934 cmd->DataMode | cmd->DataDtrMode)); 02935 } 02936 else 02937 { 02938 /* ---- Command with instruction and address ---- */ 02939 02940 /* Configure the CCR register with all communication parameters */ 02941 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | 02942 OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), 02943 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize | 02944 cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize)); 02945 02946 /* The DHQC bit is linked with DDTR bit which should be activated */ 02947 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && 02948 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE)) 02949 { 02950 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); 02951 } 02952 } 02953 02954 /* Configure the IR register with the instruction value */ 02955 *ir_reg = cmd->Instruction; 02956 02957 /* Configure the AR register with the address value */ 02958 hospi->Instance->AR = cmd->Address; 02959 } 02960 else 02961 { 02962 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 02963 { 02964 /* ---- Command with instruction and data ---- */ 02965 02966 /* Configure the CCR register with all communication parameters */ 02967 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | 02968 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR), 02969 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize | 02970 cmd->DataMode | cmd->DataDtrMode)); 02971 } 02972 else 02973 { 02974 /* ---- Command with only instruction ---- */ 02975 02976 /* Configure the CCR register with all communication parameters */ 02977 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE), 02978 (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize)); 02979 02980 /* The DHQC bit is linked with DDTR bit which should be activated */ 02981 if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && 02982 (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE)) 02983 { 02984 MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); 02985 } 02986 } 02987 02988 /* Configure the IR register with the instruction value */ 02989 *ir_reg = cmd->Instruction; 02990 02991 } 02992 } 02993 else 02994 { 02995 if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) 02996 { 02997 if (cmd->DataMode != HAL_OSPI_DATA_NONE) 02998 { 02999 /* ---- Command with address and data ---- */ 03000 03001 /* Configure the CCR register with all communication parameters */ 03002 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE | 03003 OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR), 03004 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | 03005 cmd->DataMode | cmd->DataDtrMode)); 03006 } 03007 else 03008 { 03009 /* ---- Command with only address ---- */ 03010 03011 /* Configure the CCR register with all communication parameters */ 03012 MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), 03013 (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize)); 03014 } 03015 03016 /* Configure the AR register with the instruction value */ 03017 hospi->Instance->AR = cmd->Address; 03018 } 03019 else 03020 { 03021 /* ---- Invalid command configuration (no instruction, no address) ---- */ 03022 status = HAL_ERROR; 03023 hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; 03024 } 03025 } 03026 03027 /* Return function status */ 03028 return status; 03029 } 03030 03031 /** 03032 * @brief Get the current IOM configuration for an OctoSPI instance. 03033 * @param instance_nb : number of the instance 03034 * @param cfg : configuration of the IO Manager for the instance 03035 * @retval HAL status 03036 */ 03037 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg) 03038 { 03039 HAL_StatusTypeDef status = HAL_OK; 03040 uint32_t reg; 03041 uint32_t value = 0U; 03042 uint32_t index; 03043 03044 if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL)) 03045 { 03046 /* Invalid parameter -> error returned */ 03047 status = HAL_ERROR; 03048 } 03049 else 03050 { 03051 /* Initialize the structure */ 03052 cfg->ClkPort = 0U; 03053 cfg->DQSPort = 0U; 03054 cfg->NCSPort = 0U; 03055 cfg->IOLowPort = 0U; 03056 cfg->IOHighPort = 0U; 03057 03058 if (instance_nb == 2U) 03059 { 03060 if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U) 03061 { 03062 value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC 03063 | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1); 03064 } 03065 else 03066 { 03067 value = OCTOSPIM_PCR_NCSSRC; 03068 } 03069 } 03070 03071 /* Get the information about the instance */ 03072 for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) 03073 { 03074 reg = OCTOSPIM->PCR[index]; 03075 03076 if ((reg & OCTOSPIM_PCR_CLKEN) != 0U) 03077 { 03078 /* The clock is enabled on this port */ 03079 if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC)) 03080 { 03081 /* The clock correspond to the instance passed as parameter */ 03082 cfg->ClkPort = index+1U; 03083 } 03084 } 03085 03086 if ((reg & OCTOSPIM_PCR_DQSEN) != 0U) 03087 { 03088 /* The DQS is enabled on this port */ 03089 if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC)) 03090 { 03091 /* The DQS correspond to the instance passed as parameter */ 03092 cfg->DQSPort = index+1U; 03093 } 03094 } 03095 03096 if ((reg & OCTOSPIM_PCR_NCSEN) != 0U) 03097 { 03098 /* The nCS is enabled on this port */ 03099 if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC)) 03100 { 03101 /* The nCS correspond to the instance passed as parameter */ 03102 cfg->NCSPort = index+1U; 03103 } 03104 } 03105 03106 if ((reg & OCTOSPIM_PCR_IOLEN) != 0U) 03107 { 03108 /* The IO Low is enabled on this port */ 03109 if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1)) 03110 { 03111 /* The IO Low correspond to the instance passed as parameter */ 03112 if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U) 03113 { 03114 cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); 03115 } 03116 else 03117 { 03118 cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); 03119 } 03120 } 03121 } 03122 03123 if ((reg & OCTOSPIM_PCR_IOHEN) != 0U) 03124 { 03125 /* The IO High is enabled on this port */ 03126 if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1)) 03127 { 03128 /* The IO High correspond to the instance passed as parameter */ 03129 if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U) 03130 { 03131 cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); 03132 } 03133 else 03134 { 03135 cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); 03136 } 03137 } 03138 } 03139 } 03140 } 03141 03142 /* Return function status */ 03143 return status; 03144 } 03145 03146 /** 03147 @endcond 03148 */ 03149 03150 /** 03151 * @} 03152 */ 03153 03154 #endif /* HAL_OSPI_MODULE_ENABLED */ 03155 03156 /** 03157 * @} 03158 */ 03159 03160 /** 03161 * @} 03162 */ 03163 03164 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */