音频编码ES7210调试笔记(一)

ES7210初始化程序的解读

最近买了立创的实战派S3成品开发板,学习过程中,对音频编码器ES7210的初始化有些不理解,但找不到什么资料,对寄存器知道的太少,所以只好从源码下手,一点点解读,现记录如下,便于移植时备查。以下顺序均按官方初始化流程进行,使用I2C进行通信完成初始化设置。

软件复位 /* Perform software reset */

先给0X00寄存器写入0XFF,再写入0X32,恢复默认值

配置时隙/* Set the initialization time when device powers up */

向0X09和0X0A寄存器都写入0X30,应该是起配合设置时隙形成不同时分复用的通道作用

配置滤波/* Configure HPF for ADC1-4 */

向0X20至0X23寄存器写入数值,顺序是倒的23(0X2A)-22(0X0A)-21(0X2A)-20(0X0A),这块是关是各个模数转换时高通滤波器的功能配置

设置采样位数,信号标准,时分多址/* Set bits per sample to 16, data protocal to I2S, enable 1xFS TDM */

官方的变量i2s_format为0X00是I2S标准模式,也即飞利浦模式,0X01是左对齐模式,还有两种是DSP-A(0X03)DSP-B(0X13),占用了0X11寄存器低5位
官方的bit_width变量为0X60是位宽,我理解为就是单次采样的位深,常用的是16位,对应的值(0X60),可选的值有0X20,0X40,0X60,0X80,占用了0X11寄存器高3位
官方的变量flags.tdm_enable(0X01)为 TDM模式
这里需要注意的是,TDM模式下,寄存器0X12需要根据I2S信号模式来赋值,即与i2s_format有关
标准模式和左对齐模式下,0X12寄存器值应写入0X02,DSP-A,DSP-B模式下,0X12寄存器值0X01,非TDM模式,0X12寄存器值应写入0X00

这段初始化的内容就是
向0X11寄存器写入0X60 (i2s_format(0x00) | bit_width(0X60))
向0X12寄存器写入0X02

配置模拟电源以及增益/* Configure analog power and VMID voltage */

向0X40寄存器写入0X3C

分别对MIC1-4通道配置电压,和选配的MIC有关/* Set MIC1-4 bias to 2.87V */

向0X41寄存器写入0X70,可选值用了BIT.4,BIT.5,BIT.6,正好3位,值取1到7,控制MIC1-2的偏置电压
向0X42寄存器写入0X70,可选值用了BIT.4,BIT.5,BIT.6,正好3位,值取1到7,控制MIC3-4的偏置电压

分别对MIC1-4通道配置麦克风增益/* Set MIC1-4 gain to 30dB */

向0X43寄存器写入10(0X0A),配置MIC1增益,数值*3dB
向0X44寄存器写入10(0X0A),配置MIC2增益,同上
向0X45寄存器写入10(0X0A),配置MIC3增益,同上
向0X46寄存器写入10(0X0A),配置MIC4增益,同上

打开MIC1-4前置放大器电源/* Power on MIC1-4 */

向0X47至0X4A都写入0X08,对应MIC1-41-4

设置采样频率/* Set ADC sample rate to 48kHz */

这段程序比较绕,我一开始没看懂,算了半天总对不上程序,后来才发现官方是查表得出数据的。
官方设置了采样率为48K,MCLK=采样率*256=12.288MHz,i2s为了对齐采样率和信息的传输时钟,可能不同频率下算法不一样,官方并未直接用这两个数据进行计算赋值,而是根据查表比对,从事先固定的表中查出对应的数据,用该数据进行设置,确保对齐.
表的内容为:

/**
 * @brief ES7210 clock coefficient lookup table
 *
 */
static const coeff_div_t es7210_coeff_div[] = {
//    mclk      lrck    ss_ds adc_div  dll  doubler osr  mclk_src  lrckh   lrckl
    /* 8k */
    {12288000,  8000,  0x00,  0x03,  0x01,  0x00,  0x20,  0x00,    0x06,  0x00},
    {16384000,  8000,  0x00,  0x04,  0x01,  0x00,  0x20,  0x00,    0x08,  0x00},
    {19200000,  8000,  0x00,  0x1e,  0x00,  0x01,  0x28,  0x00,    0x09,  0x60},
    {4096000,   8000,  0x00,  0x01,  0x01,  0x00,  0x20,  0x00,    0x02,  0x00},

    /* 11.025k */
    {11289600,  11025,  0x00,  0x02,  0x01,  0x00,  0x20,  0x00,    0x01,  0x00},

    /* 12k */
    {12288000,  12000,  0x00,  0x02,  0x01,  0x00,  0x20,  0x00,    0x04,  0x00},
    {19200000,  12000,  0x00,  0x14,  0x00,  0x01,  0x28,  0x00,    0x06,  0x40},

    /* 16k */
    {4096000,   16000,  0x00,  0x01,  0x01,  0x01,  0x20,  0x00,    0x01,  0x00},
    {19200000,  16000,  0x00,  0x0a,  0x00,  0x00,  0x1e,  0x00,    0x04,  0x80},
    {16384000,  16000,  0x00,  0x02,  0x01,  0x00,  0x20,  0x00,    0x04,  0x00},
    {12288000,  16000,  0x00,  0x03,  0x01,  0x01,  0x20,  0x00,    0x03,  0x00},

    /* 22.05k */
    {11289600,  22050,  0x00,  0x01,  0x01,  0x00,  0x20,  0x00,    0x02,  0x00},

    /* 24k */
    {12288000,  24000,  0x00,  0x01,  0x01,  0x00,  0x20,  0x00,    0x02,  0x00},
    {19200000,  24000,  0x00,  0x0a,  0x00,  0x01,  0x28,  0x00,    0x03,  0x20},

    /* 32k */
    {12288000,  32000,  0x00,  0x03,  0x00,  0x00,  0x20,  0x00,    0x01,  0x80},
    {16384000,  32000,  0x00,  0x01,  0x01,  0x00,  0x20,  0x00,    0x02,  0x00},
    {19200000,  32000,  0x00,  0x05,  0x00,  0x00,  0x1e,  0x00,    0x02,  0x58},

    /* 44.1k */
    {11289600,  44100,  0x00,  0x01,  0x01,  0x01,  0x20,  0x00,    0x01,  0x00},

    /* 48k */
    {12288000,  48000,  0x00,  0x01,  0x01,  0x01,  0x20,  0x00,    0x01,  0x00},
    {19200000,  48000,  0x00,  0x05,  0x00,  0x01,  0x28,  0x00,    0x01,  0x90},

    /* 64k */
    {16384000,  64000,  0x01,  0x01,  0x01,  0x00,  0x20,  0x00,    0x01,  0x00},
    {19200000,  64000,  0x00,  0x05,  0x00,  0x01,  0x1e,  0x00,    0x01,  0x2c},

    /* 88.2k */
    {11289600,  88200,  0x01,  0x01,  0x01,  0x01,  0x20,  0x00,    0x00,  0x80},

    /* 96k */
    {12288000,  96000,  0x01,  0x01,  0x01,  0x01,  0x20,  0x00,    0x00,  0x80},
    {19200000,  96000,  0x01,  0x05,  0x00,  0x01,  0x28,  0x00,    0x00,  0xc8},
};

