Gitee仓库:https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/dev/team_x/demo_record_pen
一、Codec介绍
WM8978为DAC+ADC芯片,本身并不具备编解码的功能,一方面,可通过I2S接口接收PCM数据,转为模拟信号输出,此为DAC过程,即放音;一方面,可接收模拟信号转为数字信号,通过I2S接口传输给MCU,此为ADC过程,即录音。WM8978还使用I2C接口配置其工作参数,比如音量,EQ,3D环绕等。WM8978本身可直连1W/8欧的小喇叭。
引脚配置:
1、I2S和I2C的使能
首先需要打开config下usr_config.mk文件,打开编译I2S和I2C的使能
2、导入lal_audio文件
打开使能后进行编译,导入lal_audio文件,可见wm8978_init函数,对引脚进行使能:
3、WM8978的I2C配置
WM8978需要使用I2C引脚对输入方式、喇叭音量、输入增益等等进行控制,详情可见lal_audio中其它函数
如上图,进行初始化后即可对录音和放音进行测试;
4、WM8978录音测试
其中需要用到I2S的读写函数,本文件中设置的采集频率和位宽是16K和16位(方便后续语音识别)
使用二维数组缓存的方式进行读取和播放,经验证后满足要求。
hi_u32 WM8978_Write_Reg(hi_u8 reg, hi_u16 val)
{
hi_i2c_data i2c_data;
hi_u8 send_data[2]= { 0 };
send_data[0] = (reg<<1)|((val>>8)&0X01);
send_data[1] = val&0XFF;
i2c_data.send_buf = send_data;
i2c_data.send_len = 2;
wm8978_register_tbl[reg] = val;
return hi_i2c_write(HI_I2C_IDX_1,(WM8978_DEVICE_ADDR<<1), &i2c_data);
}
hi_u32 WM8978_Read_Reg(hi_u8 reg)
{
return wm8978_register_tbl[reg];
}
void WM8978_AUX_Gain(hi_u8 gain)
{
hi_u16 regval;
gain&=0X07;
regval=WM8978_Read_Reg(47);
regval&=~(7<<0);
WM8978_Write_Reg(47,regval|gain<<0);
regval=WM8978_Read_Reg(48);
regval&=~(7<<0);
WM8978_Write_Reg(48,regval|gain<<0);
}
void WM8978_Output_Cfg(hi_u8 dacen,hi_u8 bpsen)
{
hi_u16 regval=0;
if(dacen)regval|=1<<0;
if(bpsen)
{
regval|=1<<1;
regval|=5<<2;
}
WM8978_Write_Reg(50,regval);
WM8978_Write_Reg(51,regval);
}
void WM8978_MIC_Gain(hi_u8 gain)
{
gain&=0X3F;
WM8978_Write_Reg(45,gain);
WM8978_Write_Reg(46,gain|1<<8);
}
void WM8978_LINEIN_Gain(hi_u8 gain)
{
hi_u16 regval;
gain&=0X07;
regval=WM8978_Read_Reg(47);
regval&=~(7<<4);
WM8978_Write_Reg(47,regval|gain<<4);
regval=WM8978_Read_Reg(48);
regval&=~(7<<4);
WM8978_Write_Reg(48,regval|gain<<4);
}
void WM8978_ADDA_Cfg(hi_u8 dacen,hi_u8 adcen)
{
hi_u16 regval;
regval=WM8978_Read_Reg(3);
if(dacen)regval|=3<<0;
else regval&=~(3<<0);
WM8978_Write_Reg(3,regval);
regval=WM8978_Read_Reg(2);
if(adcen)regval|=3<<0;
else regval&=~(3<<0);
WM8978_Write_Reg(2,regval);
}
void WM8978_Input_Cfg(hi_u8 micen,hi_u8 lineinen,hi_u8 auxen)
{
hi_u16 regval;
regval=WM8978_Read_Reg(2);
if(micen)regval|=3<<2;
else regval&=~(3<<2);
WM8978_Write_Reg(2,regval);
regval=WM8978_Read_Reg(44);
if(micen)regval|=3<<4|3<<0;
else regval&=~(3<<4|3<<0);
WM8978_Write_Reg(44,regval);
if(lineinen)WM8978_LINEIN_Gain(5);
else WM8978_LINEIN_Gain(0);
if(auxen)WM8978_AUX_Gain(7);
else WM8978_AUX_Gain(0);
}
void WM8978_I2S_Cfg(hi_u8 fmt,hi_u8 len)
{
fmt&=0X03;
len&=0X03;
WM8978_Write_Reg(4,(fmt<<3)|(len<<5));
}
void WM8978_HPvol_Set(hi_u8 voll,hi_u8 volr)
{
voll&=0X3F;
volr&=0X3F;
if(voll==0)voll|=1<<6;
if(volr==0)volr|=1<<6;
WM8978_Write_Reg(52,voll);
WM8978_Write_Reg(53,volr|(1<<8));
}
void WM8978_SPKvol_Set(hi_u8 volx)
{
volx&=0X3F;
if(volx==0)volx|=1<<6;
WM8978_Write_Reg(54,volx);
WM8978_Write_Reg(55,volx|(1<<8));
}
void I2C_TEST()
{
hi_u32 ret;
hi_io_set_func(HI_IO_NAME_GPIO_0, HI_IO_FUNC_GPIO_0_I2C1_SDA);
hi_io_set_func(HI_IO_NAME_GPIO_1, HI_IO_FUNC_GPIO_1_I2C1_SCL);
ret = hi_i2c_deinit(HI_I2C_IDX_1);
if (ret != HI_ERR_SUCCESS) {
printf("I2C delete error\r\n");
return;
}
ret = hi_i2c_init(HI_I2C_IDX_1, 100000);
if (ret != HI_ERR_SUCCESS) {
printf("I2C error\r\n");
return;
}
printf("IIC sucessfully\r\n");
ret = WM8978_Write_Reg(0,0);
if (ret != HI_ERR_SUCCESS) {
printf("8978 error\r\n");
printf("flash partition table init fail:0x%x \r\n", ret);
return;
}
printf("8978 pass\r\n");
}
|