思澈科技软件开发工具包  2.20
I2S

I2S HAL 提供用于访问 I2S 外设寄存器的基本 API。 SF32LB55X有两个实例I2S1/I2S2(都在HPSYS),SF32LB58X有三个实例I2S1/I2S2/I2S3(I2S1和I2S2在HPSYS,I2S3在LPSYS)。 对于 I2S1,它只支持 RX 功能, 对于 I2S2/I2S3,它支持 RX 和 TX。 当使用 I2S2 RX 时,它的时钟来自它的 TX,所以如果使用 I2S2 作为 RX,它的 TX 也需要使能提供时钟。 SF32LB56X只有一个全功能的I2S1,相当于SF32LB58X的I2S2,支持RX和TX。 SF32LB55X的时钟只能是xtal48M,SF32LB58X和SF32LB56X的时钟可以是xtal48M或PLL。

Note
SF32LB52X与SF32LB56X相同。

主要功能包括:

  • 多个实例支持。
  • 接收/发送支持。
  • DMA/中断模式支持。
  • 主/从模式支持。

使用 I2S HAL 驱动程序

以下以全功能的I2S为例进行描述,当I2S作为maser模式时,RX的时钟是由TX进行提供的,因此tx_cfg中的slave_mode要配置成0,rx_cfg中的slave_mode配置成1。 当I2S作为SLAVE模式时,时钟是由外部的I2S提供,因此tx_cfg和rx_cfg中的slave_mode都要配置成1。 使用xtal48M作为时钟源时,bclk和lrclk的时序可能无法满足对方I2S的需求(这个需要注意),使用PLL作为时钟源时,需要打开audcodec模块,并且保证所有音频模块的时钟一致。 可以参考drv_i2s中的实现。

