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。
以下以全功能的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
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
#define EXAMPLE_I2S_TRANS_SIZE (480)
static uint8_t pData[EXAMPLE_I2S_TRANS_SIZE];
#if CLOCK_USING_XTAL
#else
#endif