You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

3007 lines
103 KiB

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