- completely drop ADF but copy necessary parts
o copy component audio_board from ADF and create custom component from it o copy component audio_hal from ADF and create custom component from it o copy component audio_sal from ADF and create custom component from it o copy component esp_peripherals from ADF and create custom component from it - add fLaC support through xiph's original repository as a git module
This commit is contained in:
679
components/audio_hal/driver/es8388/es8388.c
Normal file
679
components/audio_hal/driver/es8388/es8388.c
Normal file
@@ -0,0 +1,679 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in
|
||||
* which case, it is free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the "Software"), to deal in the
|
||||
* Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es8388.h"
|
||||
#include "board_pins_config.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
#include "headphone_detect.h"
|
||||
#endif
|
||||
|
||||
static const char *ES_TAG = "ES8388_DRIVER";
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
|
||||
#define ES_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) \
|
||||
{ \
|
||||
ESP_LOGE (ES_TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES8388_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es8388_init,
|
||||
.audio_codec_deinitialize = es8388_deinit,
|
||||
.audio_codec_ctrl = es8388_ctrl_state,
|
||||
.audio_codec_config_iface = es8388_config_i2s,
|
||||
.audio_codec_set_mute = es8388_set_voice_mute,
|
||||
.audio_codec_set_volume = es8388_set_voice_volume,
|
||||
.audio_codec_get_volume = es8388_get_voice_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static esp_err_t
|
||||
es_write_reg (uint8_t slave_addr, uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
return i2c_bus_write_bytes (i2c_handle, slave_addr, ®_add,
|
||||
sizeof (reg_add), &data, sizeof (data));
|
||||
}
|
||||
|
||||
static esp_err_t
|
||||
es_read_reg (uint8_t reg_add, uint8_t *p_data)
|
||||
{
|
||||
return i2c_bus_read_bytes (i2c_handle, ES8388_ADDR, ®_add,
|
||||
sizeof (reg_add), p_data, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_init ()
|
||||
{
|
||||
int res;
|
||||
i2c_config_t es_i2c_cfg = { .mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000 };
|
||||
res = get_i2c_pins (I2C_NUM_0, &es_i2c_cfg);
|
||||
ES_ASSERT (res, "getting i2c pins error", -1);
|
||||
i2c_handle = i2c_bus_create (I2C_NUM_0, &es_i2c_cfg);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
es8388_read_all ()
|
||||
{
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
uint8_t reg = 0;
|
||||
es_read_reg (i, ®);
|
||||
ets_printf ("%x: %x\n", i, reg);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_write_reg (uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
return es_write_reg (ES8388_ADDR, 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)
|
||||
{
|
||||
int res = 0;
|
||||
if (volume < -96 || volume > 0)
|
||||
{
|
||||
ESP_LOGW (ES_TAG, "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 |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL8, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL9,
|
||||
volume); // ADC Right Volume=0db
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL5, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, 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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_start (es_module_t mode)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t prev_data = 0, data = 0;
|
||||
es_read_reg (ES8388_DACCONTROL21, &prev_data);
|
||||
if (mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x50); // left DAC to left mixer enable and LIN signal to left
|
||||
// mixer enable 0db : bupass enable
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x50); // right DAC to right mixer enable and LIN signal to right
|
||||
// mixer enable 0db : bupass enable
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0xC0); // enable adc
|
||||
}
|
||||
else
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // enable dac
|
||||
}
|
||||
es_read_reg (ES8388_DACCONTROL21, &data);
|
||||
if (prev_data != data)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xF0); // start state machine
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x16);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // start state machine
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC
|
||||
|| mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x00); // power up adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC
|
||||
|| mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
0x3c); // power up dac and line out
|
||||
res |= es8388_set_voice_mute (false);
|
||||
ESP_LOGD (ES_TAG, "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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_stop (es_module_t mode)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
if (mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // enable dac
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
return res;
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER, 0x00);
|
||||
res |= es8388_set_voice_mute (
|
||||
true); // res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
|
||||
// res |= es_write_reg(ES8388_ADDR, 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 |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0xFF); // power down adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x9C); // disable mclk
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x00);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x58);
|
||||
// res |= es_write_reg(ES8388_ADDR, 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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_i2s_config_clock (es_i2s_clock_t cfg)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_MASTERMODE, cfg.sclk_div);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_deinit (void)
|
||||
{
|
||||
int res = 0;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xFF); // reset and stop es8388
|
||||
i2c_bus_delete (i2c_handle);
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
headphone_detect_deinit ();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_init (audio_hal_codec_config_t *cfg)
|
||||
{
|
||||
int res = 0;
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
headphone_detect_init (get_headphone_detect_gpio ());
|
||||
#endif
|
||||
|
||||
res = i2c_init (); // ESP32 in master mode
|
||||
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL3,
|
||||
0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and
|
||||
// disabled digital volume control soft ramp
|
||||
/* Chip Control and Power Management */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // normal all and power up all
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_MASTERMODE,
|
||||
cfg->i2s_iface.mode); // CODEC IN I2S SLAVE MODE
|
||||
|
||||
/* dac */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
0xC0); // disable DAC and disable Lout/Rout/1/2
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_CONTROL1,
|
||||
0x12); // Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0);
|
||||
// //LPVrefBuf=0,Pdn_ana=0
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL1,
|
||||
0x18); // 1a 0x18:16bit iis , 0x00:24
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
0x02); // DACFsMode,SINGLE SPEED; DACFsRatio,256
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // set internal ADC and DAC use the same LRCK
|
||||
// clock, ADC LRCK as internal LRCK
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0
|
||||
res |= es8388_set_adc_dac_volume (ES_MODULE_DAC, 0, 0); // 0db
|
||||
int tmp = 0;
|
||||
if (AUDIO_HAL_DAC_OUTPUT_LINE2 == cfg->dac_output)
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_ROUT1;
|
||||
}
|
||||
else if (AUDIO_HAL_DAC_OUTPUT_LINE1 == cfg->dac_output)
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1
|
||||
| DAC_OUTPUT_ROUT2;
|
||||
}
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
tmp); // 0x3c Enable DAC and Enable Lout/Rout/1/2
|
||||
/* adc */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER, 0xFF);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL1,
|
||||
0xbb); // MIC Left and Right channel PGA gain
|
||||
tmp = 0;
|
||||
if (AUDIO_HAL_ADC_INPUT_LINE1 == cfg->adc_input)
|
||||
{
|
||||
tmp = ADC_INPUT_LINPUT1_RINPUT1;
|
||||
}
|
||||
else if (AUDIO_HAL_ADC_INPUT_LINE2 == cfg->adc_input)
|
||||
{
|
||||
tmp = ADC_INPUT_LINPUT2_RINPUT2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = ADC_INPUT_DIFFERENCE;
|
||||
}
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL2,
|
||||
tmp); // 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input;
|
||||
// DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL3, 0x02);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4,
|
||||
0x0d); // Left/Right data, Left/Right justified mode,
|
||||
// Bits length, I2S format
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
0x02); // ADCFsMode,singel SPEED,RATIO=256
|
||||
// ALC for Microphone
|
||||
res |= es8388_set_adc_dac_volume (ES_MODULE_ADC, 0, 0); // 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x09); // Power on ADC, Enable LIN&RIN, Power off
|
||||
// MICBIAS, set int1lp to low power mode
|
||||
/* enable es8388 PA */
|
||||
es8388_pa_power (true);
|
||||
ESP_LOGI (ES_TAG, "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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_fmt (es_module_t mode, es_i2s_fmt_t fmt)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xfc;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4, reg | fmt);
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xf9;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL1, reg | (fmt << 1));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param volume: 0 ~ 100
|
||||
*
|
||||
* @return
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_voice_volume (int volume)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
else if (volume > 100)
|
||||
volume = 100;
|
||||
volume /= 3;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_DACCONTROL24, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL25, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL26, 0);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL27, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* volume
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_get_voice_volume (int *volume)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACCONTROL24, ®);
|
||||
if (res == ESP_FAIL)
|
||||
{
|
||||
*volume = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*volume = reg;
|
||||
*volume *= 3;
|
||||
if (*volume == 99)
|
||||
*volume = 100;
|
||||
}
|
||||
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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_bits_per_sample (es_module_t mode, es_bits_length_t bits_length)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
int bits = (int)bits_length;
|
||||
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xe3;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4, reg | (bits << 2));
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xc7;
|
||||
res |= es_write_reg (ES8388_ADDR, 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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_voice_mute (bool enable)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACCONTROL3, ®);
|
||||
reg = reg & 0xFB;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL3,
|
||||
reg | (((int)enable) << 2));
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_get_voice_mute (void)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_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
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_dac_output (int output)
|
||||
{
|
||||
esp_err_t res;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACPOWER, ®);
|
||||
reg = reg & 0xc3;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER, reg | output);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gain: Config ADC input
|
||||
*
|
||||
* @return
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_adc_input (es_adc_input_t input)
|
||||
{
|
||||
esp_err_t res;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_ADCCONTROL2, ®);
|
||||
reg = reg & 0x0f;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL2, reg | input);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gain: see es_mic_gain_t
|
||||
*
|
||||
* @return
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_mic_gain (es_mic_gain_t gain)
|
||||
{
|
||||
esp_err_t res, gain_n;
|
||||
gain_n = (int)gain / 3;
|
||||
gain_n = (gain_n << 4) + gain_n;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL1, gain_n); // MIC PGA
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
es8388_ctrl_state (audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
|
||||
{
|
||||
int res = 0;
|
||||
int es_mode_t = 0;
|
||||
switch (mode)
|
||||
{
|
||||
case AUDIO_HAL_CODEC_MODE_ENCODE:
|
||||
es_mode_t = ES_MODULE_ADC;
|
||||
break;
|
||||
case AUDIO_HAL_CODEC_MODE_LINE_IN:
|
||||
es_mode_t = ES_MODULE_LINE;
|
||||
break;
|
||||
case AUDIO_HAL_CODEC_MODE_DECODE:
|
||||
es_mode_t = ES_MODULE_DAC;
|
||||
break;
|
||||
case AUDIO_HAL_CODEC_MODE_BOTH:
|
||||
es_mode_t = ES_MODULE_ADC_DAC;
|
||||
break;
|
||||
default:
|
||||
es_mode_t = ES_MODULE_DAC;
|
||||
ESP_LOGW (ES_TAG, "Codec mode not support, default is decode mode");
|
||||
break;
|
||||
}
|
||||
if (AUDIO_HAL_CTRL_STOP == ctrl_state)
|
||||
{
|
||||
res = es8388_stop (es_mode_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = es8388_start (es_mode_t);
|
||||
ESP_LOGD (ES_TAG, "start default is decode mode:%d", es_mode_t);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
int tmp = 0;
|
||||
res |= es8388_config_fmt (ES_MODULE_ADC_DAC, iface->fmt);
|
||||
if (iface->bits == AUDIO_HAL_BIT_LENGTH_16BITS)
|
||||
{
|
||||
tmp = BIT_LENGTH_16BITS;
|
||||
}
|
||||
else if (iface->bits == AUDIO_HAL_BIT_LENGTH_24BITS)
|
||||
{
|
||||
tmp = BIT_LENGTH_24BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = BIT_LENGTH_32BITS;
|
||||
}
|
||||
res |= es8388_set_bits_per_sample (ES_MODULE_ADC_DAC, tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
es8388_pa_power (bool enable)
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
memset (&io_conf, 0, sizeof (io_conf));
|
||||
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
||||
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);
|
||||
if (enable)
|
||||
{
|
||||
gpio_set_level (get_pa_enable_gpio (), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_level (get_pa_enable_gpio (), 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user