Trying to patch the I2C bus directly from esp_adf. Should be a lot more logical to do this way

This commit is contained in:
X-Ryl669 2024-03-10 14:32:28 +01:00
parent 7208dd25d0
commit c6fea06dba
5 changed files with 115 additions and 77 deletions

View file

@ -5,9 +5,15 @@ import esphome.codegen as cg
import esphome.final_validate as fv
from esphome.components import esp32
from esphome.components.i2c import I2CDevice, i2c_ns, I2CBus, CONFIG_SCHEMA as I2C_CONFIG_SCHEMA
from esphome.core import CORE
from esphome.const import CONF_ID, CONF_BOARD
from pprint import pprint
CODEOWNERS = ["@jesserockz"]
DEPENDENCIES = ["esp32"]
@ -77,15 +83,19 @@ async def to_code(config):
submodules=["components/esp-sr", "components/esp-adf-libs"],
)
esp32.add_idf_component(
name="esp-dsp",
repo="https://github.com/espressif/esp-dsp",
ref="v1.2.0",
)
# esp32.add_idf_component(
# name="esp-dsp",
# repo="https://github.com/espressif/esp-dsp",
# ref="v1.4.0",
# )
cg.add_platformio_option(
"board_build.embed_txtfiles", "components/dueros_service/duer_profile"
)
# This is required for esp-dsp that have files with the same basename and different extension (.S,.c)
cg.add_platformio_option(
"board_build.esp-idf.preserve_source_file_extension", "yes"
)
if board := config.get(CONF_BOARD):
cg.add_define("USE_ESP_ADF_BOARD")
@ -101,3 +111,20 @@ async def to_code(config):
"esp_adf_patches/idf_v4.4_freertos.patch",
"https://github.com/X-Ryl669/esp-adf/raw/with-i2c-cb/idf_patches/idf_v4.4_freertos.patch",
)
# I2C Bus below
ADFI2CBus = i2c_ns.class_("ADFI2CBus", I2CBus, cg.Component)
# Patch the I2C config schema to use the right I2C bus
def _patch_idfi2cbus(config):
from esphome.cpp_generator import MockObjClass
if not CORE.is_esp32:
raise cv.Invalid("Not supported on other CPU that ESP32")
if "i2c" in fv.full_config.get():
for i2c_inst in fv.full_config.get()["i2c"]:
i2c_inst["id"].type = MockObjClass("i2c::ADFI2CBus", parents = i2c_inst["id"].type._parents)
return config
FINAL_VALIDATE_SCHEMA = _patch_idfi2cbus

View file

