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