554 lines
11 KiB
C
554 lines
11 KiB
C
#include <stdio.h>
|
||
#include "ql_rtos.h"
|
||
#include "ql_application.h"
|
||
#include "ql_audio.h"
|
||
#include "ql_iic.h"
|
||
#include "ql_gpio.h"
|
||
#include "app_inc.h"
|
||
#include "ql_fs.h"
|
||
|
||
#define DEFAULT_VOLUME 6
|
||
|
||
//#define TEST_MIC
|
||
|
||
u8 g_cur_volume = 0;
|
||
u8 g_pre_volume = 0;
|
||
|
||
extern const char *mp3_file[];
|
||
extern int g_file_valid;
|
||
|
||
|
||
// 关键寄存器定义
|
||
#define ES8311_REG_SYSTEM 0x01
|
||
#define ES8311_REG_CLK_CTL 0x00
|
||
#define ES8311_REG_PDN_CTL 0x0D
|
||
#define ES8311_REG_STATUS 0x00
|
||
#define ES8311_REG_CHIPID 0xFD
|
||
#if 0
|
||
static uint16 es8311_init_reg[] = {
|
||
0x0045,//45 is the addr, 0x00 is the value
|
||
0x3001,
|
||
0x1002,
|
||
0x0002,
|
||
0x1003,
|
||
0x2416,
|
||
0x2004,
|
||
0x0005,
|
||
0x2006,
|
||
0x0007,
|
||
0xff08,
|
||
0x0f09,
|
||
0x0f0a,
|
||
0x000b,
|
||
0x000c,
|
||
0x1310,
|
||
0x7f11,
|
||
0x3f01,
|
||
0x8000,
|
||
0x010d,
|
||
0x1014,
|
||
0x2812,
|
||
0x1013,
|
||
0x020e,
|
||
0x440f,
|
||
0x0015,
|
||
0x0a1b,
|
||
0x6a1c,
|
||
0x0837,
|
||
0x0044,
|
||
0xbf17,
|
||
0xbf32,
|
||
};
|
||
#endif
|
||
|
||
#if 1
|
||
static uint16 es8311_init_reg[] = {
|
||
0x0045,
|
||
0x3001,
|
||
0x1002,
|
||
0x0002,
|
||
0x1003,
|
||
0x2416,
|
||
0x2004,
|
||
0x0005,
|
||
0x2006,
|
||
0x0007,
|
||
0xff08,
|
||
0x0f09,
|
||
0x0f0a,
|
||
0x000b,
|
||
0x000c,
|
||
0x1310, // 0x10 保持不变
|
||
0x7f11, // 0x11 保持不变
|
||
0x3f01,
|
||
0x8000,
|
||
0x010d,
|
||
0x1014, // ← 修改:LINSEL=1, PGAGAIN=0(+0dB) 或 0x0214(+6dB)
|
||
0x2812,
|
||
0x1013,
|
||
0x020e,
|
||
0x440f,
|
||
0x0015,
|
||
0x0a1b,
|
||
0x6a1c,
|
||
0x0837,
|
||
0x0044,
|
||
0xa717, // ← 修改:ADC_VOLUME=0x9F (-32dB),缩短拾音距离
|
||
0xbf32, // DAC音量保持不变
|
||
0x0018, // ← 新增:关闭ALC (如果之前没配的话)
|
||
// 0x0016, // ← 新增/修改:ADC_SCALE=0 (0dB)
|
||
};
|
||
#endif
|
||
|
||
static uint16 es8311_sleep_reg[] = {
|
||
0x0032,//32 is the addr, 0x00 is the value 音量控制
|
||
0x0017,//MIC采样功率
|
||
0xFF0E,//设置外设低功耗
|
||
0x0212,//powerdown dac
|
||
0x0014,
|
||
0xF90D,//FA0D
|
||
0x0015,
|
||
0x0837,
|
||
0x1002,
|
||
0x0000,
|
||
0x1F00,
|
||
0x3001,
|
||
0x0001,
|
||
0x0045,
|
||
};
|
||
|
||
#if 0
|
||
static uint16 es8311_resume_reg[] = {
|
||
0x010D,//45 is the addr, 0x00 is the value
|
||
0x0045,
|
||
0x3F01,
|
||
0x8000,
|
||
0x0002,
|
||
0x0837,
|
||
0x4015,
|
||
0x1014,
|
||
0x0012,
|
||
0x000E,
|
||
0xBF32,
|
||
0xBF17,
|
||
};
|
||
#endif
|
||
|
||
#if 1
|
||
static uint16 es8311_resume_reg[] = {
|
||
0x010D,
|
||
0x0045,
|
||
0x3F01,
|
||
0x8000,
|
||
0x0002,
|
||
0x0837,
|
||
0x4015,
|
||
0x1014,
|
||
0x0012,
|
||
0x000E,
|
||
0xBF32,
|
||
0xa717, // ← 同步修改:ADC_VOLUME=-32dB
|
||
};
|
||
#endif
|
||
|
||
|
||
#define ES8311_INIT_REG_LEN sizeof(es8311_init_reg)/sizeof(es8311_init_reg[0])
|
||
|
||
#define ES8311_SLEEP_REG_LEN sizeof(es8311_sleep_reg)/sizeof(es8311_sleep_reg[0])
|
||
|
||
#define ES8311_RESUME_REG_LEN sizeof(es8311_resume_reg)/sizeof(es8311_resume_reg[0])
|
||
|
||
#define ES8311_REG_I2C_DEVICEID 0xFD
|
||
#define ES8311_I2C_SLAVE_ADDR 0x18
|
||
|
||
unsigned char ql_es8311_write_reg(unsigned char reg, unsigned char data)
|
||
{
|
||
sw_i2c_start();
|
||
|
||
sw_i2c_write_byte(ES8311_I2C_SLAVE_ADDR << 1);
|
||
|
||
sw_i2c_write_byte(reg);
|
||
|
||
sw_i2c_write_byte(data);
|
||
|
||
sw_i2c_stop();
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*************************************************************
|
||
* I2C1_read_eeprom
|
||
* Description: I2C1 read FT24C02 eeprom
|
||
* Parameters: op_addr: operate address
|
||
* pData: data point
|
||
* len: data len
|
||
* return: unsigned long
|
||
* error: none
|
||
*/
|
||
unsigned char ql_es8311_read_reg(unsigned char reg, unsigned char *pData)
|
||
{
|
||
sw_i2c_start();
|
||
|
||
sw_i2c_write_byte(ES8311_I2C_SLAVE_ADDR << 1);
|
||
|
||
sw_i2c_write_byte(reg);
|
||
|
||
sw_i2c_start();
|
||
|
||
sw_i2c_write_byte((ES8311_I2C_SLAVE_ADDR << 1)+1);
|
||
|
||
*pData=sw_i2c_read_byte(0);
|
||
|
||
sw_i2c_stop();
|
||
|
||
return 0;
|
||
}
|
||
|
||
void ql_es8311_init(void)
|
||
{
|
||
char i = 0;
|
||
|
||
for (i = 0; i < ES8311_INIT_REG_LEN; i++)
|
||
{
|
||
ql_es8311_write_reg(es8311_init_reg[i]&0xFF, es8311_init_reg[i]>>8);
|
||
}
|
||
}
|
||
|
||
void ql_es8311_open(void) //��ʼ��es8311�ͺ�codec
|
||
{
|
||
unsigned short status = 0;
|
||
unsigned char val = 0;
|
||
status = ql_es8311_read_reg(ES8311_REG_I2C_DEVICEID, &val);
|
||
if ((status == 0) && (0x83 == val))
|
||
{
|
||
ql_es8311_init();
|
||
printf("quec_es8311_init!!!\n");
|
||
}
|
||
|
||
app_set_default_volume();
|
||
}
|
||
|
||
void ql_es8311_sleep(void)
|
||
{
|
||
#if 1
|
||
char i = 0;
|
||
|
||
for (i = 0; i < ES8311_SLEEP_REG_LEN; i++)
|
||
{
|
||
ql_es8311_write_reg(es8311_sleep_reg[i]&0xFF, es8311_sleep_reg[i]>>8);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void ql_es8311_wake(void)
|
||
{
|
||
#if 1
|
||
char i = 0;
|
||
|
||
for (i = 0; i < ES8311_RESUME_REG_LEN; i++)
|
||
{
|
||
ql_es8311_write_reg(es8311_resume_reg[i]&0xFF, es8311_resume_reg[i]>>8);
|
||
ql_rtos_task_sleep_ms(5);
|
||
}
|
||
|
||
app_set_default_volume();
|
||
#endif
|
||
}
|
||
|
||
void ql_es8311_vocie_set(u8 value)
|
||
{
|
||
ql_es8311_write_reg(0x32, value);
|
||
}
|
||
|
||
u8 ql_es8311_vocie_get(void)
|
||
{
|
||
u8 value = 0;
|
||
|
||
//ql_es8311_write_reg(0x32, value);
|
||
ql_es8311_read_reg(0x32, &value);
|
||
}
|
||
|
||
|
||
static ql_cb_on_speakerpa play_audio_pa_cb(unsigned int on){
|
||
if(on){
|
||
// printf("PA on\r\n");
|
||
}else{
|
||
//printf("PA off\r\n");
|
||
app_codec_pa_close();
|
||
}
|
||
}
|
||
|
||
signed short DSP_codec_gain[12]={-36,-31,-27,-24,-21,-18,-15,-12,-9,-6,-3,0};
|
||
|
||
|
||
static void ql_audio_record_callback(acm_audio_track_handle handle, acm_audio_record_event_t event)
|
||
{
|
||
printf("audio_record_callback event:%d\r\n", event);
|
||
}
|
||
|
||
void app_codec_pa_close(void)
|
||
{
|
||
ql_gpio_init(GPIO_PIN_NO_68, PIN_DIRECTION_OUT, PIN_PULL_PU, PIN_LEVEL_LOW); //for new board
|
||
//ql_gpio_init(GPIO_PIN_NO_57, PIN_DIRECTION_OUT, PIN_PULL_PU, PIN_LEVEL_LOW); //for old board
|
||
}
|
||
|
||
void app_codec_pa_open(void)
|
||
{
|
||
ql_gpio_init(GPIO_PIN_NO_68, PIN_DIRECTION_OUT, PIN_PULL_PU, PIN_LEVEL_HIGH); //for new board
|
||
//ql_gpio_init(GPIO_PIN_NO_57, PIN_DIRECTION_OUT, PIN_PULL_PU, PIN_LEVEL_HIGH); //for old board
|
||
}
|
||
|
||
#if 0
|
||
#define VOLUME_FILE "U:/volume_file.txt"
|
||
|
||
int read_volume_file(uint8_t *buff, int len)
|
||
{
|
||
QFILE * fp = NULL;
|
||
int ret = -1;
|
||
|
||
// 安全修复:检查参数
|
||
if(buff == NULL || len <= 0){
|
||
printf("[FS]ERROR!!! *** invalid parameters\r\n");
|
||
return -1;
|
||
}
|
||
|
||
if(ql_access(VOLUME_FILE, 0)!=0){
|
||
printf("read %s not is exist\n", VOLUME_FILE);
|
||
return -1;
|
||
}
|
||
|
||
fp = ql_fopen(VOLUME_FILE, "r");
|
||
|
||
if(NULL == fp)
|
||
{
|
||
printf("[FS]ERROR!!! *** file open fail: %s \r\n", VOLUME_FILE);
|
||
return -1;
|
||
}
|
||
|
||
ret = ql_fread(buff, len, 1, fp);
|
||
if(ret < 0)
|
||
{
|
||
printf("[FS]ERROR!!! *** file read fail: %s \r\n", VOLUME_FILE);
|
||
}
|
||
|
||
ql_fclose(fp);
|
||
// 安全修复:fp已关闭,无需设为NULL
|
||
|
||
return ret;
|
||
}
|
||
|
||
int save_volume_file(uint8_t *buff, int len)
|
||
{
|
||
QFILE * fp = NULL;
|
||
int ret = -1;
|
||
|
||
// 安全修复:检查参数
|
||
if(buff == NULL || len <= 0){
|
||
printf("[FS]ERROR!!! *** invalid parameters\r\n");
|
||
return -1;
|
||
}
|
||
|
||
fp = ql_fopen(VOLUME_FILE, "w+");
|
||
|
||
if(NULL == fp)
|
||
{
|
||
printf("[FS]ERROR!!! *** file open fail: %s \r\n", VOLUME_FILE);
|
||
return -1;
|
||
}
|
||
|
||
ret = ql_fwrite(buff, len, 1, fp);
|
||
if(ret < 0)
|
||
{
|
||
printf("[FS]ERROR!!! *** file write fail: %s \r\n", VOLUME_FILE);
|
||
}
|
||
|
||
ql_fclose(fp);
|
||
// 安全修复:fp已关闭,无需设为NULL
|
||
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
void app_set_volume(uint8_t value)
|
||
{
|
||
//save_volume_file(&value, 1);
|
||
if(g_cur_volume==0){
|
||
hal_kv_set("volume", &value, 1);
|
||
}
|
||
|
||
printf("set volume:%d\r\n", value);
|
||
ql_es8311_vocie_set(value);
|
||
|
||
if(value==VOLUME_80){
|
||
g_cur_volume = 80;
|
||
}else if(value==VOLUME_60){
|
||
g_cur_volume = 60;
|
||
}else if(value==VOLUME_40){
|
||
g_cur_volume = 40;
|
||
}else if(value==VOLUME_100){
|
||
g_cur_volume = 100;
|
||
}else if(value==VOLUME_10){
|
||
g_cur_volume = 10;
|
||
}else if(value==VOLUME_20){
|
||
g_cur_volume = 20;
|
||
}else if(value==VOLUME_30){
|
||
g_cur_volume = 30;
|
||
}else if(value==VOLUME_70){
|
||
g_cur_volume = 70;
|
||
}else if(value==VOLUME_50){
|
||
g_cur_volume = 50;
|
||
}else if(value==VOLUME_90){
|
||
g_cur_volume = 90;
|
||
}else{
|
||
g_cur_volume = 70;
|
||
}
|
||
|
||
}
|
||
|
||
uint8_t app_get_volume(void)
|
||
{
|
||
uint8_t value = 0;
|
||
int ret = 0;
|
||
|
||
ret = hal_kv_get("volume", &value, 1);
|
||
printf("get volume:%d, ret:%d\r\n", value, ret);
|
||
//ret = read_volume_file(&value, 1);
|
||
if(ret<0){
|
||
g_cur_volume = 70;
|
||
hal_kv_set("volume", &g_cur_volume, 1);
|
||
return VOLUME_70;
|
||
}
|
||
|
||
g_cur_volume = value;
|
||
|
||
if(value==10){
|
||
ret = VOLUME_10;
|
||
}else if(value==20){
|
||
ret = VOLUME_20;
|
||
}else if(value==30){
|
||
ret = VOLUME_30;
|
||
}else if(value==40){
|
||
ret = VOLUME_40;
|
||
}else if(value==50){
|
||
ret = VOLUME_50;
|
||
}else if(value==60){
|
||
ret = VOLUME_60;
|
||
}else if(value==70){
|
||
ret = VOLUME_70;
|
||
}else if(value==80){
|
||
ret = VOLUME_80;
|
||
}else if(value==90){
|
||
ret = VOLUME_90;
|
||
}else if(value==100){
|
||
ret = VOLUME_100;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
int app_set_default_volume(void)
|
||
{
|
||
int volume = app_get_volume();
|
||
//g_pre_volume = volume;
|
||
printf("volume:%d\r\n", volume);
|
||
ql_es8311_vocie_set(volume);
|
||
|
||
return volume;
|
||
}
|
||
|
||
|
||
#ifdef TEST_MIC
|
||
static void ql_audio_track_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||
{
|
||
printf("audio_track_callback event:%d\r\n", event);
|
||
}
|
||
#endif
|
||
|
||
void play_start_mp3_file(void)
|
||
{
|
||
char *filename_buff[64]={0x00};
|
||
|
||
sprintf(filename_buff, "U:/%s", mp3_file[1]);
|
||
|
||
if(ql_access(filename_buff, 0)==0){
|
||
g_file_valid = 1;
|
||
aofei_mp3_player(filename_buff);
|
||
}
|
||
}
|
||
|
||
void app_audio_init(void)
|
||
{
|
||
|
||
// static audio_record_handle record_hd;
|
||
|
||
while(!ql_get_audio_state()){
|
||
ql_rtos_task_sleep_ms(50);
|
||
}
|
||
|
||
printf("ql_audio_init ...\r\n");
|
||
|
||
unsigned int rate = 16000;
|
||
ql_codecpcm_config pcm_config[] = {PCM_FS_256,PCM_CODEC_SAMPLE_16000,0};
|
||
|
||
app_codec_pa_close();
|
||
|
||
ql_codec_choose(AUD_EXTERNAL_CODEC, &pcm_config); //ģ���ڲ����ú�������codec���pcm����
|
||
ql_es8311_open();
|
||
|
||
ql_set_audio_path_receiver();
|
||
ql_set_rxcodec_gain_table(1, 0, 36, 1, 1,0, 2);
|
||
ql_set_rxcodec_gain_table(1, 1, 36, 1, 1,0, 2);
|
||
ql_set_rxcodec_gain_table(1, 2, 36, 1, 2,0, 2);
|
||
ql_set_rxcodec_gain_table(1, 3, 36, 1, 2,0, 2);
|
||
ql_set_rxcodec_gain_table(1, 4, 36, 1, 3,0, 2);
|
||
ql_set_rxcodec_gain_table(1, 5, 36, 1, 3,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 6, 36, 1, 4,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 7, 36, 1, 4,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 8, 36, 1, 4,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 9, 36, 1, 4,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 10, 36, 1, 4,1, 2);
|
||
ql_set_rxcodec_gain_table(1, 11, 36, 1, 4,1, 2);
|
||
ql_set_dsp_gain_table(1, DSP_codec_gain);
|
||
ql_bind_speakerpa_cb(play_audio_pa_cb);
|
||
//ql_set_volume(DEFAULT_VOLUME);
|
||
|
||
g_pre_volume = app_set_default_volume();
|
||
|
||
play_start_mp3_file();
|
||
|
||
#ifdef TEST_MIC
|
||
unsigned int channels = 1;
|
||
unsigned int record_len;
|
||
int read_ret = -1, write_ret = -1;
|
||
|
||
char *tmp_buf = NULL;
|
||
audio_track_handle track_hd;
|
||
audio_record_handle record_hd;
|
||
|
||
record_len = (channels*rate*2*20)/1000;
|
||
tmp_buf = malloc(record_len);
|
||
|
||
track_hd = ql_audio_track_open(rate, channels, 0x100, ql_audio_track_callback);
|
||
|
||
record_hd = ql_audio_record_open(rate, channels, 0, ql_audio_record_callback);
|
||
|
||
app_codec_pa_open();
|
||
|
||
while (1)
|
||
{
|
||
read_ret = ql_audio_record_read(record_hd, tmp_buf, &record_len);
|
||
printf("ql_pcm_read, pcm read:%d %d\n", read_ret,record_len);
|
||
|
||
if ((read_ret == 0) && record_len > 0) {
|
||
write_ret = ql_audio_track_write(track_hd, tmp_buf, record_len);
|
||
printf("ql_pcm_write, pcm write:%d\n", write_ret);
|
||
}
|
||
|
||
ql_rtos_task_sleep_ms(15);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|