使用WM-W800-SDK-202207-V1.00.08工程。
对ES8311使用I2C进行配置后,无法使用I2S进行读取,读取过程一直等待。不知道问题出现在哪里,是ES8311和I2S的配置错误,还是我使用方式有误。
代码如下:
#ifndef __I2C_H__
#define __I2C_H__
#include "wm_gpio.h"
#include "wm_gpio_afsel.h"
#include "wm_i2c.h"
#define I2C_FREQ (100 * 1000)
#define I2C_SCL WM_IO_PA_01 // 控制线
#define I2C_SDA WM_IO_PA_04 // 数据线
/**
* @brief I2C 初始化
*/
static inline void i2c_init(void)
{
// 配置引脚
wm_i2c_scl_config(I2C_SCL);
wm_i2c_sda_config(I2C_SDA);
// 设置时钟频率
tls_i2c_init(I2C_FREQ);
}
#endif
#ifndef __I2S_H__
#define __I2S_H__
#include "wm_gpio.h"
#include "wm_gpio_afsel.h"
#include "wm_i2s.h"
#include "wm_pwm.h"
#define I2S_MCLK WM_IO_PB_07
#define I2S_BCLK WM_IO_PB_08
#define I2S_LRCK WM_IO_PB_09
#define I2S_DI WM_IO_PB_10
#define I2S_DO WM_IO_PB_11
/**
* @brief I2S 初始化
*/
static inline void i2s_init(void)
{
wm_i2s_ck_config(I2S_BCLK);
wm_i2s_ws_config(I2S_LRCK);
wm_i2s_di_config(I2S_DI);
wm_i2s_do_config(I2S_DO);
}
static inline void i2s_mclk_out(u8 div)
{
u8 channel = 4;
tls_pwm_stop(channel);
wm_pwm4_config(I2S_MCLK); // I2S_MCLK attention
tls_pwm_out_mode_config(channel, WM_PWM_OUT_MODE_INDPT);
tls_pwm_cnt_type_config(channel, WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT);
tls_pwm_freq_config(channel, 0, div - 1);
tls_pwm_duty_config(channel, (div - 1) / 2);
tls_pwm_loop_mode_config(channel, WM_PWM_LOOP_TYPE_LOOP);
tls_pwm_out_inverse_cmd(channel, DISABLE);
tls_pwm_output_en_cmd(channel, WM_PWM_OUT_EN_STATE_OUT);
tls_pwm_start(channel);
}
#endif
#include "driver/es8311.h"
#include "wm_gpio.h"
#include "wm_gpio_afsel.h"
#include "wm_i2c.h"
#include "wm_pwm.h"
#include "util/error.h"
static u8 init_data[][2] = {
{0x00, 0x1F},
{0x45, 0x00},
{0x01, 0x30},
{0x02, 0x90},
{0x03, 0x19},
{0x16, 0x03},
{0x04, 0x19},
{0x05, 0x00},
{0x06, 0x0F},
{0x07, 0x01},
{0x08, 0xFF},
{0x0B, 0x00},
{0x0C, 0x00},
{0x10, 0x1F},
{0x11, 0x7F},
{0x00, 0xC0},
{0x0D, 0x01},
{0x01, 0x3F},
{0x14, 0x1A},
{0x12, 0x00},
{0x13, 0x10},
{0x09, 0x0C},
{0x0A, 0x0C},
{0x0E, 0x02},
{0x0F, 0x44},
{0x15, 0x00},
{0x1B, 0x05},
{0x1C, 0x65},
{0x17, 0xFF}, // ADC volume 0xBF = 0
{0x37, 0x08},
{0x32, 0xFF}, // DAC volume 0xBF = 0
{0x44, 0x00}, // loopback test。on:0x88; off:0x00; mic-->speak
};
int es8311_i2c_get_reg(u8 addr, u8 *val)
{
tls_i2c_write_byte(ES8311_I2C_ADDRW, 1);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
tls_i2c_write_byte(addr, 0);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
tls_i2c_write_byte(ES8311_I2C_ADDRR, 1);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
*val = tls_i2c_read_byte(0, 1);
return WM_SUCCESS;
err:
LOG("es8311 i2c get reg fail");
return WM_FAILED;
}
int es8311_i2c_set_reg(u8 addr, u8 val)
{
tls_i2c_write_byte(ES8311_I2C_ADDRW, 1);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
tls_i2c_write_byte(addr, 0);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
tls_i2c_write_byte(val, 0);
GOTO_IF(tls_i2c_wait_ack() == WM_SUCCESS, err);
tls_i2c_stop();
return WM_SUCCESS;
err:
LOG("es8311 i2c set reg fail");
return WM_FAILED;
}
int es8311_init(void)
{
for (size_t i = 0; i < sizeof(init_data) / sizeof(init_data[0]); i++)
{
GOTO_IF(es8311_i2c_set_reg(init_data[i][0], init_data[i][1]) == WM_SUCCESS, err);
tls_os_time_delay(10); // 防止速度过快
}
return WM_SUCCESS;
err:
LOG("es8311 init fail");
return WM_FAILED;
}
#include "wm_include.h"
#include "driver/es8311.h"
#include "driver/i2c.h"
#include "driver/i2s.h"
#include "util/debug.h"
#define DEMO_DATA_SIZE (1024)
static u32 i2s_demo_rx[DEMO_DATA_SIZE] = {0};
static void show_rx_data(u16 len)
{
printf("recv %d\r\n", len);
for (u16 i = 0; i < len; i++)
{
printf("%08X ", i2s_demo_rx[i]);
if (i % 16 == 15)
{
printf("\n");
}
}
}
void callback(uint32_t *data, uint16_t *len)
{
printf("x\n");
}
void i2s_config(void)
{
I2S_InitDef opts = {
.I2S_Mode_MS = I2S_MODE_SLAVE,
.I2S_Mode_SS = I2S_CTRL_MONO,
.I2S_Mode_LR = I2S_LEFT_CHANNEL,
.I2S_Trans_STD = I2S_Standard,
.I2S_DataFormat = I2S_DataFormat_16,
.I2S_AudioFreq = 12500,
.I2S_MclkFreq = 8000000,
};
wm_i2s_port_init(&opts);
wm_i2s_register_callback(NULL);
}
void UserMain(void)
{
i2c_init();
i2s_init();
printf("[i2c] init \n");
printf("[i2s] init \n");
i2s_mclk_out(5);
printf("[i2s] mclk out \n");
DBG(es8311_init() == WM_SUCCESS);
printf("[es8311] init \n");
printf("[i2s] read start \n");
i2s_config();
wm_i2s_rx_int((int16_t *)i2s_demo_rx, DEMO_DATA_SIZE); // 在此处无限等待
show_rx_data(DEMO_DATA_SIZE);
printf("[i2s] read end \n");
while (1)
{
tls_os_time_delay(1000);
}
}
推荐参考这个SDK,里面有现成的codec驱动代码。http://ask.winnermicro.com/article/74.html