[i2s_audio] Allow config for primary/secondary i2s mode (#7092)

This commit is contained in:
Jesse Hills 2024-07-16 16:28:41 +12:00 committed by GitHub
parent 07b78fea76
commit f1d19416be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 3 deletions

View file

@ -25,6 +25,10 @@ CONF_I2S_LRCLK_PIN = "i2s_lrclk_pin"
CONF_I2S_AUDIO = "i2s_audio" CONF_I2S_AUDIO = "i2s_audio"
CONF_I2S_AUDIO_ID = "i2s_audio_id" CONF_I2S_AUDIO_ID = "i2s_audio_id"
CONF_I2S_MODE = "i2s_mode"
CONF_PRIMARY = "primary"
CONF_SECONDARY = "secondary"
i2s_audio_ns = cg.esphome_ns.namespace("i2s_audio") i2s_audio_ns = cg.esphome_ns.namespace("i2s_audio")
I2SAudioComponent = i2s_audio_ns.class_("I2SAudioComponent", cg.Component) I2SAudioComponent = i2s_audio_ns.class_("I2SAudioComponent", cg.Component)
I2SAudioIn = i2s_audio_ns.class_("I2SAudioIn", cg.Parented.template(I2SAudioComponent)) I2SAudioIn = i2s_audio_ns.class_("I2SAudioIn", cg.Parented.template(I2SAudioComponent))
@ -32,6 +36,12 @@ I2SAudioOut = i2s_audio_ns.class_(
"I2SAudioOut", cg.Parented.template(I2SAudioComponent) "I2SAudioOut", cg.Parented.template(I2SAudioComponent)
) )
i2s_mode_t = cg.global_ns.enum("i2s_mode_t")
I2S_MODE_OPTIONS = {
CONF_PRIMARY: i2s_mode_t.I2S_MODE_MASTER, # NOLINT
CONF_SECONDARY: i2s_mode_t.I2S_MODE_SLAVE, # NOLINT
}
# https://github.com/espressif/esp-idf/blob/master/components/soc/{variant}/include/soc/soc_caps.h # https://github.com/espressif/esp-idf/blob/master/components/soc/{variant}/include/soc/soc_caps.h
I2S_PORTS = { I2S_PORTS = {
VARIANT_ESP32: 2, VARIANT_ESP32: 2,

View file

@ -7,6 +7,9 @@ from esphome.components import microphone, esp32
from esphome.components.adc import ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin from esphome.components.adc import ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin
from .. import ( from .. import (
CONF_I2S_MODE,
CONF_PRIMARY,
I2S_MODE_OPTIONS,
i2s_audio_ns, i2s_audio_ns,
I2SAudioComponent, I2SAudioComponent,
I2SAudioIn, I2SAudioIn,
@ -68,6 +71,9 @@ BASE_SCHEMA = microphone.MICROPHONE_SCHEMA.extend(
_validate_bits, cv.enum(BITS_PER_SAMPLE) _validate_bits, cv.enum(BITS_PER_SAMPLE)
), ),
cv.Optional(CONF_USE_APLL, default=False): cv.boolean, cv.Optional(CONF_USE_APLL, default=False): cv.boolean,
cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.enum(
I2S_MODE_OPTIONS, lower=True
),
} }
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
@ -107,6 +113,7 @@ async def to_code(config):
cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN])) cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN]))
cg.add(var.set_pdm(config[CONF_PDM])) cg.add(var.set_pdm(config[CONF_PDM]))
cg.add(var.set_i2s_mode(config[CONF_I2S_MODE]))
cg.add(var.set_channel(config[CONF_CHANNEL])) cg.add(var.set_channel(config[CONF_CHANNEL]))
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE])) cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE])) cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))

View file

@ -46,7 +46,7 @@ void I2SAudioMicrophone::start_() {
return; // Waiting for another i2s to return lock return; // Waiting for another i2s to return lock
} }
i2s_driver_config_t config = { i2s_driver_config_t config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX), .mode = (i2s_mode_t) (this->i2s_mode_ | I2S_MODE_RX),
.sample_rate = this->sample_rate_, .sample_rate = this->sample_rate_,
.bits_per_sample = this->bits_per_sample_, .bits_per_sample = this->bits_per_sample_,
.channel_format = this->channel_, .channel_format = this->channel_,
@ -174,8 +174,7 @@ size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) {
size_t samples_read = bytes_read / sizeof(int32_t); size_t samples_read = bytes_read / sizeof(int32_t);
samples.resize(samples_read); samples.resize(samples_read);
for (size_t i = 0; i < samples_read; i++) { for (size_t i = 0; i < samples_read; i++) {
int32_t temp = reinterpret_cast<int32_t *>(buf)[i] >> 14; samples[i] = reinterpret_cast<int32_t *>(buf)[i] >> 16;
samples[i] = clamp<int16_t>(temp, INT16_MIN, INT16_MAX);
} }
memcpy(buf, samples.data(), samples_read * sizeof(int16_t)); memcpy(buf, samples.data(), samples_read * sizeof(int16_t));
return samples_read * sizeof(int16_t); return samples_read * sizeof(int16_t);

View file

@ -30,6 +30,8 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
} }
#endif #endif
void set_i2s_mode(i2s_mode_t mode) { this->i2s_mode_ = mode; }
void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; } void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; } void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; } void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
@ -46,6 +48,7 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
bool adc_{false}; bool adc_{false};
#endif #endif
bool pdm_{false}; bool pdm_{false};
i2s_mode_t i2s_mode_{};
i2s_channel_fmt_t channel_; i2s_channel_fmt_t channel_;
uint32_t sample_rate_; uint32_t sample_rate_;
i2s_bits_per_sample_t bits_per_sample_; i2s_bits_per_sample_t bits_per_sample_;