@ -48,7 +48,7 @@ void ADFI2CBus::setup() {
this->mark_failed();
return;
}
if (i2c_bus_run_cb(this->handle_, &recover_i2c_hard, this) != ESP_OK)
if (i2c_bus_run_cb(this->handle_, &recover_i2c_hard, this) != ESP_OK) {
ESP_LOGW(TAG, "i2c_bus_recover failed");
this->mark_failed();
return;
@ -99,6 +99,8 @@ struct ReadVCmd
size_t cnt;
ErrorCode code { ERROR_UNKNOWN };
ReadVCmd(uint8_t address, ReadBuffer * buffers, size_t cnt) : address(address), buffers(buffers), cnt(cnt) {}
ErrorCode read(i2c_port_t port) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
esp_err_t err = i2c_master_start(cmd);
@ -192,6 +194,9 @@ struct WriteVCmd
bool stop;
ErrorCode code { ERROR_UNKNOWN };
WriteVCmd(uint8_t address, WriteBuffer * buffers, size_t cnt, bool stop) : address(address), buffers(buffers), cnt(cnt), stop(stop) {}
ErrorCode write(i2c_port_t port) {
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
char debug_buf[4];

View file

@ -1,7 +1,13 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_ESP_ADF
#include <esp_peripherals/driver/i2c_bus/i2c_bus.h>
/* Tried and failed with:
esp_peripherals/driver/i2c_bus/i2c_bus.h
driver/i2c_bus/i2c_bus.h
*/
#include "../components/esp_peripherals/driver/i2c_bus/i2c_bus.h"
#include "esphome/components/i2c/i2c_bus.h"
#include "esphome/core/component.h"
#include <driver/i2c.h>
@ -9,13 +15,14 @@
namespace esphome {
namespace i2c {
enum RecoveryCode {
RECOVERY_FAILED_SCL_LOW,
RECOVERY_FAILED_SDA_LOW,
RECOVERY_COMPLETED,
};
class ADFI2CBus : public I2CBus, public Component {
private:
enum RecoveryCode {
RECOVERY_FAILED_SCL_LOW,
RECOVERY_FAILED_SDA_LOW,
RECOVERY_COMPLETED,
};
public:
void setup() override;
void dump_config() override;
@ -30,7 +37,7 @@ class ADFI2CBus : public I2CBus, public Component {
void set_scl_pullup_enabled(bool scl_pullup_enabled) { scl_pullup_enabled_ = scl_pullup_enabled; }
void set_frequency(uint32_t frequency) { frequency_ = frequency; }
private:
public:
void recover_();
RecoveryCode recovery_result_;
@ -41,7 +48,7 @@ class ADFI2CBus : public I2CBus, public Component {
bool scl_pullup_enabled_;
uint32_t frequency_;
i2c_bus_t handle_;
i2c_bus_handle_t handle_;
};
} // namespace i2c

View file

@ -81,38 +81,37 @@ void ESPADFMicrophone::read_task(void *params) {
};
audio_pipeline_handle_t pipeline = audio_pipeline_init(&pipeline_cfg);
i2s_driver_config_t i2s_config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
.dma_buf_count = 8,
.dma_buf_len = 128,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = 0,
.mclk_multiple = I2S_MCLK_MULTIPLE_256,
.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
};
i2s_driver_config_t i2s_config = {};
i2s_config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX);
i2s_config.sample_rate = 16000;
i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM;
i2s_config.dma_buf_count = 8;
i2s_config.dma_buf_len = 128;
i2s_config.use_apll = false;
i2s_config.tx_desc_auto_clear = true;
i2s_config.fixed_mclk = 0;
i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_256;
i2s_config.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT;
i2s_stream_cfg_t i2s_cfg = {};
i2s_cfg.type = AUDIO_STREAM_READER;
i2s_cfg.i2s_config = i2s_config;
i2s_cfg.i2s_port = static_cast<i2s_port_t>(CODEC_ADC_I2S_PORT);
i2s_cfg.use_alc = false;
i2s_cfg.volume = 0;
i2s_cfg.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE;
i2s_cfg.task_stack = I2S_STREAM_TASK_STACK;
i2s_cfg.task_core = I2S_STREAM_TASK_CORE;
i2s_cfg.task_prio = I2S_STREAM_TASK_PRIO;
i2s_cfg.stack_in_ext = false;
i2s_cfg.multi_out_num = 0;
i2s_cfg.uninstall_drv = true;
i2s_cfg.need_expand = false;
i2s_cfg.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT;
i2s_stream_cfg_t i2s_cfg = {
.type = AUDIO_STREAM_READER,
.i2s_config = i2s_config,
.i2s_port = static_cast<i2s_port_t>(CODEC_ADC_I2S_PORT),
.use_alc = false,
.volume = 0,
.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,
.task_stack = I2S_STREAM_TASK_STACK,
.task_core = I2S_STREAM_TASK_CORE,
.task_prio = I2S_STREAM_TASK_PRIO,
.stack_in_ext = false,
.multi_out_num = 0,
.uninstall_drv = true,
.need_expand = false,
.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT,
};
audio_element_handle_t i2s_stream_reader = i2s_stream_init(&i2s_cfg);
rsp_filter_cfg_t rsp_cfg = {

View file

@ -43,43 +43,43 @@ void ESPADFSpeaker::player_task(void *params) {
event.type = TaskEventType::STARTING;
xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
i2s_driver_config_t i2s_config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
.dma_buf_count = 8,
.dma_buf_len = 1024,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = 0,
.mclk_multiple = I2S_MCLK_MULTIPLE_256,
.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
};
i2s_driver_config_t i2s_config = {};
i2s_config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX);
i2s_config.sample_rate = 16000;
i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM;
i2s_config.dma_buf_count = 8;
i2s_config.dma_buf_len = 1024;
i2s_config.use_apll = false;
i2s_config.tx_desc_auto_clear = true;
i2s_config.fixed_mclk = 0;
i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_256;
i2s_config.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT;
audio_pipeline_cfg_t pipeline_cfg = {
.rb_size = 8 * 1024,
};
audio_pipeline_handle_t pipeline = audio_pipeline_init(&pipeline_cfg);
i2s_stream_cfg_t i2s_cfg = {
.type = AUDIO_STREAM_WRITER,
.i2s_config = i2s_config,
.i2s_port = I2S_NUM_0,
.use_alc = false,
.volume = 0,
.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,
.task_stack = I2S_STREAM_TASK_STACK,
.task_core = I2S_STREAM_TASK_CORE,
.task_prio = I2S_STREAM_TASK_PRIO,
.stack_in_ext = false,
.multi_out_num = 0,
.uninstall_drv = true,
.need_expand = false,
.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT,
};
i2s_stream_cfg_t i2s_cfg = {};
i2s_cfg.type = AUDIO_STREAM_WRITER;
i2s_cfg.i2s_config = i2s_config;
i2s_cfg.i2s_port = I2S_NUM_0;
i2s_cfg.use_alc = false;
i2s_cfg.volume = 0;
i2s_cfg.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE;
i2s_cfg.task_stack = I2S_STREAM_TASK_STACK;
i2s_cfg.task_core = I2S_STREAM_TASK_CORE;
i2s_cfg.task_prio = I2S_STREAM_TASK_PRIO;
i2s_cfg.stack_in_ext = false;
i2s_cfg.multi_out_num = 0;
i2s_cfg.uninstall_drv = true;
i2s_cfg.need_expand = false;
i2s_cfg.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT;
audio_element_handle_t i2s_stream_writer = i2s_stream_init(&i2s_cfg);
rsp_filter_cfg_t rsp_cfg = {