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