#define CLOCK_USING_XTAL 0 //PLL clock need open audcodec
#if CLOCK_USING_XTAL //crystal
static CLK_DIV_T txrx_clk_div[9] = {{48000, 125, 125, 5}, {44100, 136, 136, 4}, {32000, 185, 190, 5}, {24000, 250, 250, 10}, {22050, 272, 272, 8},
{16000, 384, 384, 12}, {12000, 500, 500, 20}, {11025, 544, 544, 16}, { 8000, 750, 750, 30}
};
#else //PLL
//PLL 16k 49.152M 44.1k 45.1584M
//lrclk_duty_high:PLL/spclk_div/samplerate/2: 64=49.152M/48k/8/2
//bclk:lrclk_duty_high/32
static CLK_DIV_T txrx_clk_div[9] = {{48000, 64, 64, 2}, {44100, 64, 64, 2}, {32000, 96, 96, 3}, {24000, 128, 128, 4}, {22050, 128, 128, 4},
{16000, 192, 192, 6}, {12000, 256, 256, 8}, {11025, 256, 256, 8}, { 8000, 384, 384, 12}
};
#endif
/* initial I2S controller */
#define EXAMPLE_I2S_TRANS_SIZE (480)
static I2S_HandleTypeDef i2s_handle;
static uint8_t pData[EXAMPLE_I2S_TRANS_SIZE];
I2S_HandleTypeDef *hi2s = &i2s_handle;
hi2s->Instance = hwp_i2s2;
HAL_RCC_EnableModule(RCC_MOD_I2S2);
/* Initial tx configure*/
hi2s->Init.tx_cfg.data_dw = 16; // bit width 16
hi2s->Init.tx_cfg.pcm_dw = 16;
hi2s->Init.tx_cfg.bus_dw = 32;
hi2s->Init.tx_cfg.slave_mode = 0; // master mode
hi2s->Init.tx_cfg.track = 0; // default stereo
hi2s->Init.tx_cfg.vol = 4; // default set to mute(15) or 0 db (4)
hi2s->Init.tx_cfg.balance_en = 0;
hi2s->Init.tx_cfg.balance_vol = 0;
hi2s->Init.tx_cfg.chnl_sel = 0;
hi2s->Init.tx_cfg.lrck_invert = 0;
hi2s->Init.tx_cfg.sample_rate = 16000;
hi2s->Init.tx_cfg.extern_intf = 0;
hi2s->Init.tx_cfg.clk_div_index = 5;//for 16k samplerate
hi2s->Init.tx_cfg.clk_div = &txrx_clk_div[hi2s->Init.tx_cfg.clk_div_index];
/* Initial rx configure*/
hi2s->Init.rx_cfg.data_dw = 16;
hi2s->Init.rx_cfg.pcm_dw = 16;
hi2s->Init.rx_cfg.bus_dw = 32;
hi2s->Init.rx_cfg.slave_mode = 1; // slave mode
hi2s->Init.rx_cfg.chnl_sel = 0; // left/right all set to left
hi2s->Init.rx_cfg.sample_rate = 16000;
hi2s->Init.rx_cfg.chnl_sel = 0; // default stereo
hi2s->Init.rx_cfg.lrck_invert = 0;
hi2s->Init.rx_cfg.clk_div_index = 5;//for 16k samplerate
hi2s->Init.rx_cfg.clk_div = &txrx_clk_div[hi2s->Init.rx_cfg.clk_div_index];
#if CLOCK_USING_XTAL
__HAL_I2S_CLK_XTAL(hi2s); // xtal use 48M for asic
__HAL_I2S_SET_SPCLK_DIV(hi2s, 4); // set to 12M to i2s
#else
__HAL_I2S_CLK_PLL(hi2s); //PLL
__HAL_I2S_SET_SPCLK_DIV(hi2s, 8); // set to 6.144M to i2s PLL
bf0_enable_pll(hi2s->Init.tx_cfg.sample_rate, 0);
#endif
/*Initial I2S controller */
HAL_I2S_Init(hi2s);
/*Start I2S TX test */
/* reconfigure I2S TX before start if any changed*/
/* Start I2S transmit with polling mode */
ret = HAL_I2S_Transmit(hi2s, pData, EXAMPLE_I2S_TRANS_SIZE, 100);
/*End I2S TX test */
/*Start I2S RX test */
/* reconfigure I2S RX before start if any changed*/
/* For I2S2, RX clock from TX, so need enable TX when start RX */
/* Start I2S Receive with polling mode */
ret = HAL_I2S_Receive(hi2s, pData, EXAMPLE_I2S_TRANS_SIZE, 100);
/*Check received data */
// pData
I2S_CFG_T::vol
uint8_t vol
Definition: bf0_hal_i2s.h:97
HAL_RCC_EnableModule
void HAL_RCC_EnableModule(RCC_MODULE_TYPE module)
Enable module if it's disabled.
I2S_CFG_T::balance_vol
uint8_t balance_vol
Definition: bf0_hal_i2s.h:99
I2S_HandleTypeDef::Init
I2S_InitTypeDef Init
Definition: bf0_hal_i2s.h:141
I2S_CFG_T::chnl_sel
uint8_t chnl_sel
Definition: bf0_hal_i2s.h:93
I2S_CFG_T::pcm_dw
uint8_t pcm_dw
Definition: bf0_hal_i2s.h:101
HAL_I2S_Transmit
HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint8_t *pData, uint32_t Size, uint32_t Timeout)
Set I2S Transmit data with polling mode.
CLK_DIV_T
I2S bclk lrck divder table structure definition.
Definition: bf0_hal_i2s.h:76
HAL_I2S_Init
HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
Initializes the I2S according to the specified parameters in the I2S_InitTypeDef and create the assoc...
__HAL_I2S_CLK_PLL
#define __HAL_I2S_CLK_PLL(__HANDLE__)
Set the I2S clock from pll.
Definition: bf0_hal_i2s.h:396
__HAL_I2S_CLK_XTAL
#define __HAL_I2S_CLK_XTAL(__HANDLE__)
Set the I2S clock from crystal.
Definition: bf0_hal_i2s.h:390
HAL_I2S_Receive
HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint8_t *pData, uint32_t Size, uint32_t Timeout)
Set I2S receive data with polling mode.
I2S_CFG_T::track
uint8_t track
Definition: bf0_hal_i2s.h:92
I2S_CFG_T::balance_en
uint8_t balance_en
Definition: bf0_hal_i2s.h:98
I2S_HandleTypeDef
I2S handle Structure definition.
Definition: bf0_hal_i2s.h:138
I2S_CFG_T::data_dw
uint8_t data_dw
Definition: bf0_hal_i2s.h:90
HAL_StatusTypeDef
HAL_StatusTypeDef
HAL Status structures definition.
Definition: bf0_hal_def.h:74
HAL_I2S_Config_Transmit
HAL_StatusTypeDef HAL_I2S_Config_Transmit(I2S_HandleTypeDef *hi2s, I2S_CFG_T *cfg)
Set I2S transmit configures.
I2S_CFG_T::slave_mode
uint8_t slave_mode
Definition: bf0_hal_i2s.h:91
__HAL_I2S_TX_ENABLE
#define __HAL_I2S_TX_ENABLE(__HANDLE__)
Enable the specified I2S TX peripheral .
Definition: bf0_hal_i2s.h:273
I2S_CFG_T::lrck_invert
uint8_t lrck_invert
Definition: bf0_hal_i2s.h:94
I2S_CFG_T::extern_intf
uint8_t extern_intf
Definition: bf0_hal_i2s.h:100
I2S_CFG_T::clk_div_index
uint8_t clk_div_index
Definition: bf0_hal_i2s.h:102
I2S_HandleTypeDef::Instance
I2S_TypeDef * Instance
Definition: bf0_hal_i2s.h:139
I2S_CFG_T::bus_dw
uint8_t bus_dw
Definition: bf0_hal_i2s.h:89
HAL_I2S_Config_Receive
HAL_StatusTypeDef HAL_I2S_Config_Receive(I2S_HandleTypeDef *hi2s, I2S_CFG_T *cfg)
Set I2S Receive configures.
__HAL_I2S_SET_SPCLK_DIV
#define __HAL_I2S_SET_SPCLK_DIV(__HANDLE__, __DIV__)
Set the I2S SP clock divider.
Definition: bf0_hal_i2s.h:403
I2S_InitTypeDef::rx_cfg
I2S_CFG_T rx_cfg
Definition: bf0_hal_i2s.h:117
I2S_InitTypeDef::tx_cfg
I2S_CFG_T tx_cfg
Definition: bf0_hal_i2s.h:116
I2S_CFG_T::sample_rate
uint32_t sample_rate
Definition: bf0_hal_i2s.h:95