MXC-A36-Demo/MCU/components/drivers/peripheral/Inc/driver_i2s.h

410 lines
16 KiB
C
Raw Permalink Blame History

/*
******************************************************************************
* @file driver_i2s.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of I2S HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_I2S_H__
#define __DRIVER_I2S_H__
#include "fr30xx.h"
/** @addtogroup I2S_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* I2S control 0 Register */
typedef struct
{
uint32_t MSTSLV : 1;
uint32_t LR_WD_EN : 1;
uint32_t INTEN : 1;
uint32_t LR_WD_SWAP : 1;
uint32_t RXFF_R_EN : 1;
uint32_t RXFF_L_EN : 1;
uint32_t TXFF_R_EN : 1;
uint32_t TXFF_L_EN : 1;
uint32_t RXFF_R_CLR : 1;
uint32_t RXFF_L_CLR : 1;
uint32_t TXFF_R_CLR : 1;
uint32_t TXFF_L_CLR : 1;
uint32_t rsv_0 : 4;
uint32_t SBC_ACCESS : 1;
uint32_t rsv_1 : 15;
}REG_I2S_CTRL0_t;
/* frame divder Register */
typedef struct
{
uint32_t BCLKDIV : 16;
uint32_t FRMDIV : 16;
}REG_FRM_DIV_t;
/* I2S control 1 Register */
typedef struct
{
uint32_t I2S_EN : 1;
uint32_t I2S_FRMINV : 1;
uint32_t I2S_BCLKINV : 1;
uint32_t I2S_LP : 1;
uint32_t I2S_HLSEL : 1;
uint32_t A2DP_SYNC_DISABLE : 1;
uint32_t rsv_0 : 1;
uint32_t I2S_NORMAL : 1;
uint32_t I2S_ADJUST : 1;
uint32_t I2S_LSB1ST : 1;
uint32_t rsv_1 : 2;
uint32_t I2S_DATA_LENGTH : 3;
uint32_t rsv_2 : 1;
uint32_t I2SFBOFF : 16;
}REG_I2S_CTRL1_t;
/* FIFO config right Register */
typedef struct
{
uint32_t TXFF_AEMPTY : 8;
uint32_t TXFF_AFULL : 8;
uint32_t RXFF_AEMPTY : 8;
uint32_t RXFF_AFULL : 8;
}REG_FIFO_CFG_t;
/* DMA config Register */
typedef struct
{
uint32_t DMACR_L_TX : 1;
uint32_t DMACR_R_TX : 1;
uint32_t DMACR_L_RX : 1;
uint32_t DMACR_R_RX : 1;
uint32_t rsv_0 : 4;
uint32_t DMARDLR : 5;
uint32_t rsv_1 : 3;
uint32_t DMATDLR : 5;
uint32_t rsv_2 : 11;
}REG_I2S_DMA_CFG_t;
/* PCM general Register */
typedef struct
{
uint32_t PCM_EN : 1;
uint32_t PCM_LRSWAP : 1;
uint32_t PCM_BYTESWAP : 1;
uint32_t PCM_PLL_EN : 1;
uint32_t PCM_MONO_STEREO : 1;
uint32_t PCM_MONO_LR_SEL : 1;
uint32_t PCM_LOOPBACK : 1;
uint32_t PCM_CLKINV : 1;
uint32_t PCM_SLVBFMST : 1;
uint32_t PCM_SET_FRAME : 1;
uint32_t rsv_0 : 22;
}REG_PCM_GENCTRL_t;
/* PCM PHY CTRL Register */
typedef struct
{
uint32_t PCM_FSYNCSHP : 3;
uint32_t rsv_0 : 1;
uint32_t PCM_DOUTCFG : 2;
uint32_t rsv_1 : 2;
uint32_t PCM_LRCHPOL : 1;
uint32_t PCM_IOM : 1;
uint32_t PCM_LSB1ST : 1;
uint32_t rsv_2 : 1;
uint32_t PCM_SAMPSZ : 1;
uint32_t PCM_SAMPTYPE : 1;
uint32_t rsv_3 : 2;
uint32_t PCM_SLOTNB : 3;
uint32_t rsv_4 : 1;
uint32_t PCM_FIRSTACTSLOT : 2;
uint32_t rsv_5 : 10;
}REG_PCM_PHYCTRL_t;
/* PCM PHY CTRL Register */
typedef struct
{
uint32_t PCM_LSAMPPAD : 16;
uint32_t PCM_RSAMPPAD : 16;
}REG_PCM_PADDING_t;
/* PCM MUTE Register */
typedef struct
{
uint32_t PCM_MUTE_PATT : 16;
uint32_t rsv_0 : 15;
uint32_t PCM_MUTE_EN : 1;
}REG_PCM_MUTE_t;
/* -----------------------------------------------*/
/* I2S Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_I2S_CTRL0_t CTRL0; /* Offset 0x00 */
volatile REG_FRM_DIV_t FrmDiv; /* Offset 0x04 */
volatile REG_I2S_CTRL1_t CTRL1; /* Offset 0x08 */
volatile uint32_t DATA_L; /* Offset 0x0C */
volatile uint32_t DATA_R; /* Offset 0x10 */
volatile uint32_t INT_STATUS; /* Offset 0x14 */
volatile uint32_t INT_STATUS_EN; /* Offset 0x18 */
volatile REG_FIFO_CFG_t FIFO_CFG_L; /* Offset 0x1C */
volatile REG_FIFO_CFG_t FIFO_CFG_R; /* Offset 0x20 */
volatile REG_I2S_DMA_CFG_t DMA_CFG; /* Offset 0x24 */
volatile REG_PCM_GENCTRL_t PCM_GENCTRL; /* Offset 0x28 */
volatile REG_PCM_PHYCTRL_t PCM_RHYCTRL; /* Offset 0x2C */
volatile REG_PCM_PADDING_t PCM_PADDING; /* Offset 0x30 */
volatile REG_PCM_MUTE_t PCM_MUTE; /* Offset 0x34 */
}struct_I2S_t;
#define I2S0 ((struct_I2S_t *)I2S0_BASE)
#define I2S1 ((struct_I2S_t *)I2S1_BASE)
#define I2S2 ((struct_I2S_t *)I2S2_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup I2S_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
#define I2S_FIFO_DEPTH (32)
#define I2S_FIFO_HALF_DEPTH (I2S_FIFO_DEPTH >> 1)
/* FIFO Status start */
#define I2S_RX_FIFOS_FULL (0x00001)
#define I2S_RX_FIFOS_HALF_FULL (0x00002)
#define I2S_RX_FIFOS_EMPTY (0x00004)
#define I2S_RX_L_FIFO_FULL (0x00008)
#define I2S_RX_L_FIFO_HALF_FULL (0x00010)
#define I2S_RX_L_FIFO_EMPTY (0x00020)
#define I2S_RX_R_FIFO_FULL (0x00040)
#define I2S_RX_R_FIFO_HALF_FULL (0x00080)
#define I2S_RX_R_FIFO_EMPTY (0x00100)
#define I2S_TX_FIFOS_FULL (0x00200)
#define I2S_TX_FIFOS_ALMOST_EMPTY (0x00400)
#define I2S_TX_FIFOS_EMPTY (0x00800)
#define I2S_TX_L_FIFO_FULL (0x01000)
#define I2S_TX_L_FIFO_ALMOST_EMPTY (0x02000)
#define I2S_TX_L_FIFO_EMPTY (0x04000)
#define I2S_TX_R_FIFO_FULL (0x08000)
#define I2S_TX_R_FIFO_ALMOST_EMPTY (0x10000)
#define I2S_TX_R_FIFO_EMPTY (0x20000)
#define I2S_ALL_FIFO_STATUS (0x3FFFF)
/* FIFO Status end */
/* I2S Mode */
typedef enum
{
I2S_MODE_MASTER,
I2S_MODE_SLAVE,
}enum_I2S_Mode_t;
/* I2S Standard */
typedef enum
{
I2S_STANDARD_PHILIPS,
I2S_STANDARD_MSB,
I2S_STANDARD_LSB,
I2S_STANDARD_PCM,
}enum_I2S_Standard_t;
/* I2S Data Format */
typedef enum
{
I2S_DATA_FORMAT_8BIT,
I2S_DATA_FORMAT_16BIT,
I2S_DATA_FORMAT_20BIT,
I2S_DATA_FORMAT_24BIT,
I2S_DATA_FORMAT_32BIT,
}enum_I2S_DataFormat_t;
/* I2S Audio Frequency */
typedef enum
{
I2S_AUDIOFREQ_192000,
I2S_AUDIOFREQ_96000,
I2S_AUDIOFREQ_48000,
I2S_AUDIOFREQ_44100,
I2S_AUDIOFREQ_32000,
I2S_AUDIOFREQ_22050,
I2S_AUDIOFREQ_16000,
I2S_AUDIOFREQ_11025,
I2S_AUDIOFREQ_8000,
}enum_I2S_Audio_Frequency_t;
/*
* @brief I2S Init Structure definition
*/
typedef struct
{
uint32_t Mode; /*!< Specifies the I2S operating mode.
This parameter can be a value of @ref enum_I2S_Mode_t */
uint32_t Standard; /*!< Specifies the communication standard.
This parameter can be a value of @ref enum_I2S_Standard_t */
uint32_t DataFormat; /*!< Specifies the data format.
This parameter can be a value of @ref enum_I2S_DataFormat_t */
uint32_t BCLKDIV; /*!< Specifies the clock dividor used to generate bclk.
This parameter can be a even value of between 0x000 ~ 0xFFF. */
uint32_t ChannelLength; /*!< Specifies the channel length.
This parameter can be a even value of between 0x000 ~ 0xFFF. */
uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
This parameter can be a value of @ref I2S_Audio_Frequency */
}struct_I2SInit_t;
/*
* @brief PCM Init Structure definition
*/
typedef struct
{
#if defined(__ICCARM__)
uint32_t dummy; /* used to avoid compile error in IAR */
#endif
}struct_PCMInit_t;
/*
* @brief I2S handle Structure definition
*/
typedef struct __I2S_HandleTypeDef
{
struct_I2S_t *I2Sx; /*!< I2S registers base address */
struct_I2SInit_t Init; /*!< I2S communication parameters */
struct_PCMInit_t PCM_Init; /*!< PCM communication parameters */
volatile bool b_TxBusy;
void (*TxIntCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< Tx Interrupt Callback */
volatile bool b_RxBusy;
void (*RxIntCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< Rx Interrupt Callback */
}I2S_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* I2s and PCM Enable/Disable */
#define __I2S_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_EN = 1)
#define __I2S_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_EN = 0)
#define __I2S_PCM_ENABLE(__I2Sx__) do{ __I2Sx__->PCM_GENCTRL.PCM_PLL_EN = 1; \
__I2Sx__->PCM_GENCTRL.PCM_EN = 1;}while(0)
#define __I2S_PCM_DISABLE(__I2Sx__) do{ __I2Sx__->PCM_GENCTRL.PCM_PLL_EN = 0; \
__I2Sx__->PCM_GENCTRL.PCM_EN = 0;}while(0)
/* RxFIFO/TxFIFO clear */
#define __I2S_TxFIFO_CLR(__I2Sx__) do{ __I2Sx__->CTRL0.TXFF_R_CLR = 1; \
__I2Sx__->CTRL0.TXFF_L_CLR = 1;}while(0)
#define __I2S_RxFIFO_CLR(__I2Sx__) do{ __I2Sx__->CTRL0.RXFF_R_CLR = 1; \
__I2Sx__->CTRL0.RXFF_L_CLR = 1;}while(0)
/* TxFIFO/RxFIFO enable */
#define __I2S_TxFIFO_EN(__I2Sx__) do{ __I2Sx__->CTRL0.TXFF_L_EN = 1; \
__I2Sx__->CTRL0.TXFF_R_EN = 1; }while(0)
#define __I2S_RxFIFO_EN(__I2Sx__) do{ __I2Sx__->CTRL0.RXFF_L_EN = 1; \
__I2Sx__->CTRL0.RXFF_R_EN = 1;}while(0)
/* TxFIFO Data from sbcdecode or cpu*/
#define __I2S_TXFIFO_SOURCE_SBC_DECODE(__I2Sx__) (__I2Sx__->CTRL0.SBC_ACCESS = 1)
#define __I2S_TXFIFO_SOURCE_CPU(__I2Sx__) (__I2Sx__->CTRL0.SBC_ACCESS = 0)
/* enable channels Operate Simultaneously*/
#define __I2S_LR_WD_ENABLE(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_EN = 1)
#define __I2S_LR_WD_DISABLE(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_EN = 0)
#define __I2S_WD_SWAP_HIGH16SIZE_RIGHT(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_SWAP = 1)
#define __I2S_WD_SWAP_HIGH16SIZE_LEFT(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_SWAP = 0)
/* Status interrupt enable and disable */
#define __I2S_INT_ENABLE(__I2Sx__, __STATUS__) do{ __I2Sx__->CTRL0.INTEN = 1; \
__I2Sx__->INT_STATUS_EN |= __STATUS__;}while(0)
#define __I2S_INT_DISABLE(__I2Sx__, __STATUS__) do{ __I2Sx__->CTRL0.INTEN = 0; \
__I2Sx__->INT_STATUS_EN &= ~__STATUS__;}while(0)
#define __I2S_INT_IS_ENANLE(__I2Sx__, __STATUS__) (__I2Sx__->INT_STATUS_EN & __STATUS__)
/* Get interrupt status */
#define __I2S_GET_INT_STATUS(__I2Sx__) (__I2Sx__->INT_STATUS)
/* Left/Right Rxfifo txfifo full/empty level */
#define __I2S_L_RxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.RXFF_AFULL = __LEVEL__)
#define __I2S_L_RxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.RXFF_AEMPTY = __LEVEL__)
#define __I2S_L_TxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.TXFF_AFULL = __LEVEL__)
#define __I2S_L_TxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.TXFF_AEMPTY = __LEVEL__)
#define __I2S_R_RxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.RXFF_AFULL = __LEVEL__)
#define __I2S_R_RxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.RXFF_AEMPTY = __LEVEL__)
#define __I2S_R_TxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.TXFF_AFULL = __LEVEL__)
#define __I2S_R_TxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.TXFF_AEMPTY = __LEVEL__)
/* BCLK Inverted Output */
#define __I2S_BCLK_INV_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_BCLKINV = 1)
#define __I2S_BCLK_INV_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_BCLKINV = 0)
/* Frame Inverted Output */
#define __I2S_FRAME_INV_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_FRMINV = 1)
#define __I2S_FRAME_INV_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_FRMINV = 0)
/* PCMCLK Inverted Output */
#define __I2S_PCMCLK_INV_ENABLE(__I2Sx__) (__I2Sx__->PCM_GENCTRL.PCM_CLKINV = 1)
#define __I2S_PCMCLK_INV_DISABLE(__I2Sx__) (__I2Sx__->PCM_GENCTRL.PCM_CLKINV = 0)
/* PCM SLOTS SET */
#define __I2S_PCM_SLOTS_SET(__I2Sx__, __LEVEL__) (__I2Sx__->PCM_RHYCTRL.PCM_SLOTNB = __LEVEL__)
#define __I2S_PCM_FIRSTSLOTS_SET(__I2Sx__, __CONFIGURE__) (__I2Sx__->PCM_RHYCTRL.PCM_FIRSTACTSLOT = __CONFIGURE__)
/* PCM SAMPLE SIZE SELECT */
#define __I2S_PCM_SAMPLESIZE_8BIT(__I2Sx__) (__I2Sx__->PCM_RHYCTRL.PCM_SAMPSZ = 0)
#define __I2S_PCM_SAMPLESIZE_16BIT(__I2Sx__) (__I2Sx__->PCM_RHYCTRL.PCM_SAMPSZ = 1)
/* DMA Request Level */
#define __I2S_TX_DMA_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->DMA_CFG.DMATDLR = __LEVEL__)
#define __I2S_RX_DMA_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->DMA_CFG.DMARDLR = __LEVEL__)
/* Exported functions --------------------------------------------------------*/
/* i2s_init */
void i2s_init(I2S_HandleTypeDef *hi2s);
/* i2s_init */
void i2s_deinit(I2S_HandleTypeDef *hi2s);
/* i2s_transmit_IT */
bool i2s_transmit_IT(I2S_HandleTypeDef *hi2s);
/* i2s_receive_IT */
bool i2s_receive_IT(I2S_HandleTypeDef *hi2s);
/* i2s_IRQHandler */
void i2s_IRQHandler(I2S_HandleTypeDef *hi2s);
/* i2s_read_data */
uint32_t i2s_read_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples);
/* i2s_send_data */
uint32_t i2s_send_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples);
/* i2s_transmit_DMA */
void i2s_transmit_DMA(I2S_HandleTypeDef *hi2s);
/* i2s_receive_DMA */
void i2s_receive_DMA(I2S_HandleTypeDef *hi2s);
#endif