668 lines
20 KiB
C
668 lines
20 KiB
C
/**
|
|
* @file es8388.c
|
|
* @author Alvin Young (impressionyang@outlook.com)
|
|
* @brief
|
|
* @version 0.1
|
|
* @date 2025-03-22
|
|
*
|
|
* _ _
|
|
* (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _
|
|
* / / ' \/ _ \/ __/ -_|_-<(_-</ / _ \/ _ \/ // / _ `/ _ \/ _ `/
|
|
* /_/_/_/_/ .__/_/ \__/___/___/_/\___/_//_/\_, /\_,_/_//_/\_, /
|
|
* /_/ /___/ /___/
|
|
* @copyright Copyright (c) 2025 impressionyang
|
|
*
|
|
* @par 修改日志:
|
|
* <table>
|
|
* <tr><th>Date <th>Version <th>Author <th>Description
|
|
* <tr><td>2025-03-22 <td>v1.0 <td>Alvin Young <td>首次创建
|
|
* </table>
|
|
*
|
|
*/
|
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "es8388.h"
|
|
#include "imp_codec.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <esp_log.h>
|
|
/* define --------------------------------------------------------------------*/
|
|
/* typedef -------------------------------------------------------------------*/
|
|
|
|
/* variables -----------------------------------------------------------------*/
|
|
|
|
static imp_es8388_cfg_t handle = { 0 };
|
|
/* Private function(only *.c) -----------------------------------------------*/
|
|
/* Exported functions --------------------------------------------------------*/
|
|
|
|
void es8388_read_all()
|
|
{
|
|
if (!handle.is_init) {
|
|
return;
|
|
}
|
|
for (int i = 0; i < 50; i++) {
|
|
uint8_t reg = 0;
|
|
handle.read_reg(i, ®);
|
|
ESP_LOGI("ES8388", "%x: %x", i, reg);
|
|
}
|
|
}
|
|
|
|
int es8388_write_reg(uint8_t reg_add, uint8_t data)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
return handle.write_reg(reg_add, data);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure ES8388 ADC and DAC volume. Basicly you can consider this as ADC and DAC gain
|
|
*
|
|
* @param mode: set ADC or DAC or all
|
|
* @param volume: -96 ~ 0 for example Es8388SetAdcDacVolume(ES_MODULE_ADC, 30, 6); means set ADC volume -30.5db
|
|
* @param dot: whether include 0.5. for example Es8388SetAdcDacVolume(ES_MODULE_ADC, 30, 4); means set ADC volume -30db
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
static int es8388_set_adc_dac_volume(int mode, int volume, int dot)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = 0;
|
|
if (volume < -96 || volume > 0) {
|
|
ESP_LOGW("ES8388", "Warning: volume < -96! or > 0!\n");
|
|
if (volume < -96)
|
|
volume = -96;
|
|
else
|
|
volume = 0;
|
|
}
|
|
dot = (dot >= 5 ? 1 : 0);
|
|
volume = (-volume << 1) + dot;
|
|
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
|
res |= handle.write_reg(ES8388_ADCCONTROL8, volume);
|
|
res |= handle.write_reg(ES8388_ADCCONTROL9,
|
|
volume); //ADC Right Volume=0db
|
|
}
|
|
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
|
res |= handle.write_reg(ES8388_DACCONTROL5, volume);
|
|
res |= handle.write_reg(ES8388_DACCONTROL4, volume);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Power Management
|
|
*
|
|
* @param mod: if ES_POWER_CHIP, the whole chip including ADC and DAC is enabled
|
|
* @param enable: false to disable true to enable
|
|
*
|
|
* @return
|
|
* - (-1) Error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_start(es_module_t mode)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t prev_data = 0, data = 0;
|
|
handle.read_reg(ES8388_DACCONTROL21, &prev_data);
|
|
if (mode == ES_MODULE_LINE) {
|
|
// 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
|
|
res |= handle.write_reg(ES8388_DACCONTROL16, 0x09);
|
|
// left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable
|
|
res |= handle.write_reg(ES8388_DACCONTROL17, 0x50);
|
|
// right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable
|
|
res |= handle.write_reg(ES8388_DACCONTROL20, 0x50);
|
|
res |= handle.write_reg(ES8388_DACCONTROL21, 0xC0); //enable adc
|
|
} else {
|
|
res |= handle.write_reg(ES8388_DACCONTROL21, 0x80); //enable dac
|
|
}
|
|
handle.read_reg(ES8388_DACCONTROL21, &data);
|
|
if (prev_data != data) {
|
|
//start state machine
|
|
res |= handle.write_reg(ES8388_CHIPPOWER, 0xF0);
|
|
// res |= handle.write_reg(ES8388_CONTROL1, 0x16);
|
|
// res |= handle.write_reg(ES8388_CONTROL2, 0x50);
|
|
//start state machine
|
|
res |= handle.write_reg(ES8388_CHIPPOWER, 0x00);
|
|
}
|
|
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC
|
|
|| mode == ES_MODULE_LINE) {
|
|
//power up adc and line in
|
|
res |= handle.write_reg(ES8388_ADCPOWER, 0x00);
|
|
}
|
|
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC
|
|
|| mode == ES_MODULE_LINE) {
|
|
//power up dac and line out
|
|
res |= handle.write_reg(ES8388_DACPOWER, 0x3c);
|
|
res |= es8388_set_voice_mute(false);
|
|
ESP_LOGD("ES8388", "es8388_start default is mode:%d", mode);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Power Management
|
|
*
|
|
* @param mod: if ES_POWER_CHIP, the whole chip including ADC and DAC is enabled
|
|
* @param enable: false to disable true to enable
|
|
*
|
|
* @return
|
|
* - (-1) Error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_stop(es_module_t mode)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
if (mode == ES_MODULE_LINE) {
|
|
//enable dac
|
|
res |= handle.write_reg(ES8388_DACCONTROL21, 0x80);
|
|
// 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
|
res |= handle.write_reg(ES8388_DACCONTROL16, 0x00);
|
|
// only left DAC to left mixer enable 0db
|
|
res |= handle.write_reg(ES8388_DACCONTROL17, 0x90);
|
|
// only right DAC to right mixer enable 0db
|
|
res |= handle.write_reg(ES8388_DACCONTROL20, 0x90);
|
|
return res;
|
|
}
|
|
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
|
res |= handle.write_reg(ES8388_DACPOWER, 0x00);
|
|
res |= es8388_set_voice_mute(
|
|
true); //res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
|
|
//res |= handle.write_reg(ES8388_DACPOWER, 0xC0); //power down dac and line out
|
|
}
|
|
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
|
//res |= Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
|
|
res |= handle.write_reg(ES8388_ADCPOWER,
|
|
0xFF); //power down adc and line in
|
|
}
|
|
if (mode == ES_MODULE_ADC_DAC) {
|
|
//disable mclk
|
|
res |= handle.write_reg(ES8388_DACCONTROL21, 0x9C);
|
|
// res |= handle.write_reg(ES8388_CONTROL1, 0x00);
|
|
// res |= handle.write_reg(ES8388_CONTROL2, 0x58);
|
|
// res |= handle.write_reg(ES8388_CHIPPOWER, 0xF3); //stop state machine
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Config I2s clock in MSATER mode
|
|
*
|
|
* @param cfg.sclkDiv: generate SCLK by dividing MCLK in MSATER mode
|
|
* @param cfg.lclkDiv: generate LCLK by dividing MCLK in MSATER mode
|
|
*
|
|
* @return
|
|
* - (-1) Error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_i2s_config_clock(es_i2s_clock_t cfg)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
res |= handle.write_reg(ES8388_MASTERMODE, cfg.sclk_div);
|
|
res |= handle.write_reg(ES8388_ADCCONTROL5,
|
|
cfg.lclk_div); //ADCFsMode,singel SPEED,RATIO=256
|
|
res |= handle.write_reg(ES8388_DACCONTROL2,
|
|
cfg.lclk_div); //ADCFsMode,singel SPEED,RATIO=256
|
|
return res;
|
|
}
|
|
|
|
int es8388_deinit(void)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = 0;
|
|
res = handle.write_reg(ES8388_CHIPPOWER,
|
|
0xFF); //reset and stop es8388
|
|
// i2c_bus_delete(i2c_handle);
|
|
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
|
headphone_detect_deinit();
|
|
#endif
|
|
|
|
// audio_codec_volume_deinit(dac_vol_handle);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @return
|
|
* - (-1) Error
|
|
* - (0) Success
|
|
*/
|
|
static int es8388_init_regs(imp_es8388_cfg_t* cfg)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = 0;
|
|
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
|
headphone_detect_init(get_headphone_detect_gpio());
|
|
#endif
|
|
ESP_LOGI("ES8388", "run %s at line %d", __FUNCTION__, __LINE__);
|
|
|
|
res = 0; // ESP32 in master mode
|
|
|
|
// 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp
|
|
res |= handle.write_reg(ES8388_DACCONTROL3, 0x04);
|
|
/* Chip Control and Power Management */
|
|
res |= handle.write_reg(ES8388_CONTROL2, 0x50);
|
|
//normal all and power up all
|
|
res |= handle.write_reg(ES8388_CHIPPOWER, 0x00);
|
|
|
|
// Disable the internal DLL to improve 8K sample rate
|
|
res |= handle.write_reg(0x35, 0xA0);
|
|
res |= handle.write_reg(0x37, 0xD0);
|
|
res |= handle.write_reg(0x39, 0xD0);
|
|
|
|
//CODEC IN I2S SLAVE MODE TODO
|
|
res |= handle.write_reg(ES8388_MASTERMODE, cfg->mode);
|
|
|
|
/* dac */
|
|
//disable DAC and disable Lout/Rout/1/2
|
|
res |= handle.write_reg(ES8388_DACPOWER, 0xC0);
|
|
//Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
|
|
res |= handle.write_reg(ES8388_CONTROL1, 0x12);
|
|
// res |= handle.write_reg(ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0
|
|
//1a 0x18:16bit iis , 0x00:24
|
|
res |= handle.write_reg(ES8388_DACCONTROL1, 0x18);
|
|
//DACFsMode,SINGLE SPEED; DACFsRatio,256
|
|
res |= handle.write_reg(ES8388_DACCONTROL2, 0x02);
|
|
// 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
|
res |= handle.write_reg(ES8388_DACCONTROL16, 0x00);
|
|
// only left DAC to left mixer enable 0db
|
|
res |= handle.write_reg(ES8388_DACCONTROL17, 0x90);
|
|
// only right DAC to right mixer enable 0db
|
|
res |= handle.write_reg(ES8388_DACCONTROL20, 0x90);
|
|
// set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
|
|
res |= handle.write_reg(ES8388_DACCONTROL21, 0x80);
|
|
res |= handle.write_reg(ES8388_DACCONTROL23, 0x00); // vroi=0
|
|
|
|
// Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dB
|
|
res |= handle.write_reg(ES8388_DACCONTROL24, 0x1E);
|
|
res |= handle.write_reg(ES8388_DACCONTROL25, 0x1E);
|
|
res |= handle.write_reg(ES8388_DACCONTROL26, 0);
|
|
res |= handle.write_reg(ES8388_DACCONTROL27, 0);
|
|
// res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, 0, 0); // 0db
|
|
int tmp = 0;
|
|
if (EM_IMP_ES8388_LINE_OUT_1 == cfg->dac_output) {
|
|
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_ROUT1;
|
|
} else if (EM_IMP_ES8388_LINE_OUT_2 == cfg->dac_output) {
|
|
tmp = DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT2;
|
|
} else {
|
|
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1
|
|
| DAC_OUTPUT_ROUT2;
|
|
}
|
|
|
|
//0x3c Enable DAC and Enable Lout/Rout/1/2
|
|
res |= handle.write_reg(ES8388_DACPOWER, tmp);
|
|
/* adc */
|
|
res |= handle.write_reg(ES8388_ADCPOWER, 0xFF);
|
|
// MIC Left and Right channel PGA gain
|
|
res |= handle.write_reg(ES8388_ADCCONTROL1, 0xbb);
|
|
tmp = 0;
|
|
if (EM_IMP_ES8388_LINE_IN_1 == cfg->adc_input) {
|
|
tmp = ADC_INPUT_LINPUT1_RINPUT1;
|
|
} else if (EM_IMP_ES8388_LINE_IN_2 == cfg->adc_input) {
|
|
tmp = ADC_INPUT_LINPUT2_RINPUT2;
|
|
} else {
|
|
tmp = ADC_INPUT_DIFFERENCE;
|
|
}
|
|
|
|
//0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
|
|
res |= handle.write_reg(ES8388_ADCCONTROL2, tmp);
|
|
res |= handle.write_reg(ES8388_ADCCONTROL3, 0x02);
|
|
// 16 Bits length and I2S serial audio data format
|
|
res |= handle.write_reg(ES8388_ADCCONTROL4, 0x0c);
|
|
//ADCFsMode,singel SPEED,RATIO=256
|
|
res |= handle.write_reg(ES8388_ADCCONTROL5, 0x02);
|
|
//ALC for Microphone
|
|
res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0); // 0db
|
|
// Power on ADC, enable LIN&RIN, power off MICBIAS, and set int1lp to low power mode
|
|
res |= handle.write_reg(ES8388_ADCPOWER, 0x09);
|
|
|
|
/* es8388 PA gpio_config */
|
|
// gpio_config_t io_conf;
|
|
// memset(&io_conf, 0, sizeof(io_conf));
|
|
// io_conf.mode = GPIO_MODE_OUTPUT;
|
|
// io_conf.pin_bit_mask = BIT64(get_pa_enable_gpio());
|
|
// io_conf.pull_down_en = 0;
|
|
// io_conf.pull_up_en = 0;
|
|
// gpio_config(&io_conf);
|
|
// /* enable es8388 PA */
|
|
// es8388_pa_power(true);
|
|
|
|
// codec_dac_volume_config_t vol_cfg = ES8388_DAC_VOL_CFG_DEFAULT();
|
|
// dac_vol_handle = audio_codec_volume_init(&vol_cfg);
|
|
ESP_LOGI("ES8388", "init,out:%02x, in:%02x", cfg->dac_output,
|
|
cfg->adc_input);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure ES8388 I2S format
|
|
*
|
|
* @param mode: set ADC or DAC or all
|
|
* @param bitPerSample: see Es8388I2sFmt
|
|
*
|
|
* @return
|
|
* - (-1) Error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_config_fmt(es_module_t mode, es_i2s_fmt_t fmt)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
|
res = handle.read_reg(ES8388_ADCCONTROL4, ®);
|
|
reg = reg & 0xfc;
|
|
res |= handle.write_reg(ES8388_ADCCONTROL4, reg | fmt);
|
|
}
|
|
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
|
res = handle.read_reg(ES8388_DACCONTROL1, ®);
|
|
reg = reg & 0xf9;
|
|
res |= handle.write_reg(ES8388_DACCONTROL1, reg | (fmt << 1));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Set voice volume
|
|
*
|
|
* @note Register values. 0xC0: -96 dB, 0x64: -50 dB, 0x00: 0 dB
|
|
* @note Accuracy of gain is 0.5 dB
|
|
*
|
|
* @param volume: voice volume (0~100)
|
|
*
|
|
* @return
|
|
* - ESP_OK
|
|
* - ESP_FAIL
|
|
*/
|
|
int es8388_set_voice_volume(int volume)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
|
|
// (min/mute)4 - 100(max)
|
|
if (volume < 4) {
|
|
volume = 4;
|
|
}
|
|
if (volume > 100) {
|
|
volume = 100;
|
|
}
|
|
|
|
// 0 - 96
|
|
volume = volume - 4;
|
|
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
reg = 192 - (volume * 2); // TODO 转换配置
|
|
res |= handle.write_reg(ES8388_DACCONTROL5, reg);
|
|
res |= handle.write_reg(ES8388_DACCONTROL4, reg);
|
|
ESP_LOGD("ES8388", "Set volume:%.2d reg_value:0x%.2x dB:%.1f", (int)volume,
|
|
reg, 0);
|
|
return res;
|
|
}
|
|
|
|
int es8388_get_voice_volume(int* volume)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
res = handle.read_reg(ES8388_DACCONTROL4, ®);
|
|
|
|
// TODO: 转换reg到值
|
|
*volume = (reg - 192) / 2;
|
|
|
|
// if (res == ESP_FAIL) {
|
|
// *volume = 0;
|
|
// } else {
|
|
// if (reg == dac_vol_handle->reg_value) {
|
|
// *volume = dac_vol_handle->user_volume;
|
|
// } else {
|
|
// *volume = 0;
|
|
// res = ESP_FAIL;
|
|
// }
|
|
// }
|
|
ESP_LOGD("ES8388", "Get volume:%.2d reg_value:0x%.2x", *volume, reg);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure ES8388 data sample bits
|
|
*
|
|
* @param mode: set ADC or DAC or all
|
|
* @param bitPerSample: see BitsLength
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_set_bits_per_sample(es_module_t mode, es_bits_length_t bits_length)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
int bits = (int)bits_length;
|
|
|
|
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
|
res = handle.read_reg(ES8388_ADCCONTROL4, ®);
|
|
reg = reg & 0xe3;
|
|
res |= handle.write_reg(ES8388_ADCCONTROL4, reg | (bits << 2));
|
|
}
|
|
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
|
res = handle.read_reg(ES8388_DACCONTROL1, ®);
|
|
reg = reg & 0xc7;
|
|
res |= handle.write_reg(ES8388_DACCONTROL1, reg | (bits << 3));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure ES8388 DAC mute or not. Basically you can use this function to mute the output or unmute
|
|
*
|
|
* @param enable: enable or disable
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_set_voice_mute(bool enable)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
res = handle.read_reg(ES8388_DACCONTROL3, ®);
|
|
reg = reg & 0xFB;
|
|
res |= handle.write_reg(ES8388_DACCONTROL3, reg | (((int)enable) << 2));
|
|
return res;
|
|
}
|
|
|
|
int es8388_get_voice_mute(void)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
uint8_t reg = 0;
|
|
res = handle.read_reg(ES8388_DACCONTROL3, ®);
|
|
if (res == ESP_OK) {
|
|
reg = (reg & 0x04) >> 2;
|
|
}
|
|
return res == ESP_OK ? reg : res;
|
|
}
|
|
|
|
/**
|
|
* @param gain: Config DAC Output
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_config_dac_output(es_dac_output_t output)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res;
|
|
uint8_t reg = 0;
|
|
res = handle.read_reg(ES8388_DACPOWER, ®);
|
|
reg = reg & 0xc3;
|
|
res |= handle.write_reg(ES8388_DACPOWER, reg | output);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @param gain: Config ADC input
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_config_adc_input(es_adc_input_t input)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res;
|
|
uint8_t reg = 0;
|
|
res = handle.read_reg(ES8388_ADCCONTROL2, ®);
|
|
reg = reg & 0x0f;
|
|
res |= handle.write_reg(ES8388_ADCCONTROL2, reg | input);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @param gain: see es_mic_gain_t
|
|
*
|
|
* @return
|
|
* - (-1) Parameter error
|
|
* - (0) Success
|
|
*/
|
|
int es8388_set_mic_gain(es_mic_gain_t gain)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res, gain_n;
|
|
gain_n = (int)gain / 3;
|
|
gain_n = (gain_n << 4) + gain_n;
|
|
res = handle.write_reg(ES8388_ADCCONTROL1, gain_n); //MIC PGA
|
|
return res;
|
|
}
|
|
|
|
int es8388_ctrl_state(codec_work_mode_t mode, uint8_t start_flag)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = 0;
|
|
int es_mode_t = 0;
|
|
switch (mode) {
|
|
case EM_IMP_CODEC_DEV_WORK_MODE_ADC:
|
|
es_mode_t = ES_MODULE_ADC;
|
|
break;
|
|
case EM_IMP_CODEC_DEV_WORK_MODE_LINE:
|
|
es_mode_t = ES_MODULE_LINE;
|
|
break;
|
|
case EM_IMP_CODEC_DEV_WORK_MODE_DAC:
|
|
es_mode_t = ES_MODULE_DAC;
|
|
break;
|
|
case EM_IMP_CODEC_DEV_WORK_MODE_BOTH:
|
|
es_mode_t = ES_MODULE_ADC_DAC;
|
|
break;
|
|
default:
|
|
es_mode_t = ES_MODULE_DAC;
|
|
ESP_LOGW("ES8388",
|
|
"Codec mode not support, default is decode mode");
|
|
break;
|
|
}
|
|
if (start_flag) {
|
|
res = es8388_start(es_mode_t);
|
|
ESP_LOGD("ES8388", "start default is decode mode:%d", es_mode_t);
|
|
} else {
|
|
res = es8388_stop(es_mode_t);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
int es8388_config_i2s(es_i2s_fmt_t fmt, es_bits_length_t bit)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
int res = ESP_OK;
|
|
int tmp = 0;
|
|
res |= es8388_config_fmt(handle.mode, fmt);
|
|
if (bit == BIT_LENGTH_16BITS) {
|
|
tmp = BIT_LENGTH_16BITS;
|
|
} else if (bit == BIT_LENGTH_24BITS) {
|
|
tmp = BIT_LENGTH_24BITS;
|
|
} else {
|
|
tmp = BIT_LENGTH_32BITS;
|
|
}
|
|
res |= es8388_set_bits_per_sample(handle.mode, tmp);
|
|
return res;
|
|
}
|
|
|
|
int es8388_pa_power(bool enable)
|
|
{
|
|
if (!handle.is_init) {
|
|
return 1;
|
|
}
|
|
|
|
int res = ESP_OK;
|
|
// if (enable) {
|
|
// res = gpio_set_level(get_pa_enable_gpio(), 1);
|
|
// } else {
|
|
// res = gpio_set_level(get_pa_enable_gpio(), 0);
|
|
// }
|
|
return res;
|
|
}
|
|
|
|
int es8388_init(es_mode_t mode, imp_es_8388_io_port_e dac_output,
|
|
imp_es_8388_io_port_e adc_input,
|
|
uint8_t (*read_reg)(uint8_t reg_addr, uint8_t* reg_data),
|
|
uint8_t (*write_reg)(uint8_t reg_addr, uint8_t reg_data))
|
|
{
|
|
ESP_LOGI("ES8388", "run %s at line %d", __FUNCTION__, __LINE__);
|
|
if (NULL == read_reg || NULL == write_reg) {
|
|
return 1;
|
|
}
|
|
ESP_LOGI("ES8388", "run %s at line %d", __FUNCTION__, __LINE__);
|
|
|
|
handle.mode = mode;
|
|
handle.dac_output = dac_output;
|
|
handle.adc_input = adc_input;
|
|
handle.read_reg = read_reg;
|
|
handle.write_reg = write_reg;
|
|
handle.is_init = 1;
|
|
es8388_init_regs(&handle);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* EOF
|
|
*/ |