| 1 | /**
|
|---|
| 2 | ******************************************************************************
|
|---|
| 3 | * @file stm32f4xx_hal_qspi.c
|
|---|
| 4 | * @author MCD Application Team
|
|---|
| 5 | * @brief QSPI HAL module driver.
|
|---|
| 6 | * This file provides firmware functions to manage the following
|
|---|
| 7 | * functionalities of the QuadSPI interface (QSPI).
|
|---|
| 8 | * + Initialization and de-initialization functions
|
|---|
| 9 | * + Indirect functional mode management
|
|---|
| 10 | * + Memory-mapped functional mode management
|
|---|
| 11 | * + Auto-polling functional mode management
|
|---|
| 12 | * + Interrupts and flags management
|
|---|
| 13 | * + DMA channel configuration for indirect functional mode
|
|---|
| 14 | * + Errors management and abort functionality
|
|---|
| 15 | *
|
|---|
| 16 | *
|
|---|
| 17 | @verbatim
|
|---|
| 18 | ===============================================================================
|
|---|
| 19 | ##### How to use this driver #####
|
|---|
| 20 | ===============================================================================
|
|---|
| 21 | [..]
|
|---|
| 22 | *** Initialization ***
|
|---|
| 23 | ======================
|
|---|
| 24 | [..]
|
|---|
| 25 | (#) As prerequisite, fill in the HAL_QSPI_MspInit() :
|
|---|
| 26 | (++) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE().
|
|---|
| 27 | (++) Reset QuadSPI Peripheral with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET().
|
|---|
| 28 | (++) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
|
|---|
| 29 | (++) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init().
|
|---|
| 30 | (++) If interrupt mode is used, enable and configure QuadSPI global
|
|---|
| 31 | interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
|
|---|
| 32 | (++) If DMA mode is used, enable the clocks for the QuadSPI DMA channel
|
|---|
| 33 | with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
|
|---|
| 34 | link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure
|
|---|
| 35 | DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
|
|---|
| 36 | (#) Configure the flash size, the clock prescaler, the fifo threshold, the
|
|---|
| 37 | clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function.
|
|---|
| 38 |
|
|---|
| 39 | *** Indirect functional mode ***
|
|---|
| 40 | ================================
|
|---|
| 41 | [..]
|
|---|
| 42 | (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT()
|
|---|
| 43 | functions :
|
|---|
| 44 | (++) Instruction phase : the mode used and if present the instruction opcode.
|
|---|
| 45 | (++) Address phase : the mode used and if present the size and the address value.
|
|---|
| 46 | (++) Alternate-bytes phase : the mode used and if present the size and the alternate
|
|---|
| 47 | bytes values.
|
|---|
| 48 | (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
|
|---|
| 49 | (++) Data phase : the mode used and if present the number of bytes.
|
|---|
| 50 | (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
|
|---|
| 51 | if activated.
|
|---|
| 52 | (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
|
|---|
| 53 | (#) If no data is required for the command, it is sent directly to the memory :
|
|---|
| 54 | (++) In polling mode, the output of the function is done when the transfer is complete.
|
|---|
| 55 | (++) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete.
|
|---|
| 56 | (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or
|
|---|
| 57 | HAL_QSPI_Transmit_IT() after the command configuration :
|
|---|
| 58 | (++) In polling mode, the output of the function is done when the transfer is complete.
|
|---|
| 59 | (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
|
|---|
| 60 | is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
|
|---|
| 61 | (++) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and
|
|---|
| 62 | HAL_QSPI_TxCpltCallback() will be called when the transfer is complete.
|
|---|
| 63 | (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or
|
|---|
| 64 | HAL_QSPI_Receive_IT() after the command configuration :
|
|---|
| 65 | (++) In polling mode, the output of the function is done when the transfer is complete.
|
|---|
| 66 | (++) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold
|
|---|
| 67 | is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
|
|---|
| 68 | (++) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and
|
|---|
| 69 | HAL_QSPI_RxCpltCallback() will be called when the transfer is complete.
|
|---|
| 70 |
|
|---|
| 71 | *** Auto-polling functional mode ***
|
|---|
| 72 | ====================================
|
|---|
| 73 | [..]
|
|---|
| 74 | (#) Configure the command sequence and the auto-polling functional mode using the
|
|---|
| 75 | HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions :
|
|---|
| 76 | (++) Instruction phase : the mode used and if present the instruction opcode.
|
|---|
| 77 | (++) Address phase : the mode used and if present the size and the address value.
|
|---|
| 78 | (++) Alternate-bytes phase : the mode used and if present the size and the alternate
|
|---|
| 79 | bytes values.
|
|---|
| 80 | (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
|
|---|
| 81 | (++) Data phase : the mode used.
|
|---|
| 82 | (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
|
|---|
| 83 | if activated.
|
|---|
| 84 | (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
|
|---|
| 85 | (++) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
|
|---|
| 86 | the polling interval and the automatic stop activation.
|
|---|
| 87 | (#) After the configuration :
|
|---|
| 88 | (++) In polling mode, the output of the function is done when the status match is reached. The
|
|---|
| 89 | automatic stop is activated to avoid an infinite loop.
|
|---|
| 90 | (++) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached.
|
|---|
| 91 |
|
|---|
| 92 | *** Memory-mapped functional mode ***
|
|---|
| 93 | =====================================
|
|---|
| 94 | [..]
|
|---|
| 95 | (#) Configure the command sequence and the memory-mapped functional mode using the
|
|---|
| 96 | HAL_QSPI_MemoryMapped() functions :
|
|---|
| 97 | (++) Instruction phase : the mode used and if present the instruction opcode.
|
|---|
| 98 | (++) Address phase : the mode used and the size.
|
|---|
| 99 | (++) Alternate-bytes phase : the mode used and if present the size and the alternate
|
|---|
| 100 | bytes values.
|
|---|
| 101 | (++) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
|
|---|
| 102 | (++) Data phase : the mode used.
|
|---|
| 103 | (++) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay
|
|---|
| 104 | if activated.
|
|---|
| 105 | (++) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
|
|---|
| 106 | (++) The timeout activation and the timeout period.
|
|---|
| 107 | (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on
|
|---|
| 108 | the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires.
|
|---|
| 109 |
|
|---|
| 110 | *** Errors management and abort functionality ***
|
|---|
| 111 | =================================================
|
|---|
| 112 | [..]
|
|---|
| 113 | (#) HAL_QSPI_GetError() function gives the error raised during the last operation.
|
|---|
| 114 | (#) HAL_QSPI_Abort() and HAL_QSPI_AbortIT() functions aborts any on-going operation and
|
|---|
| 115 | flushes the fifo :
|
|---|
| 116 | (++) In polling mode, the output of the function is done when the transfer
|
|---|
| 117 | complete bit is set and the busy bit cleared.
|
|---|
| 118 | (++) In interrupt mode, HAL_QSPI_AbortCpltCallback() will be called when
|
|---|
| 119 | the transfer complete bit is set.
|
|---|
| 120 |
|
|---|
| 121 | *** Control functions ***
|
|---|
| 122 | =========================
|
|---|
| 123 | [..]
|
|---|
| 124 | (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver.
|
|---|
| 125 | (#) HAL_QSPI_SetTimeout() function configures the timeout value used in the driver.
|
|---|
| 126 | (#) HAL_QSPI_SetFifoThreshold() function configures the threshold on the Fifo of the QSPI IP.
|
|---|
| 127 | (#) HAL_QSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
|
|---|
| 128 | (#) HAL_QSPI_SetFlashID() function configures the index of the flash memory to be accessed.
|
|---|
| 129 |
|
|---|
| 130 | *** Callback registration ***
|
|---|
| 131 | =============================================
|
|---|
| 132 | [..]
|
|---|
| 133 | The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS when set to 1
|
|---|
| 134 | allows the user to configure dynamically the driver callbacks.
|
|---|
| 135 |
|
|---|
| 136 | Use Functions @ref HAL_QSPI_RegisterCallback() to register a user callback,
|
|---|
| 137 | it allows to register following callbacks:
|
|---|
| 138 | (+) ErrorCallback : callback when error occurs.
|
|---|
| 139 | (+) AbortCpltCallback : callback when abort is completed.
|
|---|
| 140 | (+) FifoThresholdCallback : callback when the fifo threshold is reached.
|
|---|
| 141 | (+) CmdCpltCallback : callback when a command without data is completed.
|
|---|
| 142 | (+) RxCpltCallback : callback when a reception transfer is completed.
|
|---|
| 143 | (+) TxCpltCallback : callback when a transmission transfer is completed.
|
|---|
| 144 | (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
|
|---|
| 145 | (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
|
|---|
| 146 | (+) StatusMatchCallback : callback when a status match occurs.
|
|---|
| 147 | (+) TimeOutCallback : callback when the timeout perioed expires.
|
|---|
| 148 | (+) MspInitCallback : QSPI MspInit.
|
|---|
| 149 | (+) MspDeInitCallback : QSPI MspDeInit.
|
|---|
| 150 | This function takes as parameters the HAL peripheral handle, the Callback ID
|
|---|
| 151 | and a pointer to the user callback function.
|
|---|
| 152 |
|
|---|
| 153 | Use function @ref HAL_QSPI_UnRegisterCallback() to reset a callback to the default
|
|---|
| 154 | weak (surcharged) function. It allows to reset following callbacks:
|
|---|
| 155 | (+) ErrorCallback : callback when error occurs.
|
|---|
| 156 | (+) AbortCpltCallback : callback when abort is completed.
|
|---|
| 157 | (+) FifoThresholdCallback : callback when the fifo threshold is reached.
|
|---|
| 158 | (+) CmdCpltCallback : callback when a command without data is completed.
|
|---|
| 159 | (+) RxCpltCallback : callback when a reception transfer is completed.
|
|---|
| 160 | (+) TxCpltCallback : callback when a transmission transfer is completed.
|
|---|
| 161 | (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
|
|---|
| 162 | (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
|
|---|
| 163 | (+) StatusMatchCallback : callback when a status match occurs.
|
|---|
| 164 | (+) TimeOutCallback : callback when the timeout perioed expires.
|
|---|
| 165 | (+) MspInitCallback : QSPI MspInit.
|
|---|
| 166 | (+) MspDeInitCallback : QSPI MspDeInit.
|
|---|
| 167 | This function) takes as parameters the HAL peripheral handle and the Callback ID.
|
|---|
| 168 |
|
|---|
| 169 | By default, after the @ref HAL_QSPI_Init and if the state is HAL_QSPI_STATE_RESET
|
|---|
| 170 | all callbacks are reset to the corresponding legacy weak (surcharged) functions.
|
|---|
| 171 | Exception done for MspInit and MspDeInit callbacks that are respectively
|
|---|
| 172 | reset to the legacy weak (surcharged) functions in the @ref HAL_QSPI_Init
|
|---|
| 173 | and @ref HAL_QSPI_DeInit only when these callbacks are null (not registered beforehand).
|
|---|
| 174 | If not, MspInit or MspDeInit are not null, the @ref HAL_QSPI_Init and @ref HAL_QSPI_DeInit
|
|---|
| 175 | keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
|
|---|
| 176 |
|
|---|
| 177 | Callbacks can be registered/unregistered in READY state only.
|
|---|
| 178 | Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
|
|---|
| 179 | in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
|
|---|
| 180 | during the Init/DeInit.
|
|---|
| 181 | In that case first register the MspInit/MspDeInit user callbacks
|
|---|
| 182 | using @ref HAL_QSPI_RegisterCallback before calling @ref HAL_QSPI_DeInit
|
|---|
| 183 | or @ref HAL_QSPI_Init function.
|
|---|
| 184 |
|
|---|
| 185 | When The compilation define USE_HAL_QSPI_REGISTER_CALLBACKS is set to 0 or
|
|---|
| 186 | not defined, the callback registering feature is not available
|
|---|
| 187 | and weak (surcharged) callbacks are used.
|
|---|
| 188 |
|
|---|
| 189 | *** Workarounds linked to Silicon Limitation ***
|
|---|
| 190 | ====================================================
|
|---|
| 191 | [..]
|
|---|
| 192 | (#) Workarounds Implemented inside HAL Driver
|
|---|
| 193 | (++) Extra data written in the FIFO at the end of a read transfer
|
|---|
| 194 |
|
|---|
| 195 | @endverbatim
|
|---|
| 196 | ******************************************************************************
|
|---|
| 197 | * @attention
|
|---|
| 198 | *
|
|---|
| 199 | * <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
|---|
| 200 | * All rights reserved.</center></h2>
|
|---|
| 201 | *
|
|---|
| 202 | * This software component is licensed by ST under BSD 3-Clause license,
|
|---|
| 203 | * the "License"; You may not use this file except in compliance with the
|
|---|
| 204 | * License. You may obtain a copy of the License at:
|
|---|
| 205 | * opensource.org/licenses/BSD-3-Clause
|
|---|
| 206 | *
|
|---|
| 207 | ******************************************************************************
|
|---|
| 208 | */
|
|---|
| 209 |
|
|---|
| 210 | /* Includes ------------------------------------------------------------------*/
|
|---|
| 211 | #include "stm32f4xx_hal.h"
|
|---|
| 212 |
|
|---|
| 213 | #if defined(QUADSPI)
|
|---|
| 214 |
|
|---|
| 215 | /** @addtogroup STM32F4xx_HAL_Driver
|
|---|
| 216 | * @{
|
|---|
| 217 | */
|
|---|
| 218 |
|
|---|
| 219 | /** @defgroup QSPI QSPI
|
|---|
| 220 | * @brief QSPI HAL module driver
|
|---|
| 221 | * @{
|
|---|
| 222 | */
|
|---|
| 223 | #ifdef HAL_QSPI_MODULE_ENABLED
|
|---|
| 224 |
|
|---|
| 225 | /* Private typedef -----------------------------------------------------------*/
|
|---|
| 226 |
|
|---|
| 227 | /* Private define ------------------------------------------------------------*/
|
|---|
| 228 | /** @defgroup QSPI_Private_Constants QSPI Private Constants
|
|---|
| 229 | * @{
|
|---|
| 230 | */
|
|---|
| 231 | #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<Indirect write mode*/
|
|---|
| 232 | #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<Indirect read mode*/
|
|---|
| 233 | #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<Automatic polling mode*/
|
|---|
| 234 | #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<Memory-mapped mode*/
|
|---|
| 235 | /**
|
|---|
| 236 | * @}
|
|---|
| 237 | */
|
|---|
| 238 |
|
|---|
| 239 | /* Private macro -------------------------------------------------------------*/
|
|---|
| 240 | /** @defgroup QSPI_Private_Macros QSPI Private Macros
|
|---|
| 241 | * @{
|
|---|
| 242 | */
|
|---|
| 243 | #define IS_QSPI_FUNCTIONAL_MODE(MODE) (((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
|
|---|
| 244 | ((MODE) == QSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
|
|---|
| 245 | ((MODE) == QSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
|
|---|
| 246 | ((MODE) == QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
|
|---|
| 247 | /**
|
|---|
| 248 | * @}
|
|---|
| 249 | */
|
|---|
| 250 |
|
|---|
| 251 | /* Private variables ---------------------------------------------------------*/
|
|---|
| 252 |
|
|---|
| 253 | /* Private function prototypes -----------------------------------------------*/
|
|---|
| 254 | static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma);
|
|---|
| 255 | static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma);
|
|---|
| 256 | static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
|
|---|
| 257 | static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
|
|---|
| 258 | static void QSPI_DMAError(DMA_HandleTypeDef *hdma);
|
|---|
| 259 | static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
|
|---|
| 260 | static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
|
|---|
| 261 | static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode);
|
|---|
| 262 |
|
|---|
| 263 | /* Exported functions --------------------------------------------------------*/
|
|---|
| 264 |
|
|---|
| 265 | /** @defgroup QSPI_Exported_Functions QSPI Exported Functions
|
|---|
| 266 | * @{
|
|---|
| 267 | */
|
|---|
| 268 |
|
|---|
| 269 | /** @defgroup QSPI_Exported_Functions_Group1 Initialization/de-initialization functions
|
|---|
| 270 | * @brief Initialization and Configuration functions
|
|---|
| 271 | *
|
|---|
| 272 | @verbatim
|
|---|
| 273 | ===============================================================================
|
|---|
| 274 | ##### Initialization and Configuration functions #####
|
|---|
| 275 | ===============================================================================
|
|---|
| 276 | [..]
|
|---|
| 277 | This subsection provides a set of functions allowing to :
|
|---|
| 278 | (+) Initialize the QuadSPI.
|
|---|
| 279 | (+) De-initialize the QuadSPI.
|
|---|
| 280 |
|
|---|
| 281 | @endverbatim
|
|---|
| 282 | * @{
|
|---|
| 283 | */
|
|---|
| 284 |
|
|---|
| 285 | /**
|
|---|
| 286 | * @brief Initialize the QSPI mode according to the specified parameters
|
|---|
| 287 | * in the QSPI_InitTypeDef and initialize the associated handle.
|
|---|
| 288 | * @param hqspi : QSPI handle
|
|---|
| 289 | * @retval HAL status
|
|---|
| 290 | */
|
|---|
| 291 | HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
|
|---|
| 292 | {
|
|---|
| 293 | HAL_StatusTypeDef status;
|
|---|
| 294 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 295 |
|
|---|
| 296 | /* Check the QSPI handle allocation */
|
|---|
| 297 | if(hqspi == NULL)
|
|---|
| 298 | {
|
|---|
| 299 | return HAL_ERROR;
|
|---|
| 300 | }
|
|---|
| 301 |
|
|---|
| 302 | /* Check the parameters */
|
|---|
| 303 | assert_param(IS_QSPI_ALL_INSTANCE(hqspi->Instance));
|
|---|
| 304 | assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler));
|
|---|
| 305 | assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold));
|
|---|
| 306 | assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting));
|
|---|
| 307 | assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize));
|
|---|
| 308 | assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime));
|
|---|
| 309 | assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode));
|
|---|
| 310 | assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash));
|
|---|
| 311 |
|
|---|
| 312 | if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE )
|
|---|
| 313 | {
|
|---|
| 314 | assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID));
|
|---|
| 315 | }
|
|---|
| 316 |
|
|---|
| 317 | if(hqspi->State == HAL_QSPI_STATE_RESET)
|
|---|
| 318 | {
|
|---|
| 319 | /* Allocate lock resource and initialize it */
|
|---|
| 320 | hqspi->Lock = HAL_UNLOCKED;
|
|---|
| 321 |
|
|---|
| 322 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 323 | /* Reset Callback pointers in HAL_QSPI_STATE_RESET only */
|
|---|
| 324 | hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
|
|---|
| 325 | hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
|
|---|
| 326 | hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
|
|---|
| 327 | hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
|
|---|
| 328 | hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
|
|---|
| 329 | hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
|
|---|
| 330 | hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
|
|---|
| 331 | hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
|
|---|
| 332 | hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
|
|---|
| 333 | hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
|
|---|
| 334 |
|
|---|
| 335 | if(hqspi->MspInitCallback == NULL)
|
|---|
| 336 | {
|
|---|
| 337 | hqspi->MspInitCallback = HAL_QSPI_MspInit;
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | /* Init the low level hardware */
|
|---|
| 341 | hqspi->MspInitCallback(hqspi);
|
|---|
| 342 | #else
|
|---|
| 343 | /* Init the low level hardware : GPIO, CLOCK */
|
|---|
| 344 | HAL_QSPI_MspInit(hqspi);
|
|---|
| 345 | #endif
|
|---|
| 346 |
|
|---|
| 347 | /* Configure the default timeout for the QSPI memory access */
|
|---|
| 348 | HAL_QSPI_SetTimeout(hqspi, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
|
|---|
| 349 | }
|
|---|
| 350 |
|
|---|
| 351 | /* Configure QSPI FIFO Threshold */
|
|---|
| 352 | MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
|
|---|
| 353 | ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
|
|---|
| 354 |
|
|---|
| 355 | /* Wait till BUSY flag reset */
|
|---|
| 356 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
|
|---|
| 357 |
|
|---|
| 358 | if(status == HAL_OK)
|
|---|
| 359 | {
|
|---|
| 360 | /* Configure QSPI Clock Prescaler and Sample Shift */
|
|---|
| 361 | MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM),
|
|---|
| 362 | ((hqspi->Init.ClockPrescaler << QUADSPI_CR_PRESCALER_Pos) |
|
|---|
| 363 | hqspi->Init.SampleShifting | hqspi->Init.FlashID | hqspi->Init.DualFlash));
|
|---|
| 364 |
|
|---|
| 365 | /* Configure QSPI Flash Size, CS High Time and Clock Mode */
|
|---|
| 366 | MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE),
|
|---|
| 367 | ((hqspi->Init.FlashSize << QUADSPI_DCR_FSIZE_Pos) |
|
|---|
| 368 | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode));
|
|---|
| 369 |
|
|---|
| 370 | /* Enable the QSPI peripheral */
|
|---|
| 371 | __HAL_QSPI_ENABLE(hqspi);
|
|---|
| 372 |
|
|---|
| 373 | /* Set QSPI error code to none */
|
|---|
| 374 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 375 |
|
|---|
| 376 | /* Initialize the QSPI state */
|
|---|
| 377 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 378 | }
|
|---|
| 379 |
|
|---|
| 380 | /* Release Lock */
|
|---|
| 381 | __HAL_UNLOCK(hqspi);
|
|---|
| 382 |
|
|---|
| 383 | /* Return function status */
|
|---|
| 384 | return status;
|
|---|
| 385 | }
|
|---|
| 386 |
|
|---|
| 387 | /**
|
|---|
| 388 | * @brief De-Initialize the QSPI peripheral.
|
|---|
| 389 | * @param hqspi : QSPI handle
|
|---|
| 390 | * @retval HAL status
|
|---|
| 391 | */
|
|---|
| 392 | HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
|
|---|
| 393 | {
|
|---|
| 394 | /* Check the QSPI handle allocation */
|
|---|
| 395 | if(hqspi == NULL)
|
|---|
| 396 | {
|
|---|
| 397 | return HAL_ERROR;
|
|---|
| 398 | }
|
|---|
| 399 |
|
|---|
| 400 | /* Disable the QSPI Peripheral Clock */
|
|---|
| 401 | __HAL_QSPI_DISABLE(hqspi);
|
|---|
| 402 |
|
|---|
| 403 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 404 | if(hqspi->MspDeInitCallback == NULL)
|
|---|
| 405 | {
|
|---|
| 406 | hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
|
|---|
| 407 | }
|
|---|
| 408 |
|
|---|
| 409 | /* DeInit the low level hardware */
|
|---|
| 410 | hqspi->MspDeInitCallback(hqspi);
|
|---|
| 411 | #else
|
|---|
| 412 | /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
|
|---|
| 413 | HAL_QSPI_MspDeInit(hqspi);
|
|---|
| 414 | #endif
|
|---|
| 415 |
|
|---|
| 416 | /* Set QSPI error code to none */
|
|---|
| 417 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 418 |
|
|---|
| 419 | /* Initialize the QSPI state */
|
|---|
| 420 | hqspi->State = HAL_QSPI_STATE_RESET;
|
|---|
| 421 |
|
|---|
| 422 | /* Release Lock */
|
|---|
| 423 | __HAL_UNLOCK(hqspi);
|
|---|
| 424 |
|
|---|
| 425 | return HAL_OK;
|
|---|
| 426 | }
|
|---|
| 427 |
|
|---|
| 428 | /**
|
|---|
| 429 | * @brief Initialize the QSPI MSP.
|
|---|
| 430 | * @param hqspi : QSPI handle
|
|---|
| 431 | * @retval None
|
|---|
| 432 | */
|
|---|
| 433 | __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
|
|---|
| 434 | {
|
|---|
| 435 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 436 | UNUSED(hqspi);
|
|---|
| 437 |
|
|---|
| 438 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 439 | the HAL_QSPI_MspInit can be implemented in the user file
|
|---|
| 440 | */
|
|---|
| 441 | }
|
|---|
| 442 |
|
|---|
| 443 | /**
|
|---|
| 444 | * @brief DeInitialize the QSPI MSP.
|
|---|
| 445 | * @param hqspi : QSPI handle
|
|---|
| 446 | * @retval None
|
|---|
| 447 | */
|
|---|
| 448 | __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
|
|---|
| 449 | {
|
|---|
| 450 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 451 | UNUSED(hqspi);
|
|---|
| 452 |
|
|---|
| 453 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 454 | the HAL_QSPI_MspDeInit can be implemented in the user file
|
|---|
| 455 | */
|
|---|
| 456 | }
|
|---|
| 457 |
|
|---|
| 458 | /**
|
|---|
| 459 | * @}
|
|---|
| 460 | */
|
|---|
| 461 |
|
|---|
| 462 | /** @defgroup QSPI_Exported_Functions_Group2 Input and Output operation functions
|
|---|
| 463 | * @brief QSPI Transmit/Receive functions
|
|---|
| 464 | *
|
|---|
| 465 | @verbatim
|
|---|
| 466 | ===============================================================================
|
|---|
| 467 | ##### IO operation functions #####
|
|---|
| 468 | ===============================================================================
|
|---|
| 469 | [..]
|
|---|
| 470 | This subsection provides a set of functions allowing to :
|
|---|
| 471 | (+) Handle the interrupts.
|
|---|
| 472 | (+) Handle the command sequence.
|
|---|
| 473 | (+) Transmit data in blocking, interrupt or DMA mode.
|
|---|
| 474 | (+) Receive data in blocking, interrupt or DMA mode.
|
|---|
| 475 | (+) Manage the auto-polling functional mode.
|
|---|
| 476 | (+) Manage the memory-mapped functional mode.
|
|---|
| 477 |
|
|---|
| 478 | @endverbatim
|
|---|
| 479 | * @{
|
|---|
| 480 | */
|
|---|
| 481 |
|
|---|
| 482 | /**
|
|---|
| 483 | * @brief Handle QSPI interrupt request.
|
|---|
| 484 | * @param hqspi : QSPI handle
|
|---|
| 485 | * @retval None
|
|---|
| 486 | */
|
|---|
| 487 | void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi)
|
|---|
| 488 | {
|
|---|
| 489 | __IO uint32_t *data_reg;
|
|---|
| 490 | uint32_t flag = READ_REG(hqspi->Instance->SR);
|
|---|
| 491 | uint32_t itsource = READ_REG(hqspi->Instance->CR);
|
|---|
| 492 |
|
|---|
| 493 | /* QSPI Fifo Threshold interrupt occurred ----------------------------------*/
|
|---|
| 494 | if(((flag & QSPI_FLAG_FT) != 0U) && ((itsource & QSPI_IT_FT) != 0U))
|
|---|
| 495 | {
|
|---|
| 496 | data_reg = &hqspi->Instance->DR;
|
|---|
| 497 |
|
|---|
| 498 | if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
|
|---|
| 499 | {
|
|---|
| 500 | /* Transmission process */
|
|---|
| 501 | while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
|
|---|
| 502 | {
|
|---|
| 503 | if (hqspi->TxXferCount > 0U)
|
|---|
| 504 | {
|
|---|
| 505 | /* Fill the FIFO until the threshold is reached */
|
|---|
| 506 | *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
|
|---|
| 507 | hqspi->pTxBuffPtr++;
|
|---|
| 508 | hqspi->TxXferCount--;
|
|---|
| 509 | }
|
|---|
| 510 | else
|
|---|
| 511 | {
|
|---|
| 512 | /* No more data available for the transfer */
|
|---|
| 513 | /* Disable the QSPI FIFO Threshold Interrupt */
|
|---|
| 514 | __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
|
|---|
| 515 | break;
|
|---|
| 516 | }
|
|---|
| 517 | }
|
|---|
| 518 | }
|
|---|
| 519 | else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
|
|---|
| 520 | {
|
|---|
| 521 | /* Receiving Process */
|
|---|
| 522 | while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != RESET)
|
|---|
| 523 | {
|
|---|
| 524 | if (hqspi->RxXferCount > 0U)
|
|---|
| 525 | {
|
|---|
| 526 | /* Read the FIFO until the threshold is reached */
|
|---|
| 527 | *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
|
|---|
| 528 | hqspi->pRxBuffPtr++;
|
|---|
| 529 | hqspi->RxXferCount--;
|
|---|
| 530 | }
|
|---|
| 531 | else
|
|---|
| 532 | {
|
|---|
| 533 | /* All data have been received for the transfer */
|
|---|
| 534 | /* Disable the QSPI FIFO Threshold Interrupt */
|
|---|
| 535 | __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_FT);
|
|---|
| 536 | break;
|
|---|
| 537 | }
|
|---|
| 538 | }
|
|---|
| 539 | }
|
|---|
| 540 | else
|
|---|
| 541 | {
|
|---|
| 542 | /* Nothing to do */
|
|---|
| 543 | }
|
|---|
| 544 |
|
|---|
| 545 | /* FIFO Threshold callback */
|
|---|
| 546 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 547 | hqspi->FifoThresholdCallback(hqspi);
|
|---|
| 548 | #else
|
|---|
| 549 | HAL_QSPI_FifoThresholdCallback(hqspi);
|
|---|
| 550 | #endif
|
|---|
| 551 | }
|
|---|
| 552 |
|
|---|
| 553 | /* QSPI Transfer Complete interrupt occurred -------------------------------*/
|
|---|
| 554 | else if(((flag & QSPI_FLAG_TC) != 0U) && ((itsource & QSPI_IT_TC) != 0U))
|
|---|
| 555 | {
|
|---|
| 556 | /* Clear interrupt */
|
|---|
| 557 | WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TC);
|
|---|
| 558 |
|
|---|
| 559 | /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */
|
|---|
| 560 | __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
|
|---|
| 561 |
|
|---|
| 562 | /* Transfer complete callback */
|
|---|
| 563 | if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX)
|
|---|
| 564 | {
|
|---|
| 565 | if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
|
|---|
| 566 | {
|
|---|
| 567 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 568 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 569 |
|
|---|
| 570 | /* Disable the DMA channel */
|
|---|
| 571 | __HAL_DMA_DISABLE(hqspi->hdma);
|
|---|
| 572 | }
|
|---|
| 573 |
|
|---|
| 574 | /* Clear Busy bit */
|
|---|
| 575 | HAL_QSPI_Abort_IT(hqspi);
|
|---|
| 576 |
|
|---|
| 577 | /* Change state of QSPI */
|
|---|
| 578 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 579 |
|
|---|
| 580 | /* TX Complete callback */
|
|---|
| 581 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 582 | hqspi->TxCpltCallback(hqspi);
|
|---|
| 583 | #else
|
|---|
| 584 | HAL_QSPI_TxCpltCallback(hqspi);
|
|---|
| 585 | #endif
|
|---|
| 586 | }
|
|---|
| 587 | else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX)
|
|---|
| 588 | {
|
|---|
| 589 | if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
|
|---|
| 590 | {
|
|---|
| 591 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 592 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 593 |
|
|---|
| 594 | /* Disable the DMA channel */
|
|---|
| 595 | __HAL_DMA_DISABLE(hqspi->hdma);
|
|---|
| 596 | }
|
|---|
| 597 | else
|
|---|
| 598 | {
|
|---|
| 599 | data_reg = &hqspi->Instance->DR;
|
|---|
| 600 | while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0U)
|
|---|
| 601 | {
|
|---|
| 602 | if (hqspi->RxXferCount > 0U)
|
|---|
| 603 | {
|
|---|
| 604 | /* Read the last data received in the FIFO until it is empty */
|
|---|
| 605 | *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
|
|---|
| 606 | hqspi->pRxBuffPtr++;
|
|---|
| 607 | hqspi->RxXferCount--;
|
|---|
| 608 | }
|
|---|
| 609 | else
|
|---|
| 610 | {
|
|---|
| 611 | /* All data have been received for the transfer */
|
|---|
| 612 | break;
|
|---|
| 613 | }
|
|---|
| 614 | }
|
|---|
| 615 | }
|
|---|
| 616 |
|
|---|
| 617 | /* Workaround - Extra data written in the FIFO at the end of a read transfer */
|
|---|
| 618 | HAL_QSPI_Abort_IT(hqspi);
|
|---|
| 619 |
|
|---|
| 620 | /* Change state of QSPI */
|
|---|
| 621 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 622 |
|
|---|
| 623 | /* RX Complete callback */
|
|---|
| 624 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 625 | hqspi->RxCpltCallback(hqspi);
|
|---|
| 626 | #else
|
|---|
| 627 | HAL_QSPI_RxCpltCallback(hqspi);
|
|---|
| 628 | #endif
|
|---|
| 629 | }
|
|---|
| 630 | else if(hqspi->State == HAL_QSPI_STATE_BUSY)
|
|---|
| 631 | {
|
|---|
| 632 | /* Change state of QSPI */
|
|---|
| 633 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 634 |
|
|---|
| 635 | /* Command Complete callback */
|
|---|
| 636 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 637 | hqspi->CmdCpltCallback(hqspi);
|
|---|
| 638 | #else
|
|---|
| 639 | HAL_QSPI_CmdCpltCallback(hqspi);
|
|---|
| 640 | #endif
|
|---|
| 641 | }
|
|---|
| 642 | else if(hqspi->State == HAL_QSPI_STATE_ABORT)
|
|---|
| 643 | {
|
|---|
| 644 | /* Reset functional mode configuration to indirect write mode by default */
|
|---|
| 645 | CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
|
|---|
| 646 |
|
|---|
| 647 | /* Change state of QSPI */
|
|---|
| 648 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 649 |
|
|---|
| 650 | if (hqspi->ErrorCode == HAL_QSPI_ERROR_NONE)
|
|---|
| 651 | {
|
|---|
| 652 | /* Abort called by the user */
|
|---|
| 653 |
|
|---|
| 654 | /* Abort Complete callback */
|
|---|
| 655 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 656 | hqspi->AbortCpltCallback(hqspi);
|
|---|
| 657 | #else
|
|---|
| 658 | HAL_QSPI_AbortCpltCallback(hqspi);
|
|---|
| 659 | #endif
|
|---|
| 660 | }
|
|---|
| 661 | else
|
|---|
| 662 | {
|
|---|
| 663 | /* Abort due to an error (eg : DMA error) */
|
|---|
| 664 |
|
|---|
| 665 | /* Error callback */
|
|---|
| 666 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 667 | hqspi->ErrorCallback(hqspi);
|
|---|
| 668 | #else
|
|---|
| 669 | HAL_QSPI_ErrorCallback(hqspi);
|
|---|
| 670 | #endif
|
|---|
| 671 | }
|
|---|
| 672 | }
|
|---|
| 673 | else
|
|---|
| 674 | {
|
|---|
| 675 | /* Nothing to do */
|
|---|
| 676 | }
|
|---|
| 677 | }
|
|---|
| 678 |
|
|---|
| 679 | /* QSPI Status Match interrupt occurred ------------------------------------*/
|
|---|
| 680 | else if(((flag & QSPI_FLAG_SM) != 0U) && ((itsource & QSPI_IT_SM) != 0U))
|
|---|
| 681 | {
|
|---|
| 682 | /* Clear interrupt */
|
|---|
| 683 | WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_SM);
|
|---|
| 684 |
|
|---|
| 685 | /* Check if the automatic poll mode stop is activated */
|
|---|
| 686 | if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0U)
|
|---|
| 687 | {
|
|---|
| 688 | /* Disable the QSPI Transfer Error and Status Match Interrupts */
|
|---|
| 689 | __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
|
|---|
| 690 |
|
|---|
| 691 | /* Change state of QSPI */
|
|---|
| 692 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 693 | }
|
|---|
| 694 |
|
|---|
| 695 | /* Status match callback */
|
|---|
| 696 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 697 | hqspi->StatusMatchCallback(hqspi);
|
|---|
| 698 | #else
|
|---|
| 699 | HAL_QSPI_StatusMatchCallback(hqspi);
|
|---|
| 700 | #endif
|
|---|
| 701 | }
|
|---|
| 702 |
|
|---|
| 703 | /* QSPI Transfer Error interrupt occurred ----------------------------------*/
|
|---|
| 704 | else if(((flag & QSPI_FLAG_TE) != 0U) && ((itsource & QSPI_IT_TE) != 0U))
|
|---|
| 705 | {
|
|---|
| 706 | /* Clear interrupt */
|
|---|
| 707 | WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TE);
|
|---|
| 708 |
|
|---|
| 709 | /* Disable all the QSPI Interrupts */
|
|---|
| 710 | __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT);
|
|---|
| 711 |
|
|---|
| 712 | /* Set error code */
|
|---|
| 713 | hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER;
|
|---|
| 714 |
|
|---|
| 715 | if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
|
|---|
| 716 | {
|
|---|
| 717 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 718 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 719 |
|
|---|
| 720 | /* Disable the DMA channel */
|
|---|
| 721 | hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
|
|---|
| 722 | if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
|
|---|
| 723 | {
|
|---|
| 724 | /* Set error code to DMA */
|
|---|
| 725 | hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
|
|---|
| 726 |
|
|---|
| 727 | /* Change state of QSPI */
|
|---|
| 728 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 729 |
|
|---|
| 730 | /* Error callback */
|
|---|
| 731 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 732 | hqspi->ErrorCallback(hqspi);
|
|---|
| 733 | #else
|
|---|
| 734 | HAL_QSPI_ErrorCallback(hqspi);
|
|---|
| 735 | #endif
|
|---|
| 736 | }
|
|---|
| 737 | }
|
|---|
| 738 | else
|
|---|
| 739 | {
|
|---|
| 740 | /* Change state of QSPI */
|
|---|
| 741 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 742 |
|
|---|
| 743 | /* Error callback */
|
|---|
| 744 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 745 | hqspi->ErrorCallback(hqspi);
|
|---|
| 746 | #else
|
|---|
| 747 | HAL_QSPI_ErrorCallback(hqspi);
|
|---|
| 748 | #endif
|
|---|
| 749 | }
|
|---|
| 750 | }
|
|---|
| 751 |
|
|---|
| 752 | /* QSPI Timeout interrupt occurred -----------------------------------------*/
|
|---|
| 753 | else if(((flag & QSPI_FLAG_TO) != 0U) && ((itsource & QSPI_IT_TO) != 0U))
|
|---|
| 754 | {
|
|---|
| 755 | /* Clear interrupt */
|
|---|
| 756 | WRITE_REG(hqspi->Instance->FCR, QSPI_FLAG_TO);
|
|---|
| 757 |
|
|---|
| 758 | /* Timeout callback */
|
|---|
| 759 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 760 | hqspi->TimeOutCallback(hqspi);
|
|---|
| 761 | #else
|
|---|
| 762 | HAL_QSPI_TimeOutCallback(hqspi);
|
|---|
| 763 | #endif
|
|---|
| 764 | }
|
|---|
| 765 |
|
|---|
| 766 | else
|
|---|
| 767 | {
|
|---|
| 768 | /* Nothing to do */
|
|---|
| 769 | }
|
|---|
| 770 | }
|
|---|
| 771 |
|
|---|
| 772 | /**
|
|---|
| 773 | * @brief Set the command configuration.
|
|---|
| 774 | * @param hqspi : QSPI handle
|
|---|
| 775 | * @param cmd : structure that contains the command configuration information
|
|---|
| 776 | * @param Timeout : Timeout duration
|
|---|
| 777 | * @note This function is used only in Indirect Read or Write Modes
|
|---|
| 778 | * @retval HAL status
|
|---|
| 779 | */
|
|---|
| 780 | HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
|
|---|
| 781 | {
|
|---|
| 782 | HAL_StatusTypeDef status;
|
|---|
| 783 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 784 |
|
|---|
| 785 | /* Check the parameters */
|
|---|
| 786 | assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
|
|---|
| 787 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 788 | {
|
|---|
| 789 | assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
|
|---|
| 790 | }
|
|---|
| 791 |
|
|---|
| 792 | assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
|
|---|
| 793 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 794 | {
|
|---|
| 795 | assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
|
|---|
| 796 | }
|
|---|
| 797 |
|
|---|
| 798 | assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
|
|---|
| 799 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 800 | {
|
|---|
| 801 | assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
|
|---|
| 802 | }
|
|---|
| 803 |
|
|---|
| 804 | assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
|
|---|
| 805 | assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
|
|---|
| 806 |
|
|---|
| 807 | assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
|
|---|
| 808 | assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
|
|---|
| 809 | assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
|
|---|
| 810 |
|
|---|
| 811 | /* Process locked */
|
|---|
| 812 | __HAL_LOCK(hqspi);
|
|---|
| 813 |
|
|---|
| 814 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 815 | {
|
|---|
| 816 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 817 |
|
|---|
| 818 | /* Update QSPI state */
|
|---|
| 819 | hqspi->State = HAL_QSPI_STATE_BUSY;
|
|---|
| 820 |
|
|---|
| 821 | /* Wait till BUSY flag reset */
|
|---|
| 822 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
|
|---|
| 823 |
|
|---|
| 824 | if (status == HAL_OK)
|
|---|
| 825 | {
|
|---|
| 826 | /* Call the configuration function */
|
|---|
| 827 | QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
|
|---|
| 828 |
|
|---|
| 829 | if (cmd->DataMode == QSPI_DATA_NONE)
|
|---|
| 830 | {
|
|---|
| 831 | /* When there is no data phase, the transfer start as soon as the configuration is done
|
|---|
| 832 | so wait until TC flag is set to go back in idle state */
|
|---|
| 833 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
|
|---|
| 834 |
|
|---|
| 835 | if (status == HAL_OK)
|
|---|
| 836 | {
|
|---|
| 837 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 838 |
|
|---|
| 839 | /* Update QSPI state */
|
|---|
| 840 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 841 | }
|
|---|
| 842 | }
|
|---|
| 843 | else
|
|---|
| 844 | {
|
|---|
| 845 | /* Update QSPI state */
|
|---|
| 846 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 847 | }
|
|---|
| 848 | }
|
|---|
| 849 | }
|
|---|
| 850 | else
|
|---|
| 851 | {
|
|---|
| 852 | status = HAL_BUSY;
|
|---|
| 853 | }
|
|---|
| 854 |
|
|---|
| 855 | /* Process unlocked */
|
|---|
| 856 | __HAL_UNLOCK(hqspi);
|
|---|
| 857 |
|
|---|
| 858 | /* Return function status */
|
|---|
| 859 | return status;
|
|---|
| 860 | }
|
|---|
| 861 |
|
|---|
| 862 | /**
|
|---|
| 863 | * @brief Set the command configuration in interrupt mode.
|
|---|
| 864 | * @param hqspi : QSPI handle
|
|---|
| 865 | * @param cmd : structure that contains the command configuration information
|
|---|
| 866 | * @note This function is used only in Indirect Read or Write Modes
|
|---|
| 867 | * @retval HAL status
|
|---|
| 868 | */
|
|---|
| 869 | HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd)
|
|---|
| 870 | {
|
|---|
| 871 | HAL_StatusTypeDef status;
|
|---|
| 872 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 873 |
|
|---|
| 874 | /* Check the parameters */
|
|---|
| 875 | assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
|
|---|
| 876 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 877 | {
|
|---|
| 878 | assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
|
|---|
| 879 | }
|
|---|
| 880 |
|
|---|
| 881 | assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
|
|---|
| 882 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 883 | {
|
|---|
| 884 | assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
|
|---|
| 885 | }
|
|---|
| 886 |
|
|---|
| 887 | assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
|
|---|
| 888 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 889 | {
|
|---|
| 890 | assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
|
|---|
| 891 | }
|
|---|
| 892 |
|
|---|
| 893 | assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
|
|---|
| 894 | assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
|
|---|
| 895 |
|
|---|
| 896 | assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
|
|---|
| 897 | assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
|
|---|
| 898 | assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
|
|---|
| 899 |
|
|---|
| 900 | /* Process locked */
|
|---|
| 901 | __HAL_LOCK(hqspi);
|
|---|
| 902 |
|
|---|
| 903 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 904 | {
|
|---|
| 905 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 906 |
|
|---|
| 907 | /* Update QSPI state */
|
|---|
| 908 | hqspi->State = HAL_QSPI_STATE_BUSY;
|
|---|
| 909 |
|
|---|
| 910 | /* Wait till BUSY flag reset */
|
|---|
| 911 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
|
|---|
| 912 |
|
|---|
| 913 | if (status == HAL_OK)
|
|---|
| 914 | {
|
|---|
| 915 | if (cmd->DataMode == QSPI_DATA_NONE)
|
|---|
| 916 | {
|
|---|
| 917 | /* Clear interrupt */
|
|---|
| 918 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
|
|---|
| 919 | }
|
|---|
| 920 |
|
|---|
| 921 | /* Call the configuration function */
|
|---|
| 922 | QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
|
|---|
| 923 |
|
|---|
| 924 | if (cmd->DataMode == QSPI_DATA_NONE)
|
|---|
| 925 | {
|
|---|
| 926 | /* When there is no data phase, the transfer start as soon as the configuration is done
|
|---|
| 927 | so activate TC and TE interrupts */
|
|---|
| 928 | /* Process unlocked */
|
|---|
| 929 | __HAL_UNLOCK(hqspi);
|
|---|
| 930 |
|
|---|
| 931 | /* Enable the QSPI Transfer Error Interrupt */
|
|---|
| 932 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC);
|
|---|
| 933 | }
|
|---|
| 934 | else
|
|---|
| 935 | {
|
|---|
| 936 | /* Update QSPI state */
|
|---|
| 937 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 938 |
|
|---|
| 939 | /* Process unlocked */
|
|---|
| 940 | __HAL_UNLOCK(hqspi);
|
|---|
| 941 | }
|
|---|
| 942 | }
|
|---|
| 943 | else
|
|---|
| 944 | {
|
|---|
| 945 | /* Process unlocked */
|
|---|
| 946 | __HAL_UNLOCK(hqspi);
|
|---|
| 947 | }
|
|---|
| 948 | }
|
|---|
| 949 | else
|
|---|
| 950 | {
|
|---|
| 951 | status = HAL_BUSY;
|
|---|
| 952 |
|
|---|
| 953 | /* Process unlocked */
|
|---|
| 954 | __HAL_UNLOCK(hqspi);
|
|---|
| 955 | }
|
|---|
| 956 |
|
|---|
| 957 | /* Return function status */
|
|---|
| 958 | return status;
|
|---|
| 959 | }
|
|---|
| 960 |
|
|---|
| 961 | /**
|
|---|
| 962 | * @brief Transmit an amount of data in blocking mode.
|
|---|
| 963 | * @param hqspi : QSPI handle
|
|---|
| 964 | * @param pData : pointer to data buffer
|
|---|
| 965 | * @param Timeout : Timeout duration
|
|---|
| 966 | * @note This function is used only in Indirect Write Mode
|
|---|
| 967 | * @retval HAL status
|
|---|
| 968 | */
|
|---|
| 969 | HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
|
|---|
| 970 | {
|
|---|
| 971 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 972 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 973 | __IO uint32_t *data_reg = &hqspi->Instance->DR;
|
|---|
| 974 |
|
|---|
| 975 | /* Process locked */
|
|---|
| 976 | __HAL_LOCK(hqspi);
|
|---|
| 977 |
|
|---|
| 978 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 979 | {
|
|---|
| 980 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 981 |
|
|---|
| 982 | if(pData != NULL )
|
|---|
| 983 | {
|
|---|
| 984 | /* Update state */
|
|---|
| 985 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
|
|---|
| 986 |
|
|---|
| 987 | /* Configure counters and size of the handle */
|
|---|
| 988 | hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 989 | hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 990 | hqspi->pTxBuffPtr = pData;
|
|---|
| 991 |
|
|---|
| 992 | /* Configure QSPI: CCR register with functional as indirect write */
|
|---|
| 993 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
|
|---|
| 994 |
|
|---|
| 995 | while(hqspi->TxXferCount > 0U)
|
|---|
| 996 | {
|
|---|
| 997 | /* Wait until FT flag is set to send data */
|
|---|
| 998 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, tickstart, Timeout);
|
|---|
| 999 |
|
|---|
| 1000 | if (status != HAL_OK)
|
|---|
| 1001 | {
|
|---|
| 1002 | break;
|
|---|
| 1003 | }
|
|---|
| 1004 |
|
|---|
| 1005 | *((__IO uint8_t *)data_reg) = *hqspi->pTxBuffPtr;
|
|---|
| 1006 | hqspi->pTxBuffPtr++;
|
|---|
| 1007 | hqspi->TxXferCount--;
|
|---|
| 1008 | }
|
|---|
| 1009 |
|
|---|
| 1010 | if (status == HAL_OK)
|
|---|
| 1011 | {
|
|---|
| 1012 | /* Wait until TC flag is set to go back in idle state */
|
|---|
| 1013 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
|
|---|
| 1014 |
|
|---|
| 1015 | if (status == HAL_OK)
|
|---|
| 1016 | {
|
|---|
| 1017 | /* Clear Transfer Complete bit */
|
|---|
| 1018 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 1019 |
|
|---|
| 1020 | /* Clear Busy bit */
|
|---|
| 1021 | status = HAL_QSPI_Abort(hqspi);
|
|---|
| 1022 | }
|
|---|
| 1023 | }
|
|---|
| 1024 |
|
|---|
| 1025 | /* Update QSPI state */
|
|---|
| 1026 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 1027 | }
|
|---|
| 1028 | else
|
|---|
| 1029 | {
|
|---|
| 1030 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1031 | status = HAL_ERROR;
|
|---|
| 1032 | }
|
|---|
| 1033 | }
|
|---|
| 1034 | else
|
|---|
| 1035 | {
|
|---|
| 1036 | status = HAL_BUSY;
|
|---|
| 1037 | }
|
|---|
| 1038 |
|
|---|
| 1039 | /* Process unlocked */
|
|---|
| 1040 | __HAL_UNLOCK(hqspi);
|
|---|
| 1041 |
|
|---|
| 1042 | return status;
|
|---|
| 1043 | }
|
|---|
| 1044 |
|
|---|
| 1045 |
|
|---|
| 1046 | /**
|
|---|
| 1047 | * @brief Receive an amount of data in blocking mode.
|
|---|
| 1048 | * @param hqspi : QSPI handle
|
|---|
| 1049 | * @param pData : pointer to data buffer
|
|---|
| 1050 | * @param Timeout : Timeout duration
|
|---|
| 1051 | * @note This function is used only in Indirect Read Mode
|
|---|
| 1052 | * @retval HAL status
|
|---|
| 1053 | */
|
|---|
| 1054 | HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
|
|---|
| 1055 | {
|
|---|
| 1056 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 1057 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 1058 | uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
|
|---|
| 1059 | __IO uint32_t *data_reg = &hqspi->Instance->DR;
|
|---|
| 1060 |
|
|---|
| 1061 | /* Process locked */
|
|---|
| 1062 | __HAL_LOCK(hqspi);
|
|---|
| 1063 |
|
|---|
| 1064 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1065 | {
|
|---|
| 1066 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1067 |
|
|---|
| 1068 | if(pData != NULL )
|
|---|
| 1069 | {
|
|---|
| 1070 | /* Update state */
|
|---|
| 1071 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
|
|---|
| 1072 |
|
|---|
| 1073 | /* Configure counters and size of the handle */
|
|---|
| 1074 | hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1075 | hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1076 | hqspi->pRxBuffPtr = pData;
|
|---|
| 1077 |
|
|---|
| 1078 | /* Configure QSPI: CCR register with functional as indirect read */
|
|---|
| 1079 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
|
|---|
| 1080 |
|
|---|
| 1081 | /* Start the transfer by re-writing the address in AR register */
|
|---|
| 1082 | WRITE_REG(hqspi->Instance->AR, addr_reg);
|
|---|
| 1083 |
|
|---|
| 1084 | while(hqspi->RxXferCount > 0U)
|
|---|
| 1085 | {
|
|---|
| 1086 | /* Wait until FT or TC flag is set to read received data */
|
|---|
| 1087 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
|
|---|
| 1088 |
|
|---|
| 1089 | if (status != HAL_OK)
|
|---|
| 1090 | {
|
|---|
| 1091 | break;
|
|---|
| 1092 | }
|
|---|
| 1093 |
|
|---|
| 1094 | *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
|
|---|
| 1095 | hqspi->pRxBuffPtr++;
|
|---|
| 1096 | hqspi->RxXferCount--;
|
|---|
| 1097 | }
|
|---|
| 1098 |
|
|---|
| 1099 | if (status == HAL_OK)
|
|---|
| 1100 | {
|
|---|
| 1101 | /* Wait until TC flag is set to go back in idle state */
|
|---|
| 1102 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
|
|---|
| 1103 |
|
|---|
| 1104 | if (status == HAL_OK)
|
|---|
| 1105 | {
|
|---|
| 1106 | /* Clear Transfer Complete bit */
|
|---|
| 1107 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 1108 |
|
|---|
| 1109 | /* Workaround - Extra data written in the FIFO at the end of a read transfer */
|
|---|
| 1110 | status = HAL_QSPI_Abort(hqspi);
|
|---|
| 1111 | }
|
|---|
| 1112 | }
|
|---|
| 1113 |
|
|---|
| 1114 | /* Update QSPI state */
|
|---|
| 1115 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 1116 | }
|
|---|
| 1117 | else
|
|---|
| 1118 | {
|
|---|
| 1119 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1120 | status = HAL_ERROR;
|
|---|
| 1121 | }
|
|---|
| 1122 | }
|
|---|
| 1123 | else
|
|---|
| 1124 | {
|
|---|
| 1125 | status = HAL_BUSY;
|
|---|
| 1126 | }
|
|---|
| 1127 |
|
|---|
| 1128 | /* Process unlocked */
|
|---|
| 1129 | __HAL_UNLOCK(hqspi);
|
|---|
| 1130 |
|
|---|
| 1131 | return status;
|
|---|
| 1132 | }
|
|---|
| 1133 |
|
|---|
| 1134 | /**
|
|---|
| 1135 | * @brief Send an amount of data in non-blocking mode with interrupt.
|
|---|
| 1136 | * @param hqspi : QSPI handle
|
|---|
| 1137 | * @param pData : pointer to data buffer
|
|---|
| 1138 | * @note This function is used only in Indirect Write Mode
|
|---|
| 1139 | * @retval HAL status
|
|---|
| 1140 | */
|
|---|
| 1141 | HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
|
|---|
| 1142 | {
|
|---|
| 1143 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 1144 |
|
|---|
| 1145 | /* Process locked */
|
|---|
| 1146 | __HAL_LOCK(hqspi);
|
|---|
| 1147 |
|
|---|
| 1148 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1149 | {
|
|---|
| 1150 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1151 |
|
|---|
| 1152 | if(pData != NULL )
|
|---|
| 1153 | {
|
|---|
| 1154 | /* Update state */
|
|---|
| 1155 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
|
|---|
| 1156 |
|
|---|
| 1157 | /* Configure counters and size of the handle */
|
|---|
| 1158 | hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1159 | hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1160 | hqspi->pTxBuffPtr = pData;
|
|---|
| 1161 |
|
|---|
| 1162 | /* Clear interrupt */
|
|---|
| 1163 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
|
|---|
| 1164 |
|
|---|
| 1165 | /* Configure QSPI: CCR register with functional as indirect write */
|
|---|
| 1166 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
|
|---|
| 1167 |
|
|---|
| 1168 | /* Process unlocked */
|
|---|
| 1169 | __HAL_UNLOCK(hqspi);
|
|---|
| 1170 |
|
|---|
| 1171 | /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
|
|---|
| 1172 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
|
|---|
| 1173 | }
|
|---|
| 1174 | else
|
|---|
| 1175 | {
|
|---|
| 1176 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1177 | status = HAL_ERROR;
|
|---|
| 1178 |
|
|---|
| 1179 | /* Process unlocked */
|
|---|
| 1180 | __HAL_UNLOCK(hqspi);
|
|---|
| 1181 | }
|
|---|
| 1182 | }
|
|---|
| 1183 | else
|
|---|
| 1184 | {
|
|---|
| 1185 | status = HAL_BUSY;
|
|---|
| 1186 |
|
|---|
| 1187 | /* Process unlocked */
|
|---|
| 1188 | __HAL_UNLOCK(hqspi);
|
|---|
| 1189 | }
|
|---|
| 1190 |
|
|---|
| 1191 | return status;
|
|---|
| 1192 | }
|
|---|
| 1193 |
|
|---|
| 1194 | /**
|
|---|
| 1195 | * @brief Receive an amount of data in non-blocking mode with interrupt.
|
|---|
| 1196 | * @param hqspi : QSPI handle
|
|---|
| 1197 | * @param pData : pointer to data buffer
|
|---|
| 1198 | * @note This function is used only in Indirect Read Mode
|
|---|
| 1199 | * @retval HAL status
|
|---|
| 1200 | */
|
|---|
| 1201 | HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
|
|---|
| 1202 | {
|
|---|
| 1203 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 1204 | uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
|
|---|
| 1205 |
|
|---|
| 1206 | /* Process locked */
|
|---|
| 1207 | __HAL_LOCK(hqspi);
|
|---|
| 1208 |
|
|---|
| 1209 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1210 | {
|
|---|
| 1211 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1212 |
|
|---|
| 1213 | if(pData != NULL )
|
|---|
| 1214 | {
|
|---|
| 1215 | /* Update state */
|
|---|
| 1216 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
|
|---|
| 1217 |
|
|---|
| 1218 | /* Configure counters and size of the handle */
|
|---|
| 1219 | hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1220 | hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1U;
|
|---|
| 1221 | hqspi->pRxBuffPtr = pData;
|
|---|
| 1222 |
|
|---|
| 1223 | /* Clear interrupt */
|
|---|
| 1224 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_TC);
|
|---|
| 1225 |
|
|---|
| 1226 | /* Configure QSPI: CCR register with functional as indirect read */
|
|---|
| 1227 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
|
|---|
| 1228 |
|
|---|
| 1229 | /* Start the transfer by re-writing the address in AR register */
|
|---|
| 1230 | WRITE_REG(hqspi->Instance->AR, addr_reg);
|
|---|
| 1231 |
|
|---|
| 1232 | /* Process unlocked */
|
|---|
| 1233 | __HAL_UNLOCK(hqspi);
|
|---|
| 1234 |
|
|---|
| 1235 | /* Enable the QSPI transfer error, FIFO threshold and transfer complete Interrupts */
|
|---|
| 1236 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC);
|
|---|
| 1237 | }
|
|---|
| 1238 | else
|
|---|
| 1239 | {
|
|---|
| 1240 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1241 | status = HAL_ERROR;
|
|---|
| 1242 |
|
|---|
| 1243 | /* Process unlocked */
|
|---|
| 1244 | __HAL_UNLOCK(hqspi);
|
|---|
| 1245 | }
|
|---|
| 1246 | }
|
|---|
| 1247 | else
|
|---|
| 1248 | {
|
|---|
| 1249 | status = HAL_BUSY;
|
|---|
| 1250 |
|
|---|
| 1251 | /* Process unlocked */
|
|---|
| 1252 | __HAL_UNLOCK(hqspi);
|
|---|
| 1253 | }
|
|---|
| 1254 |
|
|---|
| 1255 | return status;
|
|---|
| 1256 | }
|
|---|
| 1257 |
|
|---|
| 1258 | /**
|
|---|
| 1259 | * @brief Send an amount of data in non-blocking mode with DMA.
|
|---|
| 1260 | * @param hqspi : QSPI handle
|
|---|
| 1261 | * @param pData : pointer to data buffer
|
|---|
| 1262 | * @note This function is used only in Indirect Write Mode
|
|---|
| 1263 | * @note If DMA peripheral access is configured as halfword, the number
|
|---|
| 1264 | * of data and the fifo threshold should be aligned on halfword
|
|---|
| 1265 | * @note If DMA peripheral access is configured as word, the number
|
|---|
| 1266 | * of data and the fifo threshold should be aligned on word
|
|---|
| 1267 | * @retval HAL status
|
|---|
| 1268 | */
|
|---|
| 1269 | HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
|
|---|
| 1270 | {
|
|---|
| 1271 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 1272 | uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
|
|---|
| 1273 |
|
|---|
| 1274 | /* Process locked */
|
|---|
| 1275 | __HAL_LOCK(hqspi);
|
|---|
| 1276 |
|
|---|
| 1277 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1278 | {
|
|---|
| 1279 | /* Clear the error code */
|
|---|
| 1280 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1281 |
|
|---|
| 1282 | if(pData != NULL )
|
|---|
| 1283 | {
|
|---|
| 1284 | /* Configure counters of the handle */
|
|---|
| 1285 | if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
|
|---|
| 1286 | {
|
|---|
| 1287 | hqspi->TxXferCount = data_size;
|
|---|
| 1288 | }
|
|---|
| 1289 | else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
|
|---|
| 1290 | {
|
|---|
| 1291 | if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
|
|---|
| 1292 | {
|
|---|
| 1293 | /* The number of data or the fifo threshold is not aligned on halfword
|
|---|
| 1294 | => no transfer possible with DMA peripheral access configured as halfword */
|
|---|
| 1295 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1296 | status = HAL_ERROR;
|
|---|
| 1297 |
|
|---|
| 1298 | /* Process unlocked */
|
|---|
| 1299 | __HAL_UNLOCK(hqspi);
|
|---|
| 1300 | }
|
|---|
| 1301 | else
|
|---|
| 1302 | {
|
|---|
| 1303 | hqspi->TxXferCount = (data_size >> 1U);
|
|---|
| 1304 | }
|
|---|
| 1305 | }
|
|---|
| 1306 | else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
|
|---|
| 1307 | {
|
|---|
| 1308 | if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
|
|---|
| 1309 | {
|
|---|
| 1310 | /* The number of data or the fifo threshold is not aligned on word
|
|---|
| 1311 | => no transfer possible with DMA peripheral access configured as word */
|
|---|
| 1312 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1313 | status = HAL_ERROR;
|
|---|
| 1314 |
|
|---|
| 1315 | /* Process unlocked */
|
|---|
| 1316 | __HAL_UNLOCK(hqspi);
|
|---|
| 1317 | }
|
|---|
| 1318 | else
|
|---|
| 1319 | {
|
|---|
| 1320 | hqspi->TxXferCount = (data_size >> 2U);
|
|---|
| 1321 | }
|
|---|
| 1322 | }
|
|---|
| 1323 | else
|
|---|
| 1324 | {
|
|---|
| 1325 | /* Nothing to do */
|
|---|
| 1326 | }
|
|---|
| 1327 |
|
|---|
| 1328 | if (status == HAL_OK)
|
|---|
| 1329 | {
|
|---|
| 1330 | /* Update state */
|
|---|
| 1331 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX;
|
|---|
| 1332 |
|
|---|
| 1333 | /* Clear interrupt */
|
|---|
| 1334 | __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
|
|---|
| 1335 |
|
|---|
| 1336 | /* Configure size and pointer of the handle */
|
|---|
| 1337 | hqspi->TxXferSize = hqspi->TxXferCount;
|
|---|
| 1338 | hqspi->pTxBuffPtr = pData;
|
|---|
| 1339 |
|
|---|
| 1340 | /* Configure QSPI: CCR register with functional mode as indirect write */
|
|---|
| 1341 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
|
|---|
| 1342 |
|
|---|
| 1343 | /* Set the QSPI DMA transfer complete callback */
|
|---|
| 1344 | hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt;
|
|---|
| 1345 |
|
|---|
| 1346 | /* Set the QSPI DMA Half transfer complete callback */
|
|---|
| 1347 | hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt;
|
|---|
| 1348 |
|
|---|
| 1349 | /* Set the DMA error callback */
|
|---|
| 1350 | hqspi->hdma->XferErrorCallback = QSPI_DMAError;
|
|---|
| 1351 |
|
|---|
| 1352 | /* Clear the DMA abort callback */
|
|---|
| 1353 | hqspi->hdma->XferAbortCallback = NULL;
|
|---|
| 1354 |
|
|---|
| 1355 | #if defined (QSPI1_V2_1L)
|
|---|
| 1356 | /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
|
|---|
| 1357 | AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
|
|---|
| 1358 | Change the following configuration of DMA peripheral
|
|---|
| 1359 | - Enable peripheral increment
|
|---|
| 1360 | - Disable memory increment
|
|---|
| 1361 | - Set DMA direction as peripheral to memory mode */
|
|---|
| 1362 |
|
|---|
| 1363 | /* Enable peripheral increment mode of the DMA */
|
|---|
| 1364 | hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
|
|---|
| 1365 |
|
|---|
| 1366 | /* Disable memory increment mode of the DMA */
|
|---|
| 1367 | hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
|
|---|
| 1368 |
|
|---|
| 1369 | /* Update peripheral/memory increment mode bits */
|
|---|
| 1370 | MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
|
|---|
| 1371 |
|
|---|
| 1372 | /* Configure the direction of the DMA */
|
|---|
| 1373 | hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
|---|
| 1374 | #else
|
|---|
| 1375 | /* Configure the direction of the DMA */
|
|---|
| 1376 | hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
|---|
| 1377 | #endif /* QSPI1_V2_1L */
|
|---|
| 1378 |
|
|---|
| 1379 | /* Update direction mode bit */
|
|---|
| 1380 | MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
|
|---|
| 1381 |
|
|---|
| 1382 | /* Enable the QSPI transmit DMA Channel */
|
|---|
| 1383 | if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)pData, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize) == HAL_OK)
|
|---|
| 1384 | {
|
|---|
| 1385 | /* Process unlocked */
|
|---|
| 1386 | __HAL_UNLOCK(hqspi);
|
|---|
| 1387 |
|
|---|
| 1388 | /* Enable the QSPI transfer error Interrupt */
|
|---|
| 1389 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
|
|---|
| 1390 |
|
|---|
| 1391 | /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
|
|---|
| 1392 | SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 1393 | }
|
|---|
| 1394 | else
|
|---|
| 1395 | {
|
|---|
| 1396 | status = HAL_ERROR;
|
|---|
| 1397 | hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
|
|---|
| 1398 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 1399 |
|
|---|
| 1400 | /* Process unlocked */
|
|---|
| 1401 | __HAL_UNLOCK(hqspi);
|
|---|
| 1402 | }
|
|---|
| 1403 | }
|
|---|
| 1404 | }
|
|---|
| 1405 | else
|
|---|
| 1406 | {
|
|---|
| 1407 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1408 | status = HAL_ERROR;
|
|---|
| 1409 |
|
|---|
| 1410 | /* Process unlocked */
|
|---|
| 1411 | __HAL_UNLOCK(hqspi);
|
|---|
| 1412 | }
|
|---|
| 1413 | }
|
|---|
| 1414 | else
|
|---|
| 1415 | {
|
|---|
| 1416 | status = HAL_BUSY;
|
|---|
| 1417 |
|
|---|
| 1418 | /* Process unlocked */
|
|---|
| 1419 | __HAL_UNLOCK(hqspi);
|
|---|
| 1420 | }
|
|---|
| 1421 |
|
|---|
| 1422 | return status;
|
|---|
| 1423 | }
|
|---|
| 1424 |
|
|---|
| 1425 | /**
|
|---|
| 1426 | * @brief Receive an amount of data in non-blocking mode with DMA.
|
|---|
| 1427 | * @param hqspi : QSPI handle
|
|---|
| 1428 | * @param pData : pointer to data buffer.
|
|---|
| 1429 | * @note This function is used only in Indirect Read Mode
|
|---|
| 1430 | * @note If DMA peripheral access is configured as halfword, the number
|
|---|
| 1431 | * of data and the fifo threshold should be aligned on halfword
|
|---|
| 1432 | * @note If DMA peripheral access is configured as word, the number
|
|---|
| 1433 | * of data and the fifo threshold should be aligned on word
|
|---|
| 1434 | * @retval HAL status
|
|---|
| 1435 | */
|
|---|
| 1436 | HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData)
|
|---|
| 1437 | {
|
|---|
| 1438 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 1439 | uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
|
|---|
| 1440 | uint32_t data_size = (READ_REG(hqspi->Instance->DLR) + 1U);
|
|---|
| 1441 |
|
|---|
| 1442 | /* Process locked */
|
|---|
| 1443 | __HAL_LOCK(hqspi);
|
|---|
| 1444 |
|
|---|
| 1445 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1446 | {
|
|---|
| 1447 | /* Clear the error code */
|
|---|
| 1448 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1449 |
|
|---|
| 1450 | if(pData != NULL )
|
|---|
| 1451 | {
|
|---|
| 1452 | /* Configure counters of the handle */
|
|---|
| 1453 | if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
|
|---|
| 1454 | {
|
|---|
| 1455 | hqspi->RxXferCount = data_size;
|
|---|
| 1456 | }
|
|---|
| 1457 | else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
|
|---|
| 1458 | {
|
|---|
| 1459 | if (((data_size % 2U) != 0U) || ((hqspi->Init.FifoThreshold % 2U) != 0U))
|
|---|
| 1460 | {
|
|---|
| 1461 | /* The number of data or the fifo threshold is not aligned on halfword
|
|---|
| 1462 | => no transfer possible with DMA peripheral access configured as halfword */
|
|---|
| 1463 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1464 | status = HAL_ERROR;
|
|---|
| 1465 |
|
|---|
| 1466 | /* Process unlocked */
|
|---|
| 1467 | __HAL_UNLOCK(hqspi);
|
|---|
| 1468 | }
|
|---|
| 1469 | else
|
|---|
| 1470 | {
|
|---|
| 1471 | hqspi->RxXferCount = (data_size >> 1U);
|
|---|
| 1472 | }
|
|---|
| 1473 | }
|
|---|
| 1474 | else if (hqspi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
|
|---|
| 1475 | {
|
|---|
| 1476 | if (((data_size % 4U) != 0U) || ((hqspi->Init.FifoThreshold % 4U) != 0U))
|
|---|
| 1477 | {
|
|---|
| 1478 | /* The number of data or the fifo threshold is not aligned on word
|
|---|
| 1479 | => no transfer possible with DMA peripheral access configured as word */
|
|---|
| 1480 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1481 | status = HAL_ERROR;
|
|---|
| 1482 |
|
|---|
| 1483 | /* Process unlocked */
|
|---|
| 1484 | __HAL_UNLOCK(hqspi);
|
|---|
| 1485 | }
|
|---|
| 1486 | else
|
|---|
| 1487 | {
|
|---|
| 1488 | hqspi->RxXferCount = (data_size >> 2U);
|
|---|
| 1489 | }
|
|---|
| 1490 | }
|
|---|
| 1491 | else
|
|---|
| 1492 | {
|
|---|
| 1493 | /* Nothing to do */
|
|---|
| 1494 | }
|
|---|
| 1495 |
|
|---|
| 1496 | if (status == HAL_OK)
|
|---|
| 1497 | {
|
|---|
| 1498 | /* Update state */
|
|---|
| 1499 | hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX;
|
|---|
| 1500 |
|
|---|
| 1501 | /* Clear interrupt */
|
|---|
| 1502 | __HAL_QSPI_CLEAR_FLAG(hqspi, (QSPI_FLAG_TE | QSPI_FLAG_TC));
|
|---|
| 1503 |
|
|---|
| 1504 | /* Configure size and pointer of the handle */
|
|---|
| 1505 | hqspi->RxXferSize = hqspi->RxXferCount;
|
|---|
| 1506 | hqspi->pRxBuffPtr = pData;
|
|---|
| 1507 |
|
|---|
| 1508 | /* Set the QSPI DMA transfer complete callback */
|
|---|
| 1509 | hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt;
|
|---|
| 1510 |
|
|---|
| 1511 | /* Set the QSPI DMA Half transfer complete callback */
|
|---|
| 1512 | hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt;
|
|---|
| 1513 |
|
|---|
| 1514 | /* Set the DMA error callback */
|
|---|
| 1515 | hqspi->hdma->XferErrorCallback = QSPI_DMAError;
|
|---|
| 1516 |
|
|---|
| 1517 | /* Clear the DMA abort callback */
|
|---|
| 1518 | hqspi->hdma->XferAbortCallback = NULL;
|
|---|
| 1519 |
|
|---|
| 1520 | #if defined (QSPI1_V2_1L)
|
|---|
| 1521 | /* Bug "ES0305 section 2.1.8 In some specific cases, DMA2 data corruption occurs when managing
|
|---|
| 1522 | AHB and APB2 peripherals in a concurrent way" Workaround Implementation:
|
|---|
| 1523 | Change the following configuration of DMA peripheral
|
|---|
| 1524 | - Enable peripheral increment
|
|---|
| 1525 | - Disable memory increment
|
|---|
| 1526 | - Set DMA direction as memory to peripheral mode
|
|---|
| 1527 | - 4 Extra words (32-bits) are added for read operation to guarantee
|
|---|
| 1528 | the last data is transferred from DMA FIFO to RAM memory */
|
|---|
| 1529 |
|
|---|
| 1530 | /* Enable peripheral increment of the DMA */
|
|---|
| 1531 | hqspi->hdma->Init.PeriphInc = DMA_PINC_ENABLE;
|
|---|
| 1532 |
|
|---|
| 1533 | /* Disable memory increment of the DMA */
|
|---|
| 1534 | hqspi->hdma->Init.MemInc = DMA_MINC_DISABLE;
|
|---|
| 1535 |
|
|---|
| 1536 | /* Update peripheral/memory increment mode bits */
|
|---|
| 1537 | MODIFY_REG(hqspi->hdma->Instance->CR, (DMA_SxCR_MINC | DMA_SxCR_PINC), (hqspi->hdma->Init.MemInc | hqspi->hdma->Init.PeriphInc));
|
|---|
| 1538 |
|
|---|
| 1539 | /* Configure the direction of the DMA */
|
|---|
| 1540 | hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
|---|
| 1541 |
|
|---|
| 1542 | /* 4 Extra words (32-bits) are needed for read operation to guarantee
|
|---|
| 1543 | the last data is transferred from DMA FIFO to RAM memory */
|
|---|
| 1544 | WRITE_REG(hqspi->Instance->DLR, (data_size - 1U + 16U));
|
|---|
| 1545 | #else
|
|---|
| 1546 | /* Configure the direction of the DMA */
|
|---|
| 1547 | hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
|---|
| 1548 | #endif
|
|---|
| 1549 | /* Update direction mode bit */
|
|---|
| 1550 | MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction);
|
|---|
| 1551 |
|
|---|
| 1552 | /* Enable the DMA Channel */
|
|---|
| 1553 | if (HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, (uint32_t)pData, hqspi->RxXferSize) == HAL_OK)
|
|---|
| 1554 | {
|
|---|
| 1555 | /* Configure QSPI: CCR register with functional as indirect read */
|
|---|
| 1556 | MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
|
|---|
| 1557 |
|
|---|
| 1558 | /* Start the transfer by re-writing the address in AR register */
|
|---|
| 1559 | WRITE_REG(hqspi->Instance->AR, addr_reg);
|
|---|
| 1560 |
|
|---|
| 1561 | /* Process unlocked */
|
|---|
| 1562 | __HAL_UNLOCK(hqspi);
|
|---|
| 1563 |
|
|---|
| 1564 | /* Enable the QSPI transfer error Interrupt */
|
|---|
| 1565 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE);
|
|---|
| 1566 |
|
|---|
| 1567 | /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */
|
|---|
| 1568 | SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 1569 | }
|
|---|
| 1570 | else
|
|---|
| 1571 | {
|
|---|
| 1572 | status = HAL_ERROR;
|
|---|
| 1573 | hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
|
|---|
| 1574 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 1575 |
|
|---|
| 1576 | /* Process unlocked */
|
|---|
| 1577 | __HAL_UNLOCK(hqspi);
|
|---|
| 1578 | }
|
|---|
| 1579 | }
|
|---|
| 1580 | }
|
|---|
| 1581 | else
|
|---|
| 1582 | {
|
|---|
| 1583 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_PARAM;
|
|---|
| 1584 | status = HAL_ERROR;
|
|---|
| 1585 |
|
|---|
| 1586 | /* Process unlocked */
|
|---|
| 1587 | __HAL_UNLOCK(hqspi);
|
|---|
| 1588 | }
|
|---|
| 1589 | }
|
|---|
| 1590 | else
|
|---|
| 1591 | {
|
|---|
| 1592 | status = HAL_BUSY;
|
|---|
| 1593 |
|
|---|
| 1594 | /* Process unlocked */
|
|---|
| 1595 | __HAL_UNLOCK(hqspi);
|
|---|
| 1596 | }
|
|---|
| 1597 |
|
|---|
| 1598 | return status;
|
|---|
| 1599 | }
|
|---|
| 1600 |
|
|---|
| 1601 | /**
|
|---|
| 1602 | * @brief Configure the QSPI Automatic Polling Mode in blocking mode.
|
|---|
| 1603 | * @param hqspi : QSPI handle
|
|---|
| 1604 | * @param cmd : structure that contains the command configuration information.
|
|---|
| 1605 | * @param cfg : structure that contains the polling configuration information.
|
|---|
| 1606 | * @param Timeout : Timeout duration
|
|---|
| 1607 | * @note This function is used only in Automatic Polling Mode
|
|---|
| 1608 | * @retval HAL status
|
|---|
| 1609 | */
|
|---|
| 1610 | HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
|
|---|
| 1611 | {
|
|---|
| 1612 | HAL_StatusTypeDef status;
|
|---|
| 1613 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 1614 |
|
|---|
| 1615 | /* Check the parameters */
|
|---|
| 1616 | assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
|
|---|
| 1617 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 1618 | {
|
|---|
| 1619 | assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
|
|---|
| 1620 | }
|
|---|
| 1621 |
|
|---|
| 1622 | assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
|
|---|
| 1623 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 1624 | {
|
|---|
| 1625 | assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
|
|---|
| 1626 | }
|
|---|
| 1627 |
|
|---|
| 1628 | assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
|
|---|
| 1629 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 1630 | {
|
|---|
| 1631 | assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
|
|---|
| 1632 | }
|
|---|
| 1633 |
|
|---|
| 1634 | assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
|
|---|
| 1635 | assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
|
|---|
| 1636 |
|
|---|
| 1637 | assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
|
|---|
| 1638 | assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
|
|---|
| 1639 | assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
|
|---|
| 1640 |
|
|---|
| 1641 | assert_param(IS_QSPI_INTERVAL(cfg->Interval));
|
|---|
| 1642 | assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
|
|---|
| 1643 | assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
|
|---|
| 1644 |
|
|---|
| 1645 | /* Process locked */
|
|---|
| 1646 | __HAL_LOCK(hqspi);
|
|---|
| 1647 |
|
|---|
| 1648 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1649 | {
|
|---|
| 1650 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1651 |
|
|---|
| 1652 | /* Update state */
|
|---|
| 1653 | hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
|
|---|
| 1654 |
|
|---|
| 1655 | /* Wait till BUSY flag reset */
|
|---|
| 1656 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, Timeout);
|
|---|
| 1657 |
|
|---|
| 1658 | if (status == HAL_OK)
|
|---|
| 1659 | {
|
|---|
| 1660 | /* Configure QSPI: PSMAR register with the status match value */
|
|---|
| 1661 | WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
|
|---|
| 1662 |
|
|---|
| 1663 | /* Configure QSPI: PSMKR register with the status mask value */
|
|---|
| 1664 | WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
|
|---|
| 1665 |
|
|---|
| 1666 | /* Configure QSPI: PIR register with the interval value */
|
|---|
| 1667 | WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
|
|---|
| 1668 |
|
|---|
| 1669 | /* Configure QSPI: CR register with Match mode and Automatic stop enabled
|
|---|
| 1670 | (otherwise there will be an infinite loop in blocking mode) */
|
|---|
| 1671 | MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
|
|---|
| 1672 | (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE));
|
|---|
| 1673 |
|
|---|
| 1674 | /* Call the configuration function */
|
|---|
| 1675 | cmd->NbData = cfg->StatusBytesSize;
|
|---|
| 1676 | QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
|
|---|
| 1677 |
|
|---|
| 1678 | /* Wait until SM flag is set to go back in idle state */
|
|---|
| 1679 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, tickstart, Timeout);
|
|---|
| 1680 |
|
|---|
| 1681 | if (status == HAL_OK)
|
|---|
| 1682 | {
|
|---|
| 1683 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM);
|
|---|
| 1684 |
|
|---|
| 1685 | /* Update state */
|
|---|
| 1686 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 1687 | }
|
|---|
| 1688 | }
|
|---|
| 1689 | }
|
|---|
| 1690 | else
|
|---|
| 1691 | {
|
|---|
| 1692 | status = HAL_BUSY;
|
|---|
| 1693 | }
|
|---|
| 1694 |
|
|---|
| 1695 | /* Process unlocked */
|
|---|
| 1696 | __HAL_UNLOCK(hqspi);
|
|---|
| 1697 |
|
|---|
| 1698 | /* Return function status */
|
|---|
| 1699 | return status;
|
|---|
| 1700 | }
|
|---|
| 1701 |
|
|---|
| 1702 | /**
|
|---|
| 1703 | * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode.
|
|---|
| 1704 | * @param hqspi : QSPI handle
|
|---|
| 1705 | * @param cmd : structure that contains the command configuration information.
|
|---|
| 1706 | * @param cfg : structure that contains the polling configuration information.
|
|---|
| 1707 | * @note This function is used only in Automatic Polling Mode
|
|---|
| 1708 | * @retval HAL status
|
|---|
| 1709 | */
|
|---|
| 1710 | HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg)
|
|---|
| 1711 | {
|
|---|
| 1712 | HAL_StatusTypeDef status;
|
|---|
| 1713 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 1714 |
|
|---|
| 1715 | /* Check the parameters */
|
|---|
| 1716 | assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
|
|---|
| 1717 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 1718 | {
|
|---|
| 1719 | assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
|
|---|
| 1720 | }
|
|---|
| 1721 |
|
|---|
| 1722 | assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
|
|---|
| 1723 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 1724 | {
|
|---|
| 1725 | assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
|
|---|
| 1726 | }
|
|---|
| 1727 |
|
|---|
| 1728 | assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
|
|---|
| 1729 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 1730 | {
|
|---|
| 1731 | assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
|
|---|
| 1732 | }
|
|---|
| 1733 |
|
|---|
| 1734 | assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
|
|---|
| 1735 | assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
|
|---|
| 1736 |
|
|---|
| 1737 | assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
|
|---|
| 1738 | assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
|
|---|
| 1739 | assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
|
|---|
| 1740 |
|
|---|
| 1741 | assert_param(IS_QSPI_INTERVAL(cfg->Interval));
|
|---|
| 1742 | assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize));
|
|---|
| 1743 | assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode));
|
|---|
| 1744 | assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
|
|---|
| 1745 |
|
|---|
| 1746 | /* Process locked */
|
|---|
| 1747 | __HAL_LOCK(hqspi);
|
|---|
| 1748 |
|
|---|
| 1749 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1750 | {
|
|---|
| 1751 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1752 |
|
|---|
| 1753 | /* Update state */
|
|---|
| 1754 | hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING;
|
|---|
| 1755 |
|
|---|
| 1756 | /* Wait till BUSY flag reset */
|
|---|
| 1757 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
|
|---|
| 1758 |
|
|---|
| 1759 | if (status == HAL_OK)
|
|---|
| 1760 | {
|
|---|
| 1761 | /* Configure QSPI: PSMAR register with the status match value */
|
|---|
| 1762 | WRITE_REG(hqspi->Instance->PSMAR, cfg->Match);
|
|---|
| 1763 |
|
|---|
| 1764 | /* Configure QSPI: PSMKR register with the status mask value */
|
|---|
| 1765 | WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask);
|
|---|
| 1766 |
|
|---|
| 1767 | /* Configure QSPI: PIR register with the interval value */
|
|---|
| 1768 | WRITE_REG(hqspi->Instance->PIR, cfg->Interval);
|
|---|
| 1769 |
|
|---|
| 1770 | /* Configure QSPI: CR register with Match mode and Automatic stop mode */
|
|---|
| 1771 | MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS),
|
|---|
| 1772 | (cfg->MatchMode | cfg->AutomaticStop));
|
|---|
| 1773 |
|
|---|
| 1774 | /* Clear interrupt */
|
|---|
| 1775 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE | QSPI_FLAG_SM);
|
|---|
| 1776 |
|
|---|
| 1777 | /* Call the configuration function */
|
|---|
| 1778 | cmd->NbData = cfg->StatusBytesSize;
|
|---|
| 1779 | QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING);
|
|---|
| 1780 |
|
|---|
| 1781 | /* Process unlocked */
|
|---|
| 1782 | __HAL_UNLOCK(hqspi);
|
|---|
| 1783 |
|
|---|
| 1784 | /* Enable the QSPI Transfer Error and status match Interrupt */
|
|---|
| 1785 | __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_SM | QSPI_IT_TE));
|
|---|
| 1786 |
|
|---|
| 1787 | }
|
|---|
| 1788 | else
|
|---|
| 1789 | {
|
|---|
| 1790 | /* Process unlocked */
|
|---|
| 1791 | __HAL_UNLOCK(hqspi);
|
|---|
| 1792 | }
|
|---|
| 1793 | }
|
|---|
| 1794 | else
|
|---|
| 1795 | {
|
|---|
| 1796 | status = HAL_BUSY;
|
|---|
| 1797 |
|
|---|
| 1798 | /* Process unlocked */
|
|---|
| 1799 | __HAL_UNLOCK(hqspi);
|
|---|
| 1800 | }
|
|---|
| 1801 |
|
|---|
| 1802 | /* Return function status */
|
|---|
| 1803 | return status;
|
|---|
| 1804 | }
|
|---|
| 1805 |
|
|---|
| 1806 | /**
|
|---|
| 1807 | * @brief Configure the Memory Mapped mode.
|
|---|
| 1808 | * @param hqspi : QSPI handle
|
|---|
| 1809 | * @param cmd : structure that contains the command configuration information.
|
|---|
| 1810 | * @param cfg : structure that contains the memory mapped configuration information.
|
|---|
| 1811 | * @note This function is used only in Memory mapped Mode
|
|---|
| 1812 | * @retval HAL status
|
|---|
| 1813 | */
|
|---|
| 1814 | HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
|
|---|
| 1815 | {
|
|---|
| 1816 | HAL_StatusTypeDef status;
|
|---|
| 1817 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 1818 |
|
|---|
| 1819 | /* Check the parameters */
|
|---|
| 1820 | assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode));
|
|---|
| 1821 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 1822 | {
|
|---|
| 1823 | assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction));
|
|---|
| 1824 | }
|
|---|
| 1825 |
|
|---|
| 1826 | assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode));
|
|---|
| 1827 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 1828 | {
|
|---|
| 1829 | assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize));
|
|---|
| 1830 | }
|
|---|
| 1831 |
|
|---|
| 1832 | assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode));
|
|---|
| 1833 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 1834 | {
|
|---|
| 1835 | assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize));
|
|---|
| 1836 | }
|
|---|
| 1837 |
|
|---|
| 1838 | assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles));
|
|---|
| 1839 | assert_param(IS_QSPI_DATA_MODE(cmd->DataMode));
|
|---|
| 1840 |
|
|---|
| 1841 | assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode));
|
|---|
| 1842 | assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle));
|
|---|
| 1843 | assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode));
|
|---|
| 1844 |
|
|---|
| 1845 | assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
|
|---|
| 1846 |
|
|---|
| 1847 | /* Process locked */
|
|---|
| 1848 | __HAL_LOCK(hqspi);
|
|---|
| 1849 |
|
|---|
| 1850 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 1851 | {
|
|---|
| 1852 | hqspi->ErrorCode = HAL_QSPI_ERROR_NONE;
|
|---|
| 1853 |
|
|---|
| 1854 | /* Update state */
|
|---|
| 1855 | hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED;
|
|---|
| 1856 |
|
|---|
| 1857 | /* Wait till BUSY flag reset */
|
|---|
| 1858 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
|
|---|
| 1859 |
|
|---|
| 1860 | if (status == HAL_OK)
|
|---|
| 1861 | {
|
|---|
| 1862 | /* Configure QSPI: CR register with timeout counter enable */
|
|---|
| 1863 | MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation);
|
|---|
| 1864 |
|
|---|
| 1865 | if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE)
|
|---|
| 1866 | {
|
|---|
| 1867 | assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
|
|---|
| 1868 |
|
|---|
| 1869 | /* Configure QSPI: LPTR register with the low-power timeout value */
|
|---|
| 1870 | WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod);
|
|---|
| 1871 |
|
|---|
| 1872 | /* Clear interrupt */
|
|---|
| 1873 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO);
|
|---|
| 1874 |
|
|---|
| 1875 | /* Enable the QSPI TimeOut Interrupt */
|
|---|
| 1876 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO);
|
|---|
| 1877 | }
|
|---|
| 1878 |
|
|---|
| 1879 | /* Call the configuration function */
|
|---|
| 1880 | QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED);
|
|---|
| 1881 | }
|
|---|
| 1882 | }
|
|---|
| 1883 | else
|
|---|
| 1884 | {
|
|---|
| 1885 | status = HAL_BUSY;
|
|---|
| 1886 | }
|
|---|
| 1887 |
|
|---|
| 1888 | /* Process unlocked */
|
|---|
| 1889 | __HAL_UNLOCK(hqspi);
|
|---|
| 1890 |
|
|---|
| 1891 | /* Return function status */
|
|---|
| 1892 | return status;
|
|---|
| 1893 | }
|
|---|
| 1894 |
|
|---|
| 1895 | /**
|
|---|
| 1896 | * @brief Transfer Error callback.
|
|---|
| 1897 | * @param hqspi : QSPI handle
|
|---|
| 1898 | * @retval None
|
|---|
| 1899 | */
|
|---|
| 1900 | __weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1901 | {
|
|---|
| 1902 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1903 | UNUSED(hqspi);
|
|---|
| 1904 |
|
|---|
| 1905 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 1906 | the HAL_QSPI_ErrorCallback could be implemented in the user file
|
|---|
| 1907 | */
|
|---|
| 1908 | }
|
|---|
| 1909 |
|
|---|
| 1910 | /**
|
|---|
| 1911 | * @brief Abort completed callback.
|
|---|
| 1912 | * @param hqspi : QSPI handle
|
|---|
| 1913 | * @retval None
|
|---|
| 1914 | */
|
|---|
| 1915 | __weak void HAL_QSPI_AbortCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1916 | {
|
|---|
| 1917 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1918 | UNUSED(hqspi);
|
|---|
| 1919 |
|
|---|
| 1920 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1921 | the HAL_QSPI_AbortCpltCallback could be implemented in the user file
|
|---|
| 1922 | */
|
|---|
| 1923 | }
|
|---|
| 1924 |
|
|---|
| 1925 | /**
|
|---|
| 1926 | * @brief Command completed callback.
|
|---|
| 1927 | * @param hqspi : QSPI handle
|
|---|
| 1928 | * @retval None
|
|---|
| 1929 | */
|
|---|
| 1930 | __weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1931 | {
|
|---|
| 1932 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1933 | UNUSED(hqspi);
|
|---|
| 1934 |
|
|---|
| 1935 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1936 | the HAL_QSPI_CmdCpltCallback could be implemented in the user file
|
|---|
| 1937 | */
|
|---|
| 1938 | }
|
|---|
| 1939 |
|
|---|
| 1940 | /**
|
|---|
| 1941 | * @brief Rx Transfer completed callback.
|
|---|
| 1942 | * @param hqspi : QSPI handle
|
|---|
| 1943 | * @retval None
|
|---|
| 1944 | */
|
|---|
| 1945 | __weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1946 | {
|
|---|
| 1947 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1948 | UNUSED(hqspi);
|
|---|
| 1949 |
|
|---|
| 1950 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1951 | the HAL_QSPI_RxCpltCallback could be implemented in the user file
|
|---|
| 1952 | */
|
|---|
| 1953 | }
|
|---|
| 1954 |
|
|---|
| 1955 | /**
|
|---|
| 1956 | * @brief Tx Transfer completed callback.
|
|---|
| 1957 | * @param hqspi : QSPI handle
|
|---|
| 1958 | * @retval None
|
|---|
| 1959 | */
|
|---|
| 1960 | __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1961 | {
|
|---|
| 1962 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1963 | UNUSED(hqspi);
|
|---|
| 1964 |
|
|---|
| 1965 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1966 | the HAL_QSPI_TxCpltCallback could be implemented in the user file
|
|---|
| 1967 | */
|
|---|
| 1968 | }
|
|---|
| 1969 |
|
|---|
| 1970 | /**
|
|---|
| 1971 | * @brief Rx Half Transfer completed callback.
|
|---|
| 1972 | * @param hqspi : QSPI handle
|
|---|
| 1973 | * @retval None
|
|---|
| 1974 | */
|
|---|
| 1975 | __weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1976 | {
|
|---|
| 1977 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1978 | UNUSED(hqspi);
|
|---|
| 1979 |
|
|---|
| 1980 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1981 | the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file
|
|---|
| 1982 | */
|
|---|
| 1983 | }
|
|---|
| 1984 |
|
|---|
| 1985 | /**
|
|---|
| 1986 | * @brief Tx Half Transfer completed callback.
|
|---|
| 1987 | * @param hqspi : QSPI handle
|
|---|
| 1988 | * @retval None
|
|---|
| 1989 | */
|
|---|
| 1990 | __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 1991 | {
|
|---|
| 1992 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 1993 | UNUSED(hqspi);
|
|---|
| 1994 |
|
|---|
| 1995 | /* NOTE: This function should not be modified, when the callback is needed,
|
|---|
| 1996 | the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file
|
|---|
| 1997 | */
|
|---|
| 1998 | }
|
|---|
| 1999 |
|
|---|
| 2000 | /**
|
|---|
| 2001 | * @brief FIFO Threshold callback.
|
|---|
| 2002 | * @param hqspi : QSPI handle
|
|---|
| 2003 | * @retval None
|
|---|
| 2004 | */
|
|---|
| 2005 | __weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2006 | {
|
|---|
| 2007 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 2008 | UNUSED(hqspi);
|
|---|
| 2009 |
|
|---|
| 2010 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 2011 | the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file
|
|---|
| 2012 | */
|
|---|
| 2013 | }
|
|---|
| 2014 |
|
|---|
| 2015 | /**
|
|---|
| 2016 | * @brief Status Match callback.
|
|---|
| 2017 | * @param hqspi : QSPI handle
|
|---|
| 2018 | * @retval None
|
|---|
| 2019 | */
|
|---|
| 2020 | __weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2021 | {
|
|---|
| 2022 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 2023 | UNUSED(hqspi);
|
|---|
| 2024 |
|
|---|
| 2025 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 2026 | the HAL_QSPI_StatusMatchCallback could be implemented in the user file
|
|---|
| 2027 | */
|
|---|
| 2028 | }
|
|---|
| 2029 |
|
|---|
| 2030 | /**
|
|---|
| 2031 | * @brief Timeout callback.
|
|---|
| 2032 | * @param hqspi : QSPI handle
|
|---|
| 2033 | * @retval None
|
|---|
| 2034 | */
|
|---|
| 2035 | __weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2036 | {
|
|---|
| 2037 | /* Prevent unused argument(s) compilation warning */
|
|---|
| 2038 | UNUSED(hqspi);
|
|---|
| 2039 |
|
|---|
| 2040 | /* NOTE : This function should not be modified, when the callback is needed,
|
|---|
| 2041 | the HAL_QSPI_TimeOutCallback could be implemented in the user file
|
|---|
| 2042 | */
|
|---|
| 2043 | }
|
|---|
| 2044 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 2045 | /**
|
|---|
| 2046 | * @brief Register a User QSPI Callback
|
|---|
| 2047 | * To be used instead of the weak (surcharged) predefined callback
|
|---|
| 2048 | * @param hqspi : QSPI handle
|
|---|
| 2049 | * @param CallbackId : ID of the callback to be registered
|
|---|
| 2050 | * This parameter can be one of the following values:
|
|---|
| 2051 | * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
|
|---|
| 2052 | * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
|
|---|
| 2053 | * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
|
|---|
| 2054 | * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
|
|---|
| 2055 | * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
|
|---|
| 2056 | * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
|
|---|
| 2057 | * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
|
|---|
| 2058 | * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
|
|---|
| 2059 | * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
|
|---|
| 2060 | * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
|
|---|
| 2061 | * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
|
|---|
| 2062 | * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
|
|---|
| 2063 | * @param pCallback : pointer to the Callback function
|
|---|
| 2064 | * @retval status
|
|---|
| 2065 | */
|
|---|
| 2066 | HAL_StatusTypeDef HAL_QSPI_RegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId, pQSPI_CallbackTypeDef pCallback)
|
|---|
| 2067 | {
|
|---|
| 2068 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2069 |
|
|---|
| 2070 | if(pCallback == NULL)
|
|---|
| 2071 | {
|
|---|
| 2072 | /* Update the error code */
|
|---|
| 2073 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2074 | return HAL_ERROR;
|
|---|
| 2075 | }
|
|---|
| 2076 |
|
|---|
| 2077 | /* Process locked */
|
|---|
| 2078 | __HAL_LOCK(hqspi);
|
|---|
| 2079 |
|
|---|
| 2080 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 2081 | {
|
|---|
| 2082 | switch (CallbackId)
|
|---|
| 2083 | {
|
|---|
| 2084 | case HAL_QSPI_ERROR_CB_ID :
|
|---|
| 2085 | hqspi->ErrorCallback = pCallback;
|
|---|
| 2086 | break;
|
|---|
| 2087 | case HAL_QSPI_ABORT_CB_ID :
|
|---|
| 2088 | hqspi->AbortCpltCallback = pCallback;
|
|---|
| 2089 | break;
|
|---|
| 2090 | case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
|
|---|
| 2091 | hqspi->FifoThresholdCallback = pCallback;
|
|---|
| 2092 | break;
|
|---|
| 2093 | case HAL_QSPI_CMD_CPLT_CB_ID :
|
|---|
| 2094 | hqspi->CmdCpltCallback = pCallback;
|
|---|
| 2095 | break;
|
|---|
| 2096 | case HAL_QSPI_RX_CPLT_CB_ID :
|
|---|
| 2097 | hqspi->RxCpltCallback = pCallback;
|
|---|
| 2098 | break;
|
|---|
| 2099 | case HAL_QSPI_TX_CPLT_CB_ID :
|
|---|
| 2100 | hqspi->TxCpltCallback = pCallback;
|
|---|
| 2101 | break;
|
|---|
| 2102 | case HAL_QSPI_RX_HALF_CPLT_CB_ID :
|
|---|
| 2103 | hqspi->RxHalfCpltCallback = pCallback;
|
|---|
| 2104 | break;
|
|---|
| 2105 | case HAL_QSPI_TX_HALF_CPLT_CB_ID :
|
|---|
| 2106 | hqspi->TxHalfCpltCallback = pCallback;
|
|---|
| 2107 | break;
|
|---|
| 2108 | case HAL_QSPI_STATUS_MATCH_CB_ID :
|
|---|
| 2109 | hqspi->StatusMatchCallback = pCallback;
|
|---|
| 2110 | break;
|
|---|
| 2111 | case HAL_QSPI_TIMEOUT_CB_ID :
|
|---|
| 2112 | hqspi->TimeOutCallback = pCallback;
|
|---|
| 2113 | break;
|
|---|
| 2114 | case HAL_QSPI_MSP_INIT_CB_ID :
|
|---|
| 2115 | hqspi->MspInitCallback = pCallback;
|
|---|
| 2116 | break;
|
|---|
| 2117 | case HAL_QSPI_MSP_DEINIT_CB_ID :
|
|---|
| 2118 | hqspi->MspDeInitCallback = pCallback;
|
|---|
| 2119 | break;
|
|---|
| 2120 | default :
|
|---|
| 2121 | /* Update the error code */
|
|---|
| 2122 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2123 | /* update return status */
|
|---|
| 2124 | status = HAL_ERROR;
|
|---|
| 2125 | break;
|
|---|
| 2126 | }
|
|---|
| 2127 | }
|
|---|
| 2128 | else if (hqspi->State == HAL_QSPI_STATE_RESET)
|
|---|
| 2129 | {
|
|---|
| 2130 | switch (CallbackId)
|
|---|
| 2131 | {
|
|---|
| 2132 | case HAL_QSPI_MSP_INIT_CB_ID :
|
|---|
| 2133 | hqspi->MspInitCallback = pCallback;
|
|---|
| 2134 | break;
|
|---|
| 2135 | case HAL_QSPI_MSP_DEINIT_CB_ID :
|
|---|
| 2136 | hqspi->MspDeInitCallback = pCallback;
|
|---|
| 2137 | break;
|
|---|
| 2138 | default :
|
|---|
| 2139 | /* Update the error code */
|
|---|
| 2140 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2141 | /* update return status */
|
|---|
| 2142 | status = HAL_ERROR;
|
|---|
| 2143 | break;
|
|---|
| 2144 | }
|
|---|
| 2145 | }
|
|---|
| 2146 | else
|
|---|
| 2147 | {
|
|---|
| 2148 | /* Update the error code */
|
|---|
| 2149 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2150 | /* update return status */
|
|---|
| 2151 | status = HAL_ERROR;
|
|---|
| 2152 | }
|
|---|
| 2153 |
|
|---|
| 2154 | /* Release Lock */
|
|---|
| 2155 | __HAL_UNLOCK(hqspi);
|
|---|
| 2156 | return status;
|
|---|
| 2157 | }
|
|---|
| 2158 |
|
|---|
| 2159 | /**
|
|---|
| 2160 | * @brief Unregister a User QSPI Callback
|
|---|
| 2161 | * QSPI Callback is redirected to the weak (surcharged) predefined callback
|
|---|
| 2162 | * @param hqspi : QSPI handle
|
|---|
| 2163 | * @param CallbackId : ID of the callback to be unregistered
|
|---|
| 2164 | * This parameter can be one of the following values:
|
|---|
| 2165 | * @arg @ref HAL_QSPI_ERROR_CB_ID QSPI Error Callback ID
|
|---|
| 2166 | * @arg @ref HAL_QSPI_ABORT_CB_ID QSPI Abort Callback ID
|
|---|
| 2167 | * @arg @ref HAL_QSPI_FIFO_THRESHOLD_CB_ID QSPI FIFO Threshold Callback ID
|
|---|
| 2168 | * @arg @ref HAL_QSPI_CMD_CPLT_CB_ID QSPI Command Complete Callback ID
|
|---|
| 2169 | * @arg @ref HAL_QSPI_RX_CPLT_CB_ID QSPI Rx Complete Callback ID
|
|---|
| 2170 | * @arg @ref HAL_QSPI_TX_CPLT_CB_ID QSPI Tx Complete Callback ID
|
|---|
| 2171 | * @arg @ref HAL_QSPI_RX_HALF_CPLT_CB_ID QSPI Rx Half Complete Callback ID
|
|---|
| 2172 | * @arg @ref HAL_QSPI_TX_HALF_CPLT_CB_ID QSPI Tx Half Complete Callback ID
|
|---|
| 2173 | * @arg @ref HAL_QSPI_STATUS_MATCH_CB_ID QSPI Status Match Callback ID
|
|---|
| 2174 | * @arg @ref HAL_QSPI_TIMEOUT_CB_ID QSPI Timeout Callback ID
|
|---|
| 2175 | * @arg @ref HAL_QSPI_MSP_INIT_CB_ID QSPI MspInit callback ID
|
|---|
| 2176 | * @arg @ref HAL_QSPI_MSP_DEINIT_CB_ID QSPI MspDeInit callback ID
|
|---|
| 2177 | * @retval status
|
|---|
| 2178 | */
|
|---|
| 2179 | HAL_StatusTypeDef HAL_QSPI_UnRegisterCallback (QSPI_HandleTypeDef *hqspi, HAL_QSPI_CallbackIDTypeDef CallbackId)
|
|---|
| 2180 | {
|
|---|
| 2181 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2182 |
|
|---|
| 2183 | /* Process locked */
|
|---|
| 2184 | __HAL_LOCK(hqspi);
|
|---|
| 2185 |
|
|---|
| 2186 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 2187 | {
|
|---|
| 2188 | switch (CallbackId)
|
|---|
| 2189 | {
|
|---|
| 2190 | case HAL_QSPI_ERROR_CB_ID :
|
|---|
| 2191 | hqspi->ErrorCallback = HAL_QSPI_ErrorCallback;
|
|---|
| 2192 | break;
|
|---|
| 2193 | case HAL_QSPI_ABORT_CB_ID :
|
|---|
| 2194 | hqspi->AbortCpltCallback = HAL_QSPI_AbortCpltCallback;
|
|---|
| 2195 | break;
|
|---|
| 2196 | case HAL_QSPI_FIFO_THRESHOLD_CB_ID :
|
|---|
| 2197 | hqspi->FifoThresholdCallback = HAL_QSPI_FifoThresholdCallback;
|
|---|
| 2198 | break;
|
|---|
| 2199 | case HAL_QSPI_CMD_CPLT_CB_ID :
|
|---|
| 2200 | hqspi->CmdCpltCallback = HAL_QSPI_CmdCpltCallback;
|
|---|
| 2201 | break;
|
|---|
| 2202 | case HAL_QSPI_RX_CPLT_CB_ID :
|
|---|
| 2203 | hqspi->RxCpltCallback = HAL_QSPI_RxCpltCallback;
|
|---|
| 2204 | break;
|
|---|
| 2205 | case HAL_QSPI_TX_CPLT_CB_ID :
|
|---|
| 2206 | hqspi->TxCpltCallback = HAL_QSPI_TxCpltCallback;
|
|---|
| 2207 | break;
|
|---|
| 2208 | case HAL_QSPI_RX_HALF_CPLT_CB_ID :
|
|---|
| 2209 | hqspi->RxHalfCpltCallback = HAL_QSPI_RxHalfCpltCallback;
|
|---|
| 2210 | break;
|
|---|
| 2211 | case HAL_QSPI_TX_HALF_CPLT_CB_ID :
|
|---|
| 2212 | hqspi->TxHalfCpltCallback = HAL_QSPI_TxHalfCpltCallback;
|
|---|
| 2213 | break;
|
|---|
| 2214 | case HAL_QSPI_STATUS_MATCH_CB_ID :
|
|---|
| 2215 | hqspi->StatusMatchCallback = HAL_QSPI_StatusMatchCallback;
|
|---|
| 2216 | break;
|
|---|
| 2217 | case HAL_QSPI_TIMEOUT_CB_ID :
|
|---|
| 2218 | hqspi->TimeOutCallback = HAL_QSPI_TimeOutCallback;
|
|---|
| 2219 | break;
|
|---|
| 2220 | case HAL_QSPI_MSP_INIT_CB_ID :
|
|---|
| 2221 | hqspi->MspInitCallback = HAL_QSPI_MspInit;
|
|---|
| 2222 | break;
|
|---|
| 2223 | case HAL_QSPI_MSP_DEINIT_CB_ID :
|
|---|
| 2224 | hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
|
|---|
| 2225 | break;
|
|---|
| 2226 | default :
|
|---|
| 2227 | /* Update the error code */
|
|---|
| 2228 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2229 | /* update return status */
|
|---|
| 2230 | status = HAL_ERROR;
|
|---|
| 2231 | break;
|
|---|
| 2232 | }
|
|---|
| 2233 | }
|
|---|
| 2234 | else if (hqspi->State == HAL_QSPI_STATE_RESET)
|
|---|
| 2235 | {
|
|---|
| 2236 | switch (CallbackId)
|
|---|
| 2237 | {
|
|---|
| 2238 | case HAL_QSPI_MSP_INIT_CB_ID :
|
|---|
| 2239 | hqspi->MspInitCallback = HAL_QSPI_MspInit;
|
|---|
| 2240 | break;
|
|---|
| 2241 | case HAL_QSPI_MSP_DEINIT_CB_ID :
|
|---|
| 2242 | hqspi->MspDeInitCallback = HAL_QSPI_MspDeInit;
|
|---|
| 2243 | break;
|
|---|
| 2244 | default :
|
|---|
| 2245 | /* Update the error code */
|
|---|
| 2246 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2247 | /* update return status */
|
|---|
| 2248 | status = HAL_ERROR;
|
|---|
| 2249 | break;
|
|---|
| 2250 | }
|
|---|
| 2251 | }
|
|---|
| 2252 | else
|
|---|
| 2253 | {
|
|---|
| 2254 | /* Update the error code */
|
|---|
| 2255 | hqspi->ErrorCode |= HAL_QSPI_ERROR_INVALID_CALLBACK;
|
|---|
| 2256 | /* update return status */
|
|---|
| 2257 | status = HAL_ERROR;
|
|---|
| 2258 | }
|
|---|
| 2259 |
|
|---|
| 2260 | /* Release Lock */
|
|---|
| 2261 | __HAL_UNLOCK(hqspi);
|
|---|
| 2262 | return status;
|
|---|
| 2263 | }
|
|---|
| 2264 | #endif
|
|---|
| 2265 |
|
|---|
| 2266 | /**
|
|---|
| 2267 | * @}
|
|---|
| 2268 | */
|
|---|
| 2269 |
|
|---|
| 2270 | /** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions
|
|---|
| 2271 | * @brief QSPI control and State functions
|
|---|
| 2272 | *
|
|---|
| 2273 | @verbatim
|
|---|
| 2274 | ===============================================================================
|
|---|
| 2275 | ##### Peripheral Control and State functions #####
|
|---|
| 2276 | ===============================================================================
|
|---|
| 2277 | [..]
|
|---|
| 2278 | This subsection provides a set of functions allowing to :
|
|---|
| 2279 | (+) Check in run-time the state of the driver.
|
|---|
| 2280 | (+) Check the error code set during last operation.
|
|---|
| 2281 | (+) Abort any operation.
|
|---|
| 2282 |
|
|---|
| 2283 |
|
|---|
| 2284 | @endverbatim
|
|---|
| 2285 | * @{
|
|---|
| 2286 | */
|
|---|
| 2287 |
|
|---|
| 2288 | /**
|
|---|
| 2289 | * @brief Return the QSPI handle state.
|
|---|
| 2290 | * @param hqspi : QSPI handle
|
|---|
| 2291 | * @retval HAL state
|
|---|
| 2292 | */
|
|---|
| 2293 | HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2294 | {
|
|---|
| 2295 | /* Return QSPI handle state */
|
|---|
| 2296 | return hqspi->State;
|
|---|
| 2297 | }
|
|---|
| 2298 |
|
|---|
| 2299 | /**
|
|---|
| 2300 | * @brief Return the QSPI error code.
|
|---|
| 2301 | * @param hqspi : QSPI handle
|
|---|
| 2302 | * @retval QSPI Error Code
|
|---|
| 2303 | */
|
|---|
| 2304 | uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2305 | {
|
|---|
| 2306 | return hqspi->ErrorCode;
|
|---|
| 2307 | }
|
|---|
| 2308 |
|
|---|
| 2309 | /**
|
|---|
| 2310 | * @brief Abort the current transmission.
|
|---|
| 2311 | * @param hqspi : QSPI handle
|
|---|
| 2312 | * @retval HAL status
|
|---|
| 2313 | */
|
|---|
| 2314 | HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2315 | {
|
|---|
| 2316 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2317 | uint32_t tickstart = HAL_GetTick();
|
|---|
| 2318 |
|
|---|
| 2319 | /* Check if the state is in one of the busy states */
|
|---|
| 2320 | if (((uint32_t)hqspi->State & 0x2U) != 0U)
|
|---|
| 2321 | {
|
|---|
| 2322 | /* Process unlocked */
|
|---|
| 2323 | __HAL_UNLOCK(hqspi);
|
|---|
| 2324 |
|
|---|
| 2325 | if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
|
|---|
| 2326 | {
|
|---|
| 2327 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 2328 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 2329 |
|
|---|
| 2330 | /* Abort DMA channel */
|
|---|
| 2331 | status = HAL_DMA_Abort(hqspi->hdma);
|
|---|
| 2332 | if(status != HAL_OK)
|
|---|
| 2333 | {
|
|---|
| 2334 | hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
|
|---|
| 2335 | }
|
|---|
| 2336 | }
|
|---|
| 2337 |
|
|---|
| 2338 | /* Configure QSPI: CR register with Abort request */
|
|---|
| 2339 | SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
|
|---|
| 2340 |
|
|---|
| 2341 | /* Wait until TC flag is set to go back in idle state */
|
|---|
| 2342 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, hqspi->Timeout);
|
|---|
| 2343 |
|
|---|
| 2344 | if (status == HAL_OK)
|
|---|
| 2345 | {
|
|---|
| 2346 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 2347 |
|
|---|
| 2348 | /* Wait until BUSY flag is reset */
|
|---|
| 2349 | status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, tickstart, hqspi->Timeout);
|
|---|
| 2350 | }
|
|---|
| 2351 |
|
|---|
| 2352 | if (status == HAL_OK)
|
|---|
| 2353 | {
|
|---|
| 2354 | /* Reset functional mode configuration to indirect write mode by default */
|
|---|
| 2355 | CLEAR_BIT(hqspi->Instance->CCR, QUADSPI_CCR_FMODE);
|
|---|
| 2356 |
|
|---|
| 2357 | /* Update state */
|
|---|
| 2358 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 2359 | }
|
|---|
| 2360 | }
|
|---|
| 2361 |
|
|---|
| 2362 | return status;
|
|---|
| 2363 | }
|
|---|
| 2364 |
|
|---|
| 2365 | /**
|
|---|
| 2366 | * @brief Abort the current transmission (non-blocking function)
|
|---|
| 2367 | * @param hqspi : QSPI handle
|
|---|
| 2368 | * @retval HAL status
|
|---|
| 2369 | */
|
|---|
| 2370 | HAL_StatusTypeDef HAL_QSPI_Abort_IT(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2371 | {
|
|---|
| 2372 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2373 |
|
|---|
| 2374 | /* Check if the state is in one of the busy states */
|
|---|
| 2375 | if (((uint32_t)hqspi->State & 0x2U) != 0U)
|
|---|
| 2376 | {
|
|---|
| 2377 | /* Process unlocked */
|
|---|
| 2378 | __HAL_UNLOCK(hqspi);
|
|---|
| 2379 |
|
|---|
| 2380 | /* Update QSPI state */
|
|---|
| 2381 | hqspi->State = HAL_QSPI_STATE_ABORT;
|
|---|
| 2382 |
|
|---|
| 2383 | /* Disable all interrupts */
|
|---|
| 2384 | __HAL_QSPI_DISABLE_IT(hqspi, (QSPI_IT_TO | QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TC | QSPI_IT_TE));
|
|---|
| 2385 |
|
|---|
| 2386 | if ((hqspi->Instance->CR & QUADSPI_CR_DMAEN) != 0U)
|
|---|
| 2387 | {
|
|---|
| 2388 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 2389 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 2390 |
|
|---|
| 2391 | /* Abort DMA channel */
|
|---|
| 2392 | hqspi->hdma->XferAbortCallback = QSPI_DMAAbortCplt;
|
|---|
| 2393 | if (HAL_DMA_Abort_IT(hqspi->hdma) != HAL_OK)
|
|---|
| 2394 | {
|
|---|
| 2395 | /* Change state of QSPI */
|
|---|
| 2396 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 2397 |
|
|---|
| 2398 | /* Abort Complete callback */
|
|---|
| 2399 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 2400 | hqspi->AbortCpltCallback(hqspi);
|
|---|
| 2401 | #else
|
|---|
| 2402 | HAL_QSPI_AbortCpltCallback(hqspi);
|
|---|
| 2403 | #endif
|
|---|
| 2404 | }
|
|---|
| 2405 | }
|
|---|
| 2406 | else
|
|---|
| 2407 | {
|
|---|
| 2408 | /* Clear interrupt */
|
|---|
| 2409 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 2410 |
|
|---|
| 2411 | /* Enable the QSPI Transfer Complete Interrupt */
|
|---|
| 2412 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
|
|---|
| 2413 |
|
|---|
| 2414 | /* Configure QSPI: CR register with Abort request */
|
|---|
| 2415 | SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
|
|---|
| 2416 | }
|
|---|
| 2417 | }
|
|---|
| 2418 | return status;
|
|---|
| 2419 | }
|
|---|
| 2420 |
|
|---|
| 2421 | /** @brief Set QSPI timeout.
|
|---|
| 2422 | * @param hqspi : QSPI handle.
|
|---|
| 2423 | * @param Timeout : Timeout for the QSPI memory access.
|
|---|
| 2424 | * @retval None
|
|---|
| 2425 | */
|
|---|
| 2426 | void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
|
|---|
| 2427 | {
|
|---|
| 2428 | hqspi->Timeout = Timeout;
|
|---|
| 2429 | }
|
|---|
| 2430 |
|
|---|
| 2431 | /** @brief Set QSPI Fifo threshold.
|
|---|
| 2432 | * @param hqspi : QSPI handle.
|
|---|
| 2433 | * @param Threshold : Threshold of the Fifo (value between 1 and 16).
|
|---|
| 2434 | * @retval HAL status
|
|---|
| 2435 | */
|
|---|
| 2436 | HAL_StatusTypeDef HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold)
|
|---|
| 2437 | {
|
|---|
| 2438 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2439 |
|
|---|
| 2440 | /* Process locked */
|
|---|
| 2441 | __HAL_LOCK(hqspi);
|
|---|
| 2442 |
|
|---|
| 2443 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 2444 | {
|
|---|
| 2445 | /* Synchronize init structure with new FIFO threshold value */
|
|---|
| 2446 | hqspi->Init.FifoThreshold = Threshold;
|
|---|
| 2447 |
|
|---|
| 2448 | /* Configure QSPI FIFO Threshold */
|
|---|
| 2449 | MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES,
|
|---|
| 2450 | ((hqspi->Init.FifoThreshold - 1U) << QUADSPI_CR_FTHRES_Pos));
|
|---|
| 2451 | }
|
|---|
| 2452 | else
|
|---|
| 2453 | {
|
|---|
| 2454 | status = HAL_BUSY;
|
|---|
| 2455 | }
|
|---|
| 2456 |
|
|---|
| 2457 | /* Process unlocked */
|
|---|
| 2458 | __HAL_UNLOCK(hqspi);
|
|---|
| 2459 |
|
|---|
| 2460 | /* Return function status */
|
|---|
| 2461 | return status;
|
|---|
| 2462 | }
|
|---|
| 2463 |
|
|---|
| 2464 | /** @brief Get QSPI Fifo threshold.
|
|---|
| 2465 | * @param hqspi : QSPI handle.
|
|---|
| 2466 | * @retval Fifo threshold (value between 1 and 16)
|
|---|
| 2467 | */
|
|---|
| 2468 | uint32_t HAL_QSPI_GetFifoThreshold(QSPI_HandleTypeDef *hqspi)
|
|---|
| 2469 | {
|
|---|
| 2470 | return ((READ_BIT(hqspi->Instance->CR, QUADSPI_CR_FTHRES) >> QUADSPI_CR_FTHRES_Pos) + 1U);
|
|---|
| 2471 | }
|
|---|
| 2472 |
|
|---|
| 2473 | /** @brief Set FlashID.
|
|---|
| 2474 | * @param hqspi : QSPI handle.
|
|---|
| 2475 | * @param FlashID : Index of the flash memory to be accessed.
|
|---|
| 2476 | * This parameter can be a value of @ref QSPI_Flash_Select.
|
|---|
| 2477 | * @note The FlashID is ignored when dual flash mode is enabled.
|
|---|
| 2478 | * @retval HAL status
|
|---|
| 2479 | */
|
|---|
| 2480 | HAL_StatusTypeDef HAL_QSPI_SetFlashID(QSPI_HandleTypeDef *hqspi, uint32_t FlashID)
|
|---|
| 2481 | {
|
|---|
| 2482 | HAL_StatusTypeDef status = HAL_OK;
|
|---|
| 2483 |
|
|---|
| 2484 | /* Check the parameter */
|
|---|
| 2485 | assert_param(IS_QSPI_FLASH_ID(FlashID));
|
|---|
| 2486 |
|
|---|
| 2487 | /* Process locked */
|
|---|
| 2488 | __HAL_LOCK(hqspi);
|
|---|
| 2489 |
|
|---|
| 2490 | if(hqspi->State == HAL_QSPI_STATE_READY)
|
|---|
| 2491 | {
|
|---|
| 2492 | /* Synchronize init structure with new FlashID value */
|
|---|
| 2493 | hqspi->Init.FlashID = FlashID;
|
|---|
| 2494 |
|
|---|
| 2495 | /* Configure QSPI FlashID */
|
|---|
| 2496 | MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FSEL, FlashID);
|
|---|
| 2497 | }
|
|---|
| 2498 | else
|
|---|
| 2499 | {
|
|---|
| 2500 | status = HAL_BUSY;
|
|---|
| 2501 | }
|
|---|
| 2502 |
|
|---|
| 2503 | /* Process unlocked */
|
|---|
| 2504 | __HAL_UNLOCK(hqspi);
|
|---|
| 2505 |
|
|---|
| 2506 | /* Return function status */
|
|---|
| 2507 | return status;
|
|---|
| 2508 | }
|
|---|
| 2509 |
|
|---|
| 2510 | /**
|
|---|
| 2511 | * @}
|
|---|
| 2512 | */
|
|---|
| 2513 |
|
|---|
| 2514 | /**
|
|---|
| 2515 | * @}
|
|---|
| 2516 | */
|
|---|
| 2517 |
|
|---|
| 2518 | /** @defgroup QSPI_Private_Functions QSPI Private Functions
|
|---|
| 2519 | * @{
|
|---|
| 2520 | */
|
|---|
| 2521 |
|
|---|
| 2522 | /**
|
|---|
| 2523 | * @brief DMA QSPI receive process complete callback.
|
|---|
| 2524 | * @param hdma : DMA handle
|
|---|
| 2525 | * @retval None
|
|---|
| 2526 | */
|
|---|
| 2527 | static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma)
|
|---|
| 2528 | {
|
|---|
| 2529 | QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
|
|---|
| 2530 | hqspi->RxXferCount = 0U;
|
|---|
| 2531 |
|
|---|
| 2532 | /* Enable the QSPI transfer complete Interrupt */
|
|---|
| 2533 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
|
|---|
| 2534 | }
|
|---|
| 2535 |
|
|---|
| 2536 | /**
|
|---|
| 2537 | * @brief DMA QSPI transmit process complete callback.
|
|---|
| 2538 | * @param hdma : DMA handle
|
|---|
| 2539 | * @retval None
|
|---|
| 2540 | */
|
|---|
| 2541 | static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma)
|
|---|
| 2542 | {
|
|---|
| 2543 | QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
|
|---|
| 2544 | hqspi->TxXferCount = 0U;
|
|---|
| 2545 |
|
|---|
| 2546 | /* Enable the QSPI transfer complete Interrupt */
|
|---|
| 2547 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
|
|---|
| 2548 | }
|
|---|
| 2549 |
|
|---|
| 2550 | /**
|
|---|
| 2551 | * @brief DMA QSPI receive process half complete callback.
|
|---|
| 2552 | * @param hdma : DMA handle
|
|---|
| 2553 | * @retval None
|
|---|
| 2554 | */
|
|---|
| 2555 | static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
|
|---|
| 2556 | {
|
|---|
| 2557 | QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
|
|---|
| 2558 |
|
|---|
| 2559 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 2560 | hqspi->RxHalfCpltCallback(hqspi);
|
|---|
| 2561 | #else
|
|---|
| 2562 | HAL_QSPI_RxHalfCpltCallback(hqspi);
|
|---|
| 2563 | #endif
|
|---|
| 2564 | }
|
|---|
| 2565 |
|
|---|
| 2566 | /**
|
|---|
| 2567 | * @brief DMA QSPI transmit process half complete callback.
|
|---|
| 2568 | * @param hdma : DMA handle
|
|---|
| 2569 | * @retval None
|
|---|
| 2570 | */
|
|---|
| 2571 | static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
|
|---|
| 2572 | {
|
|---|
| 2573 | QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)(hdma->Parent);
|
|---|
| 2574 |
|
|---|
| 2575 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 2576 | hqspi->TxHalfCpltCallback(hqspi);
|
|---|
| 2577 | #else
|
|---|
| 2578 | HAL_QSPI_TxHalfCpltCallback(hqspi);
|
|---|
| 2579 | #endif
|
|---|
| 2580 | }
|
|---|
| 2581 |
|
|---|
| 2582 | /**
|
|---|
| 2583 | * @brief DMA QSPI communication error callback.
|
|---|
| 2584 | * @param hdma : DMA handle
|
|---|
| 2585 | * @retval None
|
|---|
| 2586 | */
|
|---|
| 2587 | static void QSPI_DMAError(DMA_HandleTypeDef *hdma)
|
|---|
| 2588 | {
|
|---|
| 2589 | QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
|
|---|
| 2590 |
|
|---|
| 2591 | /* if DMA error is FIFO error ignore it */
|
|---|
| 2592 | if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
|
|---|
| 2593 | {
|
|---|
| 2594 | hqspi->RxXferCount = 0U;
|
|---|
| 2595 | hqspi->TxXferCount = 0U;
|
|---|
| 2596 | hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA;
|
|---|
| 2597 |
|
|---|
| 2598 | /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */
|
|---|
| 2599 | CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN);
|
|---|
| 2600 |
|
|---|
| 2601 | /* Abort the QSPI */
|
|---|
| 2602 | (void)HAL_QSPI_Abort_IT(hqspi);
|
|---|
| 2603 |
|
|---|
| 2604 | }
|
|---|
| 2605 | }
|
|---|
| 2606 |
|
|---|
| 2607 | /**
|
|---|
| 2608 | * @brief DMA QSPI abort complete callback.
|
|---|
| 2609 | * @param hdma : DMA handle
|
|---|
| 2610 | * @retval None
|
|---|
| 2611 | */
|
|---|
| 2612 | static void QSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
|
|---|
| 2613 | {
|
|---|
| 2614 | QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )(hdma->Parent);
|
|---|
| 2615 |
|
|---|
| 2616 | hqspi->RxXferCount = 0U;
|
|---|
| 2617 | hqspi->TxXferCount = 0U;
|
|---|
| 2618 |
|
|---|
| 2619 | if(hqspi->State == HAL_QSPI_STATE_ABORT)
|
|---|
| 2620 | {
|
|---|
| 2621 | /* DMA Abort called by QSPI abort */
|
|---|
| 2622 | /* Clear interrupt */
|
|---|
| 2623 | __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
|
|---|
| 2624 |
|
|---|
| 2625 | /* Enable the QSPI Transfer Complete Interrupt */
|
|---|
| 2626 | __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
|
|---|
| 2627 |
|
|---|
| 2628 | /* Configure QSPI: CR register with Abort request */
|
|---|
| 2629 | SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT);
|
|---|
| 2630 | }
|
|---|
| 2631 | else
|
|---|
| 2632 | {
|
|---|
| 2633 | /* DMA Abort called due to a transfer error interrupt */
|
|---|
| 2634 | /* Change state of QSPI */
|
|---|
| 2635 | hqspi->State = HAL_QSPI_STATE_READY;
|
|---|
| 2636 |
|
|---|
| 2637 | /* Error callback */
|
|---|
| 2638 | #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
|
|---|
| 2639 | hqspi->ErrorCallback(hqspi);
|
|---|
| 2640 | #else
|
|---|
| 2641 | HAL_QSPI_ErrorCallback(hqspi);
|
|---|
| 2642 | #endif
|
|---|
| 2643 | }
|
|---|
| 2644 | }
|
|---|
| 2645 |
|
|---|
| 2646 | /**
|
|---|
| 2647 | * @brief Wait for a flag state until timeout.
|
|---|
| 2648 | * @param hqspi : QSPI handle
|
|---|
| 2649 | * @param Flag : Flag checked
|
|---|
| 2650 | * @param State : Value of the flag expected
|
|---|
| 2651 | * @param Tickstart : Tick start value
|
|---|
| 2652 | * @param Timeout : Duration of the timeout
|
|---|
| 2653 | * @retval HAL status
|
|---|
| 2654 | */
|
|---|
| 2655 | static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
|
|---|
| 2656 | FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
|
|---|
| 2657 | {
|
|---|
| 2658 | /* Wait until flag is in expected state */
|
|---|
| 2659 | while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
|
|---|
| 2660 | {
|
|---|
| 2661 | /* Check for the Timeout */
|
|---|
| 2662 | if (Timeout != HAL_MAX_DELAY)
|
|---|
| 2663 | {
|
|---|
| 2664 | if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
|
|---|
| 2665 | {
|
|---|
| 2666 | hqspi->State = HAL_QSPI_STATE_ERROR;
|
|---|
| 2667 | hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
|
|---|
| 2668 |
|
|---|
| 2669 | return HAL_ERROR;
|
|---|
| 2670 | }
|
|---|
| 2671 | }
|
|---|
| 2672 | }
|
|---|
| 2673 | return HAL_OK;
|
|---|
| 2674 | }
|
|---|
| 2675 |
|
|---|
| 2676 | /**
|
|---|
| 2677 | * @brief Configure the communication registers.
|
|---|
| 2678 | * @param hqspi : QSPI handle
|
|---|
| 2679 | * @param cmd : structure that contains the command configuration information
|
|---|
| 2680 | * @param FunctionalMode : functional mode to configured
|
|---|
| 2681 | * This parameter can be one of the following values:
|
|---|
| 2682 | * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode
|
|---|
| 2683 | * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode
|
|---|
| 2684 | * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode
|
|---|
| 2685 | * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode
|
|---|
| 2686 | * @retval None
|
|---|
| 2687 | */
|
|---|
| 2688 | static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode)
|
|---|
| 2689 | {
|
|---|
| 2690 | assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode));
|
|---|
| 2691 |
|
|---|
| 2692 | if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
|
|---|
| 2693 | {
|
|---|
| 2694 | /* Configure QSPI: DLR register with the number of data to read or write */
|
|---|
| 2695 | WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1U));
|
|---|
| 2696 | }
|
|---|
| 2697 |
|
|---|
| 2698 | if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE)
|
|---|
| 2699 | {
|
|---|
| 2700 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 2701 | {
|
|---|
| 2702 | /* Configure QSPI: ABR register with alternate bytes value */
|
|---|
| 2703 | WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
|
|---|
| 2704 |
|
|---|
| 2705 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 2706 | {
|
|---|
| 2707 | /*---- Command with instruction, address and alternate bytes ----*/
|
|---|
| 2708 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2709 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2710 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2711 | cmd->AlternateBytesSize | cmd->AlternateByteMode |
|
|---|
| 2712 | cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode |
|
|---|
| 2713 | cmd->Instruction | FunctionalMode));
|
|---|
| 2714 |
|
|---|
| 2715 | if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
|
|---|
| 2716 | {
|
|---|
| 2717 | /* Configure QSPI: AR register with address value */
|
|---|
| 2718 | WRITE_REG(hqspi->Instance->AR, cmd->Address);
|
|---|
| 2719 | }
|
|---|
| 2720 | }
|
|---|
| 2721 | else
|
|---|
| 2722 | {
|
|---|
| 2723 | /*---- Command with instruction and alternate bytes ----*/
|
|---|
| 2724 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2725 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2726 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2727 | cmd->AlternateBytesSize | cmd->AlternateByteMode |
|
|---|
| 2728 | cmd->AddressMode | cmd->InstructionMode |
|
|---|
| 2729 | cmd->Instruction | FunctionalMode));
|
|---|
| 2730 | }
|
|---|
| 2731 | }
|
|---|
| 2732 | else
|
|---|
| 2733 | {
|
|---|
| 2734 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 2735 | {
|
|---|
| 2736 | /*---- Command with instruction and address ----*/
|
|---|
| 2737 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2738 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2739 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2740 | cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode |
|
|---|
| 2741 | cmd->InstructionMode | cmd->Instruction | FunctionalMode));
|
|---|
| 2742 |
|
|---|
| 2743 | if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
|
|---|
| 2744 | {
|
|---|
| 2745 | /* Configure QSPI: AR register with address value */
|
|---|
| 2746 | WRITE_REG(hqspi->Instance->AR, cmd->Address);
|
|---|
| 2747 | }
|
|---|
| 2748 | }
|
|---|
| 2749 | else
|
|---|
| 2750 | {
|
|---|
| 2751 | /*---- Command with only instruction ----*/
|
|---|
| 2752 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2753 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2754 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2755 | cmd->AlternateByteMode | cmd->AddressMode |
|
|---|
| 2756 | cmd->InstructionMode | cmd->Instruction | FunctionalMode));
|
|---|
| 2757 | }
|
|---|
| 2758 | }
|
|---|
| 2759 | }
|
|---|
| 2760 | else
|
|---|
| 2761 | {
|
|---|
| 2762 | if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE)
|
|---|
| 2763 | {
|
|---|
| 2764 | /* Configure QSPI: ABR register with alternate bytes value */
|
|---|
| 2765 | WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes);
|
|---|
| 2766 |
|
|---|
| 2767 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 2768 | {
|
|---|
| 2769 | /*---- Command with address and alternate bytes ----*/
|
|---|
| 2770 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2771 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2772 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2773 | cmd->AlternateBytesSize | cmd->AlternateByteMode |
|
|---|
| 2774 | cmd->AddressSize | cmd->AddressMode |
|
|---|
| 2775 | cmd->InstructionMode | FunctionalMode));
|
|---|
| 2776 |
|
|---|
| 2777 | if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
|
|---|
| 2778 | {
|
|---|
| 2779 | /* Configure QSPI: AR register with address value */
|
|---|
| 2780 | WRITE_REG(hqspi->Instance->AR, cmd->Address);
|
|---|
| 2781 | }
|
|---|
| 2782 | }
|
|---|
| 2783 | else
|
|---|
| 2784 | {
|
|---|
| 2785 | /*---- Command with only alternate bytes ----*/
|
|---|
| 2786 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2787 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2788 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2789 | cmd->AlternateBytesSize | cmd->AlternateByteMode |
|
|---|
| 2790 | cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
|
|---|
| 2791 | }
|
|---|
| 2792 | }
|
|---|
| 2793 | else
|
|---|
| 2794 | {
|
|---|
| 2795 | if (cmd->AddressMode != QSPI_ADDRESS_NONE)
|
|---|
| 2796 | {
|
|---|
| 2797 | /*---- Command with only address ----*/
|
|---|
| 2798 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2799 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2800 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2801 | cmd->AlternateByteMode | cmd->AddressSize |
|
|---|
| 2802 | cmd->AddressMode | cmd->InstructionMode | FunctionalMode));
|
|---|
| 2803 |
|
|---|
| 2804 | if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)
|
|---|
| 2805 | {
|
|---|
| 2806 | /* Configure QSPI: AR register with address value */
|
|---|
| 2807 | WRITE_REG(hqspi->Instance->AR, cmd->Address);
|
|---|
| 2808 | }
|
|---|
| 2809 | }
|
|---|
| 2810 | else
|
|---|
| 2811 | {
|
|---|
| 2812 | /*---- Command with only data phase ----*/
|
|---|
| 2813 | if (cmd->DataMode != QSPI_DATA_NONE)
|
|---|
| 2814 | {
|
|---|
| 2815 | /* Configure QSPI: CCR register with all communications parameters */
|
|---|
| 2816 | WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode |
|
|---|
| 2817 | cmd->DataMode | (cmd->DummyCycles << QUADSPI_CCR_DCYC_Pos) |
|
|---|
| 2818 | cmd->AlternateByteMode | cmd->AddressMode |
|
|---|
| 2819 | cmd->InstructionMode | FunctionalMode));
|
|---|
| 2820 | }
|
|---|
| 2821 | }
|
|---|
| 2822 | }
|
|---|
| 2823 | }
|
|---|
| 2824 | }
|
|---|
| 2825 |
|
|---|
| 2826 | /**
|
|---|
| 2827 | * @}
|
|---|
| 2828 | */
|
|---|
| 2829 |
|
|---|
| 2830 | /**
|
|---|
| 2831 | * @}
|
|---|
| 2832 | */
|
|---|
| 2833 |
|
|---|
| 2834 | #endif /* HAL_QSPI_MODULE_ENABLED */
|
|---|
| 2835 | /**
|
|---|
| 2836 | * @}
|
|---|
| 2837 | */
|
|---|
| 2838 |
|
|---|
| 2839 | /**
|
|---|
| 2840 | * @}
|
|---|
| 2841 | */
|
|---|
| 2842 |
|
|---|
| 2843 | #endif /* defined(QUADSPI) || defined(QUADSPI1) || defined(QUADSPI2) */
|
|---|
| 2844 |
|
|---|
| 2845 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|---|