STM32G474xx HAL用户手册
stm32g4xx_hal_qspi.c
跳转到此文件的文档。
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 /**