无法通过I2S读取ES8311的音频数据

发布于 2023-01-06 09:39:36

使用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);
    }
}

查看更多

关注者
0
被浏览
2.2k
isme
isme 认证专家 2023-01-06
冰镇大西瓜

推荐参考这个SDK,里面有现成的codec驱动代码。http://ask.winnermicro.com/article/74.html

2 个回答
Magical_Lin
Magical_Lin 2023-06-19
这家伙很懒,什么也没写!

请问你的成功了吗

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览