```html STM32G474xx HAL用户手册:stm32g4xx_hal_i2s.c源文件
STM32G474xx HAL用户手册
stm32g4xx_hal_i2s.c
转到此文件文档。
00001 /**
00002   ******************************************************************************
00003   * @file    stm32g4xx_hal_i2s.c
00004   * @author  MCD Application Team
00005   * @brief   I2S HAL模块驱动程序。
00006   *          本文件提供固件函数用于管理集成音频总线(I2S)外设的以下功能:
00007   *           + 初始化和去初始化函数
00008   *           + IO操作函数
00009   *           + 外设状态和错误函数
00010   ******************************************************************************
00011   * @attention
00012   *
00013   * Copyright (c) 2019 STMicroelectronics.
00014   * All rights reserved.
00015   *
00016   * This software is licensed under terms that can be found in the LICENSE file
00017   * in the root directory of this software component.
00018   * If no LICENSE file comes with this software, it is provided AS-IS.
00019   *
00020   ******************************************************************************
00021   @verbatim
00022  ===============================================================================
00023                   ##### 如何使用此驱动程序 #####
00024  ===============================================================================
00025  [..]
00026     I2S HAL驱动程序使用如下:
00027 
00028     (#) 声明一个I2S_HandleTypeDef句柄结构体。
00029     (#) 通过实现HAL_I2S_MspInit() API初始化I2S低层资源:
00030         (##) 使能SPIx接口时钟。
00031         (##) I2S引脚配置:
00032             (+++) 使能I2S GPIO的时钟。
00033             (+++) 将这些I2S引脚配置为复用功能上拉。
00034         (##) 如果需要使用中断处理(HAL_I2S_Transmit_IT()
00035              和HAL_I2S_Receive_IT() API),则配置NVIC。
00036             (+++) 配置I2Sx中断优先级。
00037             (+++) 使能NVIC I2S IRQ处理。
00038         (##) 如果需要使用DMA处理(HAL_I2S_Transmit_DMA()
00039              和HAL_I2S_Receive_DMA() API),则配置DMA:
00040             (+++) 为Tx/Rx流/通道声明DMA句柄结构体。
00041             (+++) 使能DMAx接口时钟。
00042             (+++) 使用所需的Tx/Rx参数配置已声明的DMA句柄结构体。
00043             (+++) 配置DMA Tx/Rx流/通道。
00044             (+++) 将初始化的DMA句柄关联到I2S DMA Tx/Rx句柄。
00045             (+++) 配置优先级并使能传输完成中断的NVIC
00046                   用于DMA Tx/Rx流/通道。
00047 
00048    (#) 使用HAL_I2S_Init()函数编程模式、标准、数据格式、MCLK输出、音频频率和极性。
00049 
00050    -@- 特定的I2S中断(传输完成中断、
00051        RXNE中断和错误中断)将使用宏
00052        __HAL_I2S_ENABLE_IT()和__HAL_I2S_DISABLE_IT()在发送和接收过程中进行管理。
00053    -@- 确保以下之一:
00054         (+@) SYSCLK已配置或
00055         (+@) PLLADCCLK输出已配置或
00056         (+@) HSI已使能或
00057         (+@) 在stm32g4xx_hal_conf.h文件中正确设置
00058              EXTERNAL_CLOCK_VALUE定义常量后,外部时钟源已配置。
00059 
00060     (#) 此驱动程序提供三种操作模式:
00061 
00062    *** 轮询模式IO操作 ***
00063    =================================
00064    [..]
00065      (+) 使用HAL_I2S_Transmit()在阻塞模式下发送数据
00066      (+) 使用HAL_I2S_Receive()在阻塞模式下接收数据
00067 
00068    *** 中断模式IO操作 ***
00069    ===================================
00070    [..]
00071      (+) 使用HAL_I2S_Transmit_IT()在非阻塞模式下发送数据
00072      (+) 传输半完成时执行HAL_I2S_TxHalfCpltCallback,用户可以通过
00073          自定义HAL_I2S_TxHalfCpltCallback函数指针添加自己的代码
00074      (+) 传输完成时执行HAL_I2S_TxCpltCallback,用户可以通过
00075          自定义HAL_I2S_TxCpltCallback函数指针添加自己的代码
00076      (+) 使用HAL_I2S_Receive_IT()在非阻塞模式下接收数据
00077      (+) 接收半完成时执行HAL_I2S_RxHalfCpltCallback,用户可以通过
00078          自定义HAL_I2S_RxHalfCpltCallback函数指针添加自己的代码
00079      (+) 接收完成时执行HAL_I2S_RxCpltCallback,用户可以通过
00080          自定义HAL_I2S_RxCpltCallback函数指针添加自己的代码
00081      (+) 如果发生传输错误,将执行HAL_I2S_ErrorCallback()函数,用户可以通过
00082          自定义HAL_I2S_ErrorCallback函数指针添加自己的代码
00083 
00084    *** DMA模式IO操作 ***
00085    ==============================
00086    [..]
00087      (+) 使用HAL_I2S_Transmit_DMA()在非阻塞模式(DMA)下发送数据
00088      (+) 传输半完成时执行HAL_I2S_TxHalfCpltCallback,用户可以通过
00089          自定义HAL_I2S_TxHalfCpltCallback函数指针添加自己的代码
00090      (+) 传输完成时执行HAL_I2S_TxCpltCallback,用户可以通过
00091          自定义HAL_I2S_TxCpltCallback函数指针添加自己的代码
00092      (+) 使用HAL_I2S_Receive_DMA()在非阻塞模式(DMA)下接收数据
00093      (+) 接收半完成时执行HAL_I2S_RxHalfCpltCallback,用户可以通过
00094          自定义HAL_I2S_RxHalfCpltCallback函数指针添加自己的代码
00095      (+) 接收完成时执行HAL_I2S_RxCpltCallback,用户可以通过
00096          自定义HAL_I2S_RxCpltCallback函数指针添加自己的代码
00097      (+) 如果发生传输错误,将执行HAL_I2S_ErrorCallback()函数,用户可以通过
00098          自定义HAL_I2S_ErrorCallback函数指针添加自己的代码
00099      (+) 使用HAL_I2S_DMAPause()暂停DMA传输
00100      (+) 使用HAL_I2S_DMAResume()恢复DMA传输
00101      (+) 使用HAL_I2S_DMAStop()停止DMA传输
00102          在从机模式下,如果使用HAL_I2S_DMAStop停止通信,
00103          会引发错误HAL_I2S_ERROR_BUSY_LINE_RX,因为主机继续传输数据。
00104          在这种情况下,必须使用__HAL_I2S_FLUSH_RX_DR宏来清除
00105          DR寄存器中剩余的数据,避免下次传输使用DeInit/Init过程。
00106 
00107    *** I2S HAL驱动程序宏列表 ***
00108    ===================================
00109    [..]
00110      以下是I2S HAL驱动程序中最常用的宏列表。
00111 
00112       (+) __HAL_I2S_ENABLE:使能指定的SPI外设(I2S模式)
00113       (+) __HAL_I2S_DISABLE:禁用指定的SPI外设(I2S模式)
00114       (+) __HAL_I2S_ENABLE_IT:使能指定的I2S中断
00115       (+) __HAL_I2S_DISABLE_IT:禁用指定的I2S中断
00116       (+) __HAL_I2S_GET_FLAG:检查指定的I2S标志是否已设置
00117       (+) __HAL_I2S_FLUSH_RX_DR:读取DR寄存器以清除RX数据
00118 
00119     [..]
00120       (@) 您可以参阅I2S HAL驱动程序头文件以获取更多有用的宏
00121 
00122    *** I2S HAL驱动程序宏列表 ***
00123    ===================================
00124    [..]
00125        回调注册:
00126 
00127       (#) 当编译标志USE_HAL_I2S_REGISTER_CALLBACKS设置为1U时
00128           允许用户动态配置驱动程序回调。
00129           使用函数HAL_I2S_RegisterCallback()注册中断回调。
00130 
00131           函数HAL_I2S_RegisterCallback()允许注册以下回调:
00132             (++) TxCpltCallback        : I2S Tx完成回调
00133             (++) RxCpltCallback        : I2S Rx完成回调
00134             (++) TxHalfCpltCallback    : I2S Tx半完成回调
00135             (++) RxHalfCpltCallback    : I2S Rx半完成回调
00136             (++) ErrorCallback         : I2S错误回调
00137             (++) MspInitCallback       : I2S Msp初始化回调
00138             (++) MspDeInitCallback     : I2S Msp去初始化回调
00139           此函数接受HAL外设句柄、回调ID
00140           和用户回调函数指针作为参数。
00141 
00142 
00143       (#) 使用函数HAL_I2S_UnRegisterCallback将回调重置为默认的弱函数。
00144           HAL_I2S_UnRegisterCallback接受HAL外设句柄
00145           和回调ID作为参数。
00146           此函数允许重置以下回调:
00147             (++) TxCpltCallback        : I2S Tx完成回调
00148             (++) RxCpltCallback        : I2S Rx完成回调
00149             (++) TxHalfCpltCallback    : I2S Tx半完成回调
00150             (++) RxHalfCpltCallback    : I2S Rx半完成回调
00151             (++) ErrorCallback         : I2S错误回调
00152             (++) MspInitCallback       : I2S Msp初始化回调
00153             (++) MspDeInitCallback     : I2S Msp去初始化回调
00154 
00155        [..]
00156        默认情况下,在HAL_I2S_Init()之后且状态为HAL_I2S_STATE_RESET时
00157        所有回调都设置为对应的弱函数:
00158        例如HAL_I2S_MasterTxCpltCallback()、HAL_I2S_MasterRxCpltCallback()。
00159        例外的MspInit和MspDeInit函数在
00160        HAL_I2S_Init()/HAL_I2S_DeInit()中仅当
00161        这些回调为空(未预先注册)时才重置为传统弱函数。
00162        如果MspInit或MspDeInit不为空,HAL_I2S_Init()/HAL_I2S_DeInit()
00163        将保留并使用用户预先注册的MspInit/MspDeInit回调(无论状态如何)。
00164 
00165        [..]
00166        回调只能在HAL_I2S_STATE_READY状态下注册/注销。
00167        例外的MspInit/MspDeInit函数可以在HAL_I2S_STATE_READY或HAL_I2S_STATE_RESET状态下注册/注销,
00168        因此已注册的用户MspInit/DeInit回调可在Init/DeInit期间使用。
00169        然后,用户首先使用HAL_I2S_RegisterCallback()注册MspInit/MspDeInit用户回调
00170        再调用HAL_I2S_DeInit()
00171        或HAL_I2S_Init()函数。
00172 
00173        [..]
00174        当编译定义USE_HAL_I2S_REGISTER_CALLBACKS设置为0或
00175        未定义时,回调注册功能不可用
00176        将使用弱(重载)回调。
00177 
00178   @endverbatim
00179 
00180   */
00181 
00182 /* Includes ------------------------------------------------------------------*/
00183 #include "stm32g4xx_hal.h"
00184 
00185 #ifdef HAL_I2S_MODULE_ENABLED
00186 
00187 #if defined(SPI_I2S_SUPPORT)
00188 /** @addtogroup STM32G4xx_HAL_Driver
00189   * @{
00190   */
00191 
00192 /** @defgroup I2S I2S
00193   * @brief I2S HAL模块驱动程序
00194   * @{
00195   */
00196 
00197 /* Private typedef -----------------------------------------------------------*/
00198 /* Private define ------------------------------------------------------------*/
00199 /* Private macro -------------------------------------------------------------*/
00200 /* Private variables ---------------------------------------------------------*/
00201 /* Private function prototypes -----------------------------------------------*/
00202 /** @defgroup I2S_Private_Functions I2S私有函数
00203   * @{
00204   */
00205 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
00206 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00207 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
00208 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00209 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
00210 static void               I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
00211 static void