Skip to content

Commit

Permalink
Merge pull request #20 from RaymiiOrg/configurable_channel
Browse files Browse the repository at this point in the history
Configurable channel (left/right)
  • Loading branch information
stas-sl authored Apr 7, 2024
2 parents 72c4aa2 + 7a56188 commit 3832eeb
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ i2s:
dma_buf_len: 256 # default: 256
use_apll: true # default: false

# according to datasheet when L/R pin is connected to GND,
# the mic should output its signal in the left channel,
# however in my experience it's the opposite: when I connect
# L/R to GND then the signal is in the right channel
channel: right # default: right

# right shift samples.
# for example if mic has 24 bit resolution, and
# i2s configured as 32 bits, then audio data will be aligned left (MSB)
Expand Down
10 changes: 10 additions & 0 deletions components/i2s/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
CONF_DMA_BUF_LEN = "dma_buf_len"
CONF_USE_APLL = "use_apll"
CONF_BITS_SHIFT = "bits_shift"
CONF_CHANNEL = "channel"


i2s_channel_fmt_t = cg.global_ns.enum("i2s_channel_fmt_t")
CHANNELS = {
"left": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT,
"right": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT,
}

CONFIG_SCHEMA = cv.All(
cv.Schema(
Expand All @@ -37,6 +45,7 @@
cv.Optional(CONF_DMA_BUF_LEN, 256): cv.positive_not_null_int,
cv.Optional(CONF_USE_APLL, False): cv.boolean,
cv.Optional(CONF_BITS_SHIFT, 0): cv.int_range(0, 32),
cv.Optional(CONF_CHANNEL, default="right"): cv.enum(CHANNELS),
}
).extend(cv.COMPONENT_SCHEMA),
cv.has_at_least_one_key(CONF_DIN_PIN, CONF_DOUT_PIN),
Expand Down Expand Up @@ -64,3 +73,4 @@ async def to_code(config):
cg.add(var.set_dma_buf_len(config[CONF_DMA_BUF_LEN]))
cg.add(var.set_use_apll(config[CONF_USE_APLL]))
cg.add(var.set_bits_shift(config[CONF_BITS_SHIFT]))
cg.add(var.set_channel(config[CONF_CHANNEL]))
9 changes: 7 additions & 2 deletions components/i2s/i2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ bool I2SComponent::get_use_apll() const { return this->use_apll_; }
void I2SComponent::set_bits_shift(uint8_t bits_shift) { this->bits_shift_ = bits_shift; }
uint8_t I2SComponent::get_bits_shift() const { return this->bits_shift_; }
float I2SComponent::get_setup_priority() const { return setup_priority::BUS; }
void I2SComponent::set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }

void I2SComponent::dump_config() {
ESP_LOGCONFIG(TAG, "I2S %d:", this->port_num_);
Expand All @@ -35,6 +36,10 @@ void I2SComponent::dump_config() {
ESP_LOGCONFIG(TAG, " DMA Buf Len: %u", this->dma_buf_len_);
ESP_LOGCONFIG(TAG, " Use APLL: %s", YESNO(this->use_apll_));
ESP_LOGCONFIG(TAG, " Bits Shift: %u", this->bits_shift_);
ESP_LOGCONFIG(TAG, " Channel: %s",
this->channel_ == I2S_CHANNEL_FMT_ONLY_RIGHT ? "right"
: this->channel_ == I2S_CHANNEL_FMT_ONLY_LEFT ? "left"
: "invalid");
}

bool I2SComponent::read(uint8_t *data, size_t len, size_t *bytes_read, TickType_t ticks_to_wait) {
Expand Down Expand Up @@ -127,10 +132,10 @@ void I2SComponent::setup() {

ESP_LOGCONFIG(TAG, "Setting up I2S %u ...", this->port_num_);

i2s_config_t i2s_config = {.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), // TODO: make it configurable
i2s_config_t i2s_config = {.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = this->sample_rate_,
.bits_per_sample = i2s_bits_per_sample_t(this->bits_per_sample_),
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // TODO: make it configurable
.channel_format = this->channel_,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = this->dma_buf_count_,
Expand Down
2 changes: 2 additions & 0 deletions components/i2s/i2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class I2SComponent : public Component {
bool read_samples(int16_t *data, size_t num_samples, size_t *samples_read, TickType_t ticks_to_wait = portMAX_DELAY);
bool read_samples(float *data, size_t num_samples, size_t *samples_read, TickType_t ticks_to_wait = portMAX_DELAY);
bool read_samples(std::vector<float> &data, TickType_t ticks_to_wait = portMAX_DELAY);
void set_channel(i2s_channel_fmt_t channel);
virtual void setup() override;
virtual void dump_config() override;
virtual float get_setup_priority() const override;
Expand All @@ -50,6 +51,7 @@ class I2SComponent : public Component {
int dma_buf_len_{256};
bool use_apll_{false};
uint8_t bits_shift_{0};
i2s_channel_fmt_t channel_{I2S_CHANNEL_FMT_ONLY_RIGHT};
};
} // namespace i2s
} // namespace esphome
6 changes: 6 additions & 0 deletions configs/advanced-example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ i2s:
dma_buf_len: 256 # default: 256
use_apll: true # default: false

# according to datasheet when L/R pin is connected to GND,
# the mic should output its signal in the left channel,
# however in my experience it's the opposite: when I connect
# L/R to GND then the signal is in the right channel
channel: right # default: right

# right shift samples.
# for example if mic has 24 bit resolution, and
# i2s configured as 32 bits, then audio data will be aligned left (MSB)
Expand Down
1 change: 1 addition & 0 deletions configs/sensor-community-example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ i2s:
dma_buf_len: 256
use_apll: true
bits_shift: 8
channel: right

sound_level_meter:
update_interval: 150s # to match original sensor.community firmware settings
Expand Down

0 comments on commit 3832eeb

Please sign in to comment.