该表对应的结构体如下:

typedef struct {
    uint32_t mclk;            /*!< mclk frequency */
    uint32_t lrck;            /*!< lrck */
    uint8_t  ss_ds;           /*!< not used */
    uint8_t  adc_div;         /*!< adcclk divider */
    uint8_t  dll;             /*!< dll_bypass */
    uint8_t  doubler;         /*!< doubler enable */
    uint8_t  osr;             /*!< adc osr */
    uint8_t  mclk_src;        /*!< select mclk  source */
    uint32_t lrck_h;          /*!< The high 4 bits of lrck */
    uint32_t lrck_l;          /*!< The low 8 bits of lrck */
} coeff_div_t;

官方的查表程序

static const coeff_div_t *es7210_get_coeff(uint32_t mclk, uint32_t lrck)
{
    for (int i = 0; i < sizeof(es7210_coeff_div) / sizeof(coeff_div_t); i++) {
        if (es7210_coeff_div[i].lrck == lrck && es7210_coeff_div[i].mclk == mclk) {
            return &es7210_coeff_div[i];
        }
    }
    return NULL;
}

根据MCLK=12288000(48000*256),LRCK=48000,查表得知OSR=0X20,(adc_div|doubler<<6|dll<<7)=(0x01|0x01<<6|0x01<<7)=0xC1,LRCK高8位=0X01,LRCK低8位=0X00

于是,这段初始化的内容简化后就是
向0X07寄存器写入0X20
向0X02寄存器写入0XC1
向0X04寄存器写入0X01
向0X05寄存器写入0X00

/* Power down DLL */

不太明白,但照做就行了
向0X06寄存器写入0X04

打开麦克风供电/* Power on MIC1-4 bias & ADC1-4 & PGA1-4 Power */

向寄存器0X4B,0X4C都写入0X0F

/* Enable device */

先给0X00寄存器写入0X71,再写入0X41,相比0X32,即先BIT.6置1,BIT.1置0,BIT.0置1,再BIT.6置0

调整麦克风音量

另外还有个0X1B至0X1E寄存器可以分别给四个MIC通道调音量,值为191 + volume_db * 2,其中volume_db >= -95 && volume_db <= 32,
官方参考值volume_db=0

程序最终简化为以下这一段.

//通过I2C初始化ES7210工作在tdm模式,I2S信号为标准模式,采样率48000,位宽16
void init_es7210(void)
{
	i2c_Write_es7210(0x00,0xff);
	i2c_Write_es7210(0x00,0x32);
	i2c_Write_es7210(0x09,0x30);
	i2c_Write_es7210(0x0a,0x30);
	i2c_Write_es7210(0x23,0x2a);
	i2c_Write_es7210(0x22,0x0a);
	i2c_Write_es7210(0x21,0x2a);
	i2c_Write_es7210(0x20,0x0a);
	i2c_Write_es7210(0x11,0x60);
	i2c_Write_es7210(0x12,0x02);
	i2c_Write_es7210(0x40,0x3c);
	i2c_Write_es7210(0x41,0x70);
	i2c_Write_es7210(0x42,0x70);
	i2c_Write_es7210(0x43,0x1a);
	i2c_Write_es7210(0x44,0x1a);
	i2c_Write_es7210(0x45,0x1a);
	i2c_Write_es7210(0x46,0x1a);
	i2c_Write_es7210(0x47,0x08);
	i2c_Write_es7210(0x48,0x08);
	i2c_Write_es7210(0x49,0x08);
	i2c_Write_es7210(0x4a,0x08);
	i2c_Write_es7210(0x07,0x20);
	i2c_Write_es7210(0x02,0xc1);
	i2c_Write_es7210(0x04,0x01);
	i2c_Write_es7210(0x05,0x00);
	i2c_Write_es7210(0x06,0x00);
	i2c_Write_es7210(0x4b,0x0f);
	i2c_Write_es7210(0x4c,0x0f);
	i2c_Write_es7210(0x00,0x71);
	i2c_Write_es7210(0x00,0x41);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值