LINUX下ESP-ADF搭建 在原子esp32s3上跑通http_mp3例程
·
开发环境如下:

IDF是通过EIM离线安装的。
一、ADF获取
由于ADF是以IDF为底层,所以需要注意版本问题,这里我根据例程,选择IDF v5.3.5。
这里我选择 ADF v2.8。
先输入如下命令(注意上网环境):
cd ~/esp
git clone --recursive https://github.com/espressif/esp-adf.git
目前默认是v2.8。
二、ADF安装

进入这个会有弹窗,选择第三个
之后再选择如下目录
此时就安装完成了。
三、跑通HTTP_MP3例程
新建例程,步骤参考如下:


根据自己的情况配置
新建完项目,试着编译一下工程,应该是可以编译通过的。
接着移植自己的开发板,进入下图所示目录:

复制
该文件夹进行重命名。

对文件夹里的文件进行修改,修改后如下:
board.h:
/*
* ESPRESSIF MIT License
*
* Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., 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.
*
*/
#ifndef _AUDIO_BOARD_H_
#define _AUDIO_BOARD_H_
#include "audio_hal.h"
#include "board_def.h"
#include "board_pins_config.h"
#include "esp_peripherals.h"
#include "display_service.h"
#include "periph_sdcard.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Audio board handle
*/
struct audio_board_handle {
audio_hal_handle_t audio_hal; /*!< audio hardware abstract layer handle */
};
typedef struct audio_board_handle *audio_board_handle_t;
/**
* @brief Initialize audio board
*
* @return The audio board handle
*/
audio_board_handle_t audio_board_init(void);
/**
* @brief Initialize codec chip
*
* @return The audio hal handle
*/
audio_hal_handle_t audio_board_codec_init(void);
/**
* @brief Initialize led peripheral and display service
*
* @return The audio display service handle
*/
display_service_handle_t audio_board_led_init(void);
/**
* @brief Initialize key peripheral
*
* @param set The handle of esp_periph_set_handle_t
*
* @return
* - ESP_OK, success
* - Others, fail
*/
esp_err_t audio_board_key_init(esp_periph_set_handle_t set);
/**
* @brief Initialize sdcard peripheral
*
* @param set The handle of esp_periph_set_handle_t
*
* @return
* - ESP_OK, success
* - Others, fail
*/
esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode);
/**
* @brief Query audio_board_handle
*
* @return The audio board handle
*/
audio_board_handle_t audio_board_get_handle(void);
/**
* @brief Uninitialize the audio board
*
* @param audio_board The handle of audio board
*
* @return 0 success,
* others fail
*/
esp_err_t audio_board_deinit(audio_board_handle_t audio_board);
#ifdef __cplusplus
}
#endif
// XL9555初始化
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "string.h"
#include "driver/i2c.h"
// 使用旧版I2C头文件
/* 引脚与相关参数定义 */
#define XL9555_INT_IO GPIO_NUM_40 /* XL9555_INT引脚 */
/* XL9555寄存器宏 */
#define XL9555_INPUT_PORT0_REG 0 /* 输入寄存器0地址 */
#define XL9555_INPUT_PORT1_REG 1 /* 输入寄存器1地址 */
#define XL9555_OUTPUT_PORT0_REG 2 /* 输出寄存器0地址 */
#define XL9555_OUTPUT_PORT1_REG 3 /* 输出寄存器1地址 */
#define XL9555_INVERSION_PORT0_REG 4 /* 极性反转寄存器0地址 */
#define XL9555_INVERSION_PORT1_REG 5 /* 极性反转寄存器1地址 */
#define XL9555_CONFIG_PORT0_REG 6 /* 方向配置寄存器0地址 */
#define XL9555_CONFIG_PORT1_REG 7 /* 方向配置寄存器1地址 */
#define XL9555_ADDR 0X40 /* XL9555器件7位地址-->请看手册(9.1. Device Address) */
/* XL9555各个IO的功能 */
#define AP_INT_IO 0x0001
#define QMA_INT_IO 0x0002
#define SPK_EN_IO 0x0004
#define BEEP_IO 0x0008
#define OV_PWDN_IO 0x0010
#define OV_RESET_IO 0x0020
#define GBC_LED_IO 0x0040
#define GBC_KEY_IO 0x0080
#define LCD_BL_IO 0x0100
#define CT_RST_IO 0x0200
#define SLCD_RST_IO 0x0400
#define SLCD_PWR_IO 0x0800
#define KEY3_IO 0x1000
#define KEY2_IO 0x2000
#define KEY1_IO 0x4000
#define KEY0_IO 0x8000
#define KEY0 xl9555_pin_read(KEY0_IO) /* 读取KEY0引脚 */
#define KEY1 xl9555_pin_read(KEY1_IO) /* 读取KEY1引脚 */
#define KEY2 xl9555_pin_read(KEY2_IO) /* 读取KEY2引脚 */
#define KEY3 xl9555_pin_read(KEY3_IO) /* 读取KEY3引脚 */
#define KEY0_PRES 1 /* KEY0按下 */
#define KEY1_PRES 2 /* KEY1按下 */
#define KEY2_PRES 3 /* KEY1按下 */
#define KEY3_PRES 4 /* KEY1按下 */
/* 函数声明 */
esp_err_t xl9555_init(void); /* 初始化XL9555 */
int xl9555_pin_read(uint16_t pin); /* 获取某个IO状态 */
uint16_t xl9555_pin_write(uint16_t pin, int val); /* 控制某个IO的电平 */
esp_err_t xl9555_read_byte(uint8_t* data, size_t len); /* 读取XL9555的IO值 */
esp_err_t xl9555_write_byte(uint8_t reg, uint8_t *data, size_t len); /* 向XL9555寄存器写入数据 */
uint8_t xl9555_key_scan(uint8_t mode); /* 扫描扩展按键 */
void xl9555_int_init(void); /* 初始化XL9555的中断引脚 */
#endif
board.c内容没动
board_def.h
/*
* ESPRESSIF MIT License
*
* Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., 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.
*
*/
#ifndef _AUDIO_BOARD_DEFINITION_H_
#define _AUDIO_BOARD_DEFINITION_H_
#include "driver/touch_pad.h"
/**
* @brief SDCARD Function Definition
*/
#define FUNC_SDCARD_EN (0)
#define SDCARD_OPEN_FILE_NUM_MAX 5
#define SDCARD_INTR_GPIO GPIO_NUM_NC
#define ESP_SD_PIN_CLK GPIO_NUM_NC
#define ESP_SD_PIN_CMD GPIO_NUM_NC
#define ESP_SD_PIN_D0 GPIO_NUM_NC
#define ESP_SD_PIN_D1 GPIO_NUM_NC
#define ESP_SD_PIN_D2 GPIO_NUM_NC
#define ESP_SD_PIN_D3 GPIO_NUM_NC
#define ESP_SD_PIN_D4 GPIO_NUM_NC
#define ESP_SD_PIN_D5 GPIO_NUM_NC
#define ESP_SD_PIN_D6 GPIO_NUM_NC
#define ESP_SD_PIN_D7 GPIO_NUM_NC
#define ESP_SD_PIN_CD GPIO_NUM_NC
#define ESP_SD_PIN_WP GPIO_NUM_NC
// #define ESP_SD_PIN_CS GPIO_NUM_2
// #define ESP_SD_PIN_SCK GPIO_NUM_12
// #define ESP_SD_PIN_MOSI GPIO_NUM_11
// #define ESP_SD_PIN_MISO GPIO_NUM_13
/**
* @brief LED Function Definition
*/
#define FUNC_SYS_LEN_EN (1)
#define GREEN_LED_GPIO GPIO_NUM_1
/**
* @brief Audio Codec Chip Function Definition
*/
#define FUNC_AUDIO_CODEC_EN (1)
#define AUXIN_DETECT_GPIO -1
#define HEADPHONE_DETECT -1
#define PA_ENABLE_GPIO -1
#define CODEC_ADC_I2S_PORT ((i2s_port_t)0)
#define CODEC_ADC_BITS_PER_SAMPLE ((i2s_data_bit_width_t)16) /* 16bit */
#define CODEC_ADC_SAMPLE_RATE (48000)
#define RECORD_HARDWARE_AEC (false)
#define BOARD_PA_GAIN (10) /* Power amplifier gain defined by board (dB) */
/**
* @brief ADC input data format
*/
#define AUDIO_ADC_INPUT_CH_FORMAT "N"
extern audio_hal_func_t AUDIO_CODEC_ES8388_DEFAULT_HANDLE;
#define AUDIO_CODEC_DEFAULT_CONFIG(){ \
.adc_input = AUDIO_HAL_ADC_INPUT_LINE1, \
.dac_output = AUDIO_HAL_DAC_OUTPUT_ALL, \
.codec_mode = AUDIO_HAL_CODEC_MODE_BOTH, \
.i2s_iface = { \
.mode = AUDIO_HAL_MODE_SLAVE, \
.fmt = AUDIO_HAL_I2S_NORMAL, \
.samples = AUDIO_HAL_48K_SAMPLES, \
.bits = AUDIO_HAL_BIT_LENGTH_16BITS, \
}, \
};
/**
* @brief Button Function Definition
*/
#define FUNC_BUTTON_EN (1)
#define INPUT_KEY_NUM 6
#define BUTTON_REC_ID GPIO_NUM_36
#define BUTTON_MODE_ID GPIO_NUM_39
#define BUTTON_SET_ID TOUCH_PAD_NUM9
#define BUTTON_PLAY_ID TOUCH_PAD_NUM8
#define BUTTON_VOLUP_ID TOUCH_PAD_NUM7
#define BUTTON_VOLDOWN_ID TOUCH_PAD_NUM4
#define INPUT_KEY_DEFAULT_INFO() { \
{ \
.type = PERIPH_ID_BUTTON, \
.user_id = INPUT_KEY_USER_ID_REC, \
.act_id = BUTTON_REC_ID, \
}, \
{ \
.type = PERIPH_ID_BUTTON, \
.user_id = INPUT_KEY_USER_ID_MODE, \
.act_id = BUTTON_MODE_ID, \
}, \
{ \
.type = PERIPH_ID_TOUCH, \
.user_id = INPUT_KEY_USER_ID_SET, \
.act_id = BUTTON_SET_ID, \
}, \
{ \
.type = PERIPH_ID_TOUCH, \
.user_id = INPUT_KEY_USER_ID_PLAY, \
.act_id = BUTTON_PLAY_ID, \
}, \
{ \
.type = PERIPH_ID_TOUCH, \
.user_id = INPUT_KEY_USER_ID_VOLUP, \
.act_id = BUTTON_VOLUP_ID, \
}, \
{ \
.type = PERIPH_ID_TOUCH, \
.user_id = INPUT_KEY_USER_ID_VOLDOWN, \
.act_id = BUTTON_VOLDOWN_ID, \
} \
}
#endif
board_pins_config.c
/*
* ESPRESSIF MIT License
*
* Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., 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 "esp_log.h"
#include "driver/gpio.h"
#include <string.h>
#include "board.h"
#include "audio_error.h"
#include "audio_mem.h"
#include "soc/io_mux_reg.h"
#include "soc/soc_caps.h"
static const char *TAG = "LYRAT_V4_3";
esp_err_t get_i2c_pins(i2c_port_t port, i2c_config_t *i2c_config)
{
AUDIO_NULL_CHECK(TAG, i2c_config, return ESP_FAIL);
if (port == I2C_NUM_0 || port == I2C_NUM_1) {
i2c_config->sda_io_num = GPIO_NUM_41;
i2c_config->scl_io_num = GPIO_NUM_42;
} else {
i2c_config->sda_io_num = -1;
i2c_config->scl_io_num = -1;
ESP_LOGE(TAG, "i2c port %d is not supported", port);
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t get_i2s_pins(int port, board_i2s_pin_t *i2s_config)
{
AUDIO_NULL_CHECK(TAG, i2s_config, return ESP_FAIL);
if (port == 0 || port == 1) {
i2s_config->mck_io_num = GPIO_NUM_3;
i2s_config->bck_io_num = GPIO_NUM_46;
i2s_config->ws_io_num = GPIO_NUM_9;
i2s_config->data_out_num = GPIO_NUM_10;
i2s_config->data_in_num = GPIO_NUM_14;
} else {
memset(i2s_config, -1, sizeof(board_i2s_pin_t));
ESP_LOGE(TAG, "i2s port %d is not supported", port);
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t get_spi_pins(spi_bus_config_t *spi_config, spi_device_interface_config_t *spi_device_interface_config)
{
AUDIO_NULL_CHECK(TAG, spi_config, return ESP_FAIL);
AUDIO_NULL_CHECK(TAG, spi_device_interface_config, return ESP_FAIL);
spi_config->mosi_io_num = -1;
spi_config->miso_io_num = -1;
spi_config->sclk_io_num = -1;
spi_config->quadwp_io_num = -1;
spi_config->quadhd_io_num = -1;
spi_device_interface_config->spics_io_num = -1;
ESP_LOGW(TAG, "SPI interface is not supported");
return ESP_OK;
}
// sdcard
int8_t get_sdcard_intr_gpio(void)
{
return SDCARD_INTR_GPIO;
}
int8_t get_sdcard_open_file_num_max(void)
{
return SDCARD_OPEN_FILE_NUM_MAX;
}
// input-output pins
int8_t get_auxin_detect_gpio(void)
{
return AUXIN_DETECT_GPIO;
}
int8_t get_headphone_detect_gpio(void)
{
return HEADPHONE_DETECT;
}
int8_t get_pa_enable_gpio(void)
{
return PA_ENABLE_GPIO;
}
// button pins
int8_t get_input_rec_id(void)
{
return BUTTON_REC_ID;
}
int8_t get_input_mode_id(void)
{
return BUTTON_MODE_ID;
}
// touch pins
int8_t get_input_set_id(void)
{
return BUTTON_SET_ID;
}
int8_t get_input_play_id(void)
{
return BUTTON_PLAY_ID;
}
int8_t get_input_volup_id(void)
{
return BUTTON_VOLUP_ID;
}
int8_t get_input_voldown_id(void)
{
return BUTTON_VOLDOWN_ID;
}
// led pins
int8_t get_green_led_gpio(void)
{
return GREEN_LED_GPIO;
}
接下来更改这三个文件

CMakeLists.txt
if (CONFIG_ESP32_S3_ALIENTEK_BOARD)
message(STATUS "Current board name is " CONFIG_ESP32_S3_ALIENTEK_BOARD)
list(APPEND COMPONENT_ADD_INCLUDEDIRS ./esp32_s3_alientek)
set(COMPONENT_SRCS
./esp32_s3_alientek/board.c
./esp32_s3_alientek/board_pins_config.c
)
endif()
component.mk
ifdef CONFIG_ESP32_S3_ALIENTEK_BOARD
COMPONENT_ADD_INCLUDEDIRS += ./esp32_s3_alientek
COMPONENT_SRCDIRS += ./esp32_s3_alientek
endif
Kconfig.projbuild
config ESP32_S3_ALIENTEK_BOARD
bool "ESP32_S3_ALIENTEK"
均为在相似部分添加,之后clean再build,打开menuconfig可见

选择刚才的开发板,再build 烧录项目,此时应该可以通过耳机听到声音。
build可能会遇到问题,提示补充补丁,可直接复制给豆包即可解决
但是扬声器需要XL9555,如果直接把官方驱动放进去会有冲突,好像是因为ADF和IDF关于i2c的API不一样。下面改
,添加XL9555。
怎么找?
先进去
再进去

即可进入

修改后内容如下
/*
* 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 <stdint.h>
#include <string.h>
#include "driver/i2c_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "i2c_bus.h"
#include "es8388.h"
#include "board.h"
#include "audio_volume.h"
#include "lwip/err.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;
static codec_dac_volume_config_t *dac_vol_handle;
#define ES8388_DAC_VOL_CFG_DEFAULT() { \
.max_dac_volume = 0, \
.min_dac_volume = -96, \
.board_pa_gain = BOARD_PA_GAIN, \
.volume_accuracy = 0.5, \
.dac_vol_symbol = -1, \
.zero_volume_reg = 0, \
.reg_value = 0, \
.user_volume = 0, \
.offset_conv_volume = NULL, \
}
#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_codec_enable_pa = es8388_pa_power,
.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 = 0;
i2c_config_t es_i2c_cfg = {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_41, /* 正点原子 SDA */
.scl_io_num = GPIO_NUM_42, /* 正点原子 SCL */
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 100000
};
/* 打印确认引脚 */
ESP_LOGI(ES_TAG, "I2C pins: SDA=%d, SCL=%d", es_i2c_cfg.sda_io_num, es_i2c_cfg.scl_io_num);
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, ®);
ESP_LOGI(ES_TAG, "%x: %x", 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
audio_codec_volume_deinit(dac_vol_handle);
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 /* CONFIG_ESP_LYRAT_V4_3_BOARD */
res = i2c_init(); // ESP32 in master mode
if(res != ESP_OK)
{
ESP_LOGE("MAIN","I2C总线初始化失败!");
return res; // 返回真实错误码,不要返回ERR_OK
}
//XL9555初始化,打开扬声器
esp_err_t xl_ret = xl9555_init();
if(xl_ret != ESP_OK){
ESP_LOGW(ES_TAG,"XL9555 init fail, speaker/key/beep not work");
// 允许继续跑音频,只是扩展IO功能失效
}
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
// Disable the internal DLL to improve 8K sample rate
res |= es_write_reg(ES8388_ADDR, 0x35, 0xA0);
res |= es_write_reg(ES8388_ADDR, 0x37, 0xD0);
res |= es_write_reg(ES8388_ADDR, 0x39, 0xD0);
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 |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, 0x1E); // Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dB
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL25, 0x1E);
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL26, 0x1E);
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL27, 0x1E);
// 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, 0x0c); // 16 Bits length and I2S serial audio data 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, and set int1lp to low power mode
/* es8388 PA gpio_config */
if (get_pa_enable_gpio() != -1) {
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(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;
}
/**
* @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
*/
esp_err_t es8388_set_voice_volume(int volume)
{
esp_err_t res = ESP_OK;
uint8_t reg = 0;
reg = audio_codec_get_dac_reg_value(dac_vol_handle, volume);
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL5, reg);
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL4, reg);
ESP_LOGD(ES_TAG, "Set volume:%.2d reg_value:0x%.2x dB:%.1f", (int)dac_vol_handle->user_volume, reg,
audio_codec_cal_dac_volume(dac_vol_handle));
return res;
}
esp_err_t es8388_get_voice_volume(int *volume)
{
esp_err_t res = ESP_OK;
uint8_t reg = 0;
res = es_read_reg(ES8388_DACCONTROL4, ®);
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(ES_TAG, "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
*/
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(es_dac_output_t 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;
}
esp_err_t es8388_pa_power(bool enable)
{
esp_err_t res = ESP_OK;
if (get_pa_enable_gpio() == -1) {
return res;
}
if (enable) {
res = gpio_set_level(get_pa_enable_gpio(), 1);
} else {
res = gpio_set_level(get_pa_enable_gpio(), 0);
}
return res;
}
esp_err_t xl9555_write_byte(uint8_t reg, uint8_t *data, size_t len)
{
esp_err_t ret = i2c_bus_write_bytes(i2c_handle, XL9555_ADDR, ®, 1, data, len);
if (ret != ESP_OK) {
ESP_LOGE("xl9555", "write reg=0x%02X fail: %s", reg, esp_err_to_name(ret));
}
return ret;
}
esp_err_t xl9555_read_byte(uint8_t *data, size_t len)
{
esp_err_t ret;
uint8_t reg = XL9555_INPUT_PORT0_REG;
ret = i2c_bus_read_bytes(i2c_handle, XL9555_ADDR, ®, 1, data, len);
if (ret != ESP_OK) {
ESP_LOGE("xl9555", "read reg=0x%02X fail: %s", reg, esp_err_to_name(ret));
}
return ret;
}
/**
* @brief 控制某个IO的电平
* @param pin : 控制的IO
* @param val : 电平
* @retval 返回所有IO状态
*/
uint16_t xl9555_pin_write(uint16_t pin, int val)
{
uint8_t w_data[2];
uint16_t temp = 0x0000;
xl9555_read_byte(w_data, 2);
if (pin <= 0x0080)
{
if (val)
{
w_data[0] |= (uint8_t)(0xFF & pin);
}
else
{
w_data[0] &= ~(uint8_t)(0xFF & pin);
}
}
else
{
if (val)
{
w_data[1] |= (uint8_t)(0xFF & (pin >> 8));
}
else
{
w_data[1] &= ~(uint8_t)(0xFF & (pin >> 8));
}
}
temp = ((uint16_t)w_data[1] << 8) | w_data[0];
xl9555_write_byte(XL9555_OUTPUT_PORT0_REG, w_data, 2);
return temp;
}
/**
* @brief 获取某个IO状态
* @param pin : 要获取状态的IO
* @retval 此IO口的值(状态, 0/1)
*/
int xl9555_pin_read(uint16_t pin)
{
uint16_t ret;
uint8_t r_data[2];
xl9555_read_byte(r_data, 2);
ret = r_data[1] << 8 | r_data[0];
return (ret & pin) ? 1 : 0;
}
/**
* @brief XL9555的IO配置
* @param config_value:IO配置输入或者输出
* @retval 返回设置的数值
*/
void xl9555_ioconfig(uint16_t config_value)
{
/* 从机地址 + CMD + data1(P0) + data2(P1) */
/* P10、P11、P12、P13和P14为输入,其他引脚为输出 -->0001 1111 0000 0000 注意:0为输出,1为输入*/
uint8_t data[2];
esp_err_t err;
data[0] = (uint8_t)(0xFF & config_value);
data[1] = (uint8_t)(0xFF & (config_value >> 8));
do
{
err = xl9555_write_byte(XL9555_CONFIG_PORT0_REG, data, 2);
if (err != ESP_OK)
{
ESP_LOGE("xl9555", "%s configure %X failed, ret: %d", __func__, config_value, err);
}
vTaskDelay(pdMS_TO_TICKS(100));
} while (err != ESP_OK);
}
esp_err_t xl9555_init(void)
{
uint8_t r_data[2];
/* 上电先读取一次清除中断标志 */
xl9555_read_byte(r_data, 2);
/* 配置那些扩展管脚为输入输出模式 */
xl9555_ioconfig(0xF003);
/* 关闭蜂鸣器 */
xl9555_pin_write(BEEP_IO, 1);
/* 关闭喇叭 */
xl9555_pin_write(SPK_EN_IO, 0);
// xl9555_pin_write(SPK_EN_IO, 1);
return ESP_OK;
}
/**
* @brief 按键扫描函数
* @param mode:0->不连续;1->连续
* @retval 键值, 定义如下:
* KEY0_PRES, 1, KEY0按下
* KEY1_PRES, 2, KEY1按下
* KEY2_PRES, 3, KEY2按下
* KEY3_PRES, 4, KEY3按下
*/
uint8_t xl9555_key_scan(uint8_t mode)
{
uint8_t keyval = 0;
static uint8_t key_up = 1; /* 按键按松开标志 */
if (mode)
{
key_up = 1; /* 支持连按 */
}
if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || KEY3 == 0 )) /* 按键松开标志为1, 且有任意一个按键按下了 */
{
esp_rom_delay_us(100000); /* 去抖动 */
key_up = 0;
if (KEY0 == 0)
{
keyval = KEY0_PRES;
}
if (KEY1 == 0)
{
keyval = KEY1_PRES;
}
if (KEY2 == 0)
{
keyval = KEY2_PRES;
}
if (KEY3 == 0)
{
keyval = KEY3_PRES;
}
}
else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && KEY3 == 1) /* 没有任何按键按下, 标记按键松开 */
{
key_up = 1;
}
return keyval; /* 返回键值 */
}
主要是添加了XL9555,还有改了下es8388 init,让扬声器声音变大些。

新增该函数,修改参数,调节音量。

修改链接,播放中国之声。
限于本人水平,文中难免存在疏漏与不妥,如有错误,敬请包涵指正。
更多推荐



所有评论(0)