|
STM32G474xx HAL用户手册
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32g4xx_hal_qspi.c 00004 * @author MCD Application Team 00005 * @brief QSPI HAL模块驱动。 00006 * 本文件提供了用于管理QuadSPI接口(QSPI)以下功能的固件函数: 00007 * + 初始化和反初始化函数 00008 * + 间接功能模式管理 00009 * + 内存映射功能模式管理 00010 * + 自动轮询功能模式管理 00011 * + 中断和标志管理 00012 * + 间接功能模式的DMA通道配置 00013 * + 错误管理和中止功能 00014 * 00015 * 00016 ****************************************************************************** 00017 * @attention 00018 * 00019 * Copyright (c) 2019 STMicroelectronics. 00020 * All rights reserved. 00021 * 00022 * This software is licensed under terms that can be found in the LICENSE file 00023 * in the root directory of this software component. 00024 * If no LICENSE file comes with this software, it is provided AS-IS. 00025 * 00026 ****************************************************************************** 00027 @verbatim 00028 =============================================================================== 00029 ##### 如何使用此驱动 ##### 00030 =============================================================================== 00031 [..] 00032 *** 初始化 *** 00033 ====================== 00034 [..] 00035 (#) 作为先决条件,填写HAL_QSPI_MspInit(): 00036 (++) 使用__HAL_RCC_QSPI_CLK_ENABLE()启用QuadSPI时钟接口。 00037 (++) 使用__HAL_RCC_QSPI_FORCE_RESET()和__HAL_RCC_QSPI_RELEASE_RESET()复位QuadSPI外设。 00038 (++) 使用__HAL_RCC_GPIOx_CLK_ENABLE()为QuadSPI GPIO启用时钟。 00039 (++) 使用HAL_GPIO_Init()将这些QuadSPI引脚配置为复用模式。 00040 (++) 如果使用中断模式,使用HAL_NVIC_SetPriority()和HAL_NVIC_EnableIRQ()启用并配置QuadSPI全局中断。 00041 (++) 如果使用DMA模式,使用__HAL_RCC_DMAx_CLK_ENABLE()为QuadSPI DMA通道启用时钟, 00042 使用HAL_DMA_Init()配置DMA,使用__HAL_LINKDMA()将其与QuadSPI句柄链接, 00043 使用HAL_NVIC_SetPriority()和HAL_NVIC_EnableIRQ()启用并配置DMA通道全局中断。 00044 (#) 使用HAL_QSPI_Init()函数配置闪存大小、时钟预分频器、FIFO阈值、 00045 时钟模式、采样偏移和CS高电平时间。 00046 00047 *** 间接功能模式 *** 00048 ================================ 00049 [..] 00050 (#) 使用HAL_QSPI_Command()或HAL_QSPI_Command_IT()函数配置命令序列: 00052 (++) 指令阶段:使用的模式以及指令操作码(如果有)。 00053 (++) 地址阶段:使用的模式以及地址大小和地址值(如果有)。 00054 (++) 交替字节阶段:使用的模式以及交替字节大小和值(如果有)。 00055 (++) 虚拟周期阶段:虚拟周期数量(使用的模式与数据阶段相同)。 00056 (++) 数据阶段:使用的模式以及字节数量(如果有)。 00057 (++) 双倍数据速率(DDR)模式:该模式的激活(或不激活)以及激活时的延迟。 00058 (++) 指令仅发送一次(SIOO)模式:该模式的激活(或不激活)。 00059 (#) 如果命令不需要数据,则直接发送到内存: 00060 (++) 在轮询模式下,函数输出在传输完成后进行。 00061 (++) 在中断模式下,当传输完成时将调用HAL_QSPI_CmdCpltCallback()。 00062 (#) 对于间接写模式,在命令配置后使用HAL_QSPI_Transmit()、HAL_QSPI_Transmit_DMA()或 00063 HAL_QSPI_Transmit_IT(): 00064 (++) 在轮询模式下,函数输出在传输完成后进行。 00065 (++) 在中断模式下,当达到FIFO阈值时将调用HAL_QSPI_FifoThresholdCallback(), 00066 当传输完成时将调用HAL_QSPI_TxCpltCallback()。 00067 (++) 在DMA模式下,半传输时将调用HAL_QSPI_TxHalfCpltCallback(), 00068 当传输完成时将调用HAL_QSPI_TxCpltCallback()。 00069 (#) 对于间接读模式,在命令配置后使用HAL_QSPI_Receive()、HAL_QSPI_Receive_DMA()或 00070 HAL_QSPI_Receive_IT(): 00071 (++) 在轮询模式下,函数输出在传输完成后进行。 00072 (++) 在中断模式下,当达到FIFO阈值时将调用HAL_QSPI_FifoThresholdCallback(), 00073 当传输完成时将调用HAL_QSPI_RxCpltCallback()。 00074 (++) 在DMA模式下,半传输时将调用HAL_QSPI_RxHalfCpltCallback(), 00075 当传输完成时将调用HAL_QSPI_RxCpltCallback()。 00076 00077 *** 自动轮询功能模式 *** 00078 ==================================== 00079 [..] 00080 (#) 使用HAL_QSPI_AutoPolling()或HAL_QSPI_AutoPolling_IT()函数配置命令序列和自动轮询功能模式: 00081 (++) 指令阶段:使用的模式以及指令操作码(如果有)。 00082 (++) 地址阶段:使用的模式以及地址大小和地址值(如果有)。 00083 (++) 交替字节阶段:使用的模式以及交替字节大小和值(如果有)。 00084 (++) 虚拟周期阶段:虚拟周期数量(使用的模式与数据阶段相同)。 00085 (++) 数据阶段:使用的模式。 00086 (++) 双倍数据速率(DDR)模式:该模式的激活(或不激活)以及激活时的延迟。 00087 (++) 指令仅发送一次(SIOO)模式:该模式的激活(或不激活)。 00088 (++) 状态字节大小、匹配值、使用的掩码、匹配模式(OR/AND)、 00089 轮询间隔和自动停止激活。 00090 (#) 配置之后: 00091 (++) 在轮询模式下,当达到状态匹配时函数输出。自动停止被激活以避免无限循环。 00092 (++) 在中断模式下,每次达到状态匹配时都会调用HAL_QSPI_StatusMatchCallback()。 00093 00094 *** 内存映射功能模式 *** 00095 ===================================== 00096 [..] 00097 (#) 使用HAL_QSPI_MemoryMapped()函数配置命令序列和内存映射功能模式: 00098 (++) 指令阶段:使用的模式以及指令操作码(如果有)。 00099 (++) 地址阶段:使用的模式和地址大小。 00100 (++) 交替字节阶段:使用的模式以及交替字节大小和值(如果有)。 00101 (++) 虚拟周期阶段:虚拟周期数量(使用的模式与数据阶段相同)。 00102 (++) 数据阶段:使用的模式。 00103 (++) 双倍数据速率(DDR)模式:该模式的激活(或不激活)以及激活时的延迟。 00104 (++) 指令仅发送一次(SIOO)模式:该模式的激活(或不激活)。 00105 (++) 超时激活和超时周期。 00106 (#) 配置后,一旦在AHB上对地址范围进行访问,QuadSPI将被使用。 00107 当超时到期时将调用HAL_QSPI_TimeOutCallback()。 00108 00109 *** 错误管理和中止功能 *** 00110 ================================================= 00111 [..] 00112 (#) HAL_QSPI_GetError()函数给出上次操作期间发生的错误。 00113 (#) HAL_QSPI_Abort()和HAL_QSPI_Abort_IT()函数中止任何正在进行的操作并 00114 清空FIFO: 00115 (++) 在轮询模式下,当传输完成位被设置且忙位被清除时函数输出。 00116 (++) 在中断模式下,当传输完成位被设置时将调用HAL_QSPI_AbortCpltCallback()。 00117 00118 *** 控制函数 *** 00119 ========================= 00120 [..] 00121 (#) HAL_QSPI_GetState()函数给出HAL QuadSPI驱动的当前状态。 00122 (#) HAL_QSPI_SetTimeout()函数配置驱动中使用的超时值。 00123 (#) HAL_QSPI_SetFifoThreshold()函数配置QSPI IP的FIFO阈值。 00124 (#) HAL_QSPI_GetFifoThreshold()函数获取FIFO阈值的当前值。 00125 (#) HAL_QSPI_SetFlashID()函数配置要访问的闪存存储器的索引。 00126 00127 *** 回调注册 *** 00128 ============================================= 00130 [..] 00131 当编译定义USE_HAL_QSPI_REGISTER_CALLBACKS设置为1时, 00132 允许用户动态配置驱动回调。 00133 00134 使用函数HAL_QSPI_RegisterCallback()注册用户回调, 00135 它允许注册以下回调: 00136 (+) ErrorCallback:发生错误时的回调。 00137 (+) AbortCpltCallback:中止完成时的回调。 00138 (+) FifoThresholdCallback:达到FIFO阈值时的回调。 00139 (+) CmdCpltCallback:无数据命令完成时的回调。 00140 (+) RxCpltCallback:接收传输完成时的回调。 00141 (+) TxCpltCallback:发送传输完成时的回调。 00142 (+) RxHalfCpltCallback:接收传输完成一半时的回调。 00143 (+) TxHalfCpltCallback:发送传输完成一半时的回调。 00144 (+) StatusMatchCallback:发生状态匹配时的回调。 00145 (+) TimeOutCallback:超时到期时的回调。 00146 (+) MspInitCallback:QSPI MspInit。 00147 (+) MspDeInitCallback:QSPI MspDeInit。 00148 此函数接受HAL外设句柄、回调ID和用户回调函数指针作为参数。 00149 00150 使用函数HAL_QSPI_UnRegisterCallback()将回调重置为默认 00151 弱(覆盖)函数。它允许重置以下回调: 00152 (+) ErrorCallback:发生错误时的回调。 00153 (+) AbortCpltCallback:中止完成时的回调。 00154 (+) FifoThresholdCallback:达到FIFO阈值时的回调。 00155 (+) CmdCpltCallback:无数据命令完成时的回调。 00156 (+) RxCpltCallback:接收传输完成时的回调。 00157 (+) TxCpltCallback:发送传输完成时的回调。 00158 (+) RxHalfCpltCallback:接收传输完成一半时的回调。 00159 (+) TxHalfCpltCallback:发送传输完成一半时的回调。 00160 (+) StatusMatchCallback:发生状态匹配时的回调。 00161 (+) TimeOutCallback:超时到期时的回调。 00162 (+) MspInitCallback:QSPI MspInit。 00163 (+) MspDeInitCallback:QSPI MspDeInit。 00164 此函数接受HAL外设句柄和回调ID作为参数。 00165 00166 默认情况下,在HAL_QSPI_Init之后,如果状态为HAL_QSPI_STATE_RESET, 00167 所有回调都重置为相应的传统弱(覆盖)函数。 00168 例外情况是MspInit和MspDeInit回调,它们分别 00169 在HAL_QSPI_Init和HAL_QSPI_DeInit中重置为传统弱(覆盖)函数, 00170 但仅在这些回调为空(未预先注册)时。 00171 否则,如果MspInit或MspDeInit不为空,HAL_QSPI_Init和HAL_QSPI_DeInit 00172 保留并使用用户的MspInit/MspDeInit回调(预先注册)。 00173 00174 回调只能在就绪状态下注册/注销。 00175 例外情况是MspInit/MspDeInit回调,它们可以在就绪或复位状态下注册/注销, 00176 因此注册的(用户)MspInit/DeInit回调可以在Init/DeInit期间使用。 00177 在这种情况下,首先使用HAL_QSPI_RegisterCallback注册MspInit/MspDeInit用户回调, 00178 然后再调用HAL_QSPI_DeInit或HAL_QSPI_Init函数。 00179 00180 当编译定义USE_HAL_QSPI_REGISTER_CALLBACKS设置为0或 00181 未定义时,回调注册功能不可用, 00182 将使用弱(覆盖)回调。 00183 00184 *** 与硅限制相关的工作around *** 00185 ==================================================== 00186 [..] 00187 (#) HAL驱动内部实现的工作around 00188 (++) 读传输结束时写入FIFO的额外数据 00189 00200 @endverbatim 00201 ****************************************************************************** 00202 */ 00203 00204 /* Includes ------------------------------------------------------------------*/ 00205 #include "stm32g4xx_hal.h" 00206 00207 #if defined(QUADSPI) 00208 00209 /** @addtogroup STM32G4xx_HAL_Driver 00210 * @{ 00211 */ 00212 00213 /** @defgroup QSPI QSPI 00214 * @brief QSPI HAL模块驱动 00216 * @{ 00217 */ 00218 #ifdef HAL_QSPI_MODULE_ENABLED 00219 00220 /* Private typedef -----------------------------------------------------------*/ 00221 00222 /* Private define ------------------------------------------------------------*/ 00223 /** @defgroup QSPI_Private_Constants QSPI私有常量 00224 * @{ 00225 */ 00226 00227 #define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE 0x00000000U /*!<间接写模式*/ 00228 #define QSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)QUADSPI_CCR_FMODE_0) /*!<间接读模式*/ 00229 #define QSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)QUADSPI_CCR_FMODE_1) /*!<自动轮询模式*/ 00230 #define QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)QUADSPI_CCR_FMODE) /*!<内存映射模式*/ 00231 /**