Skip to content

Commit

Permalink
i2s: adds i2s_rxtxdrive_begin(enableRx, enableTx, driveRxClocks, driv…
Browse files Browse the repository at this point in the history
…eTxClocks) (#7748)

Two parameters are added to allow using only i2s-in/out-data pin.
This is necessary when i2so-bck and i2so-ws are repurposed
especially because they overlap with SPI GPIO.
  • Loading branch information
d-a-v authored Dec 12, 2020
1 parent e76a98d commit 1e016a4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
35 changes: 25 additions & 10 deletions cores/esp8266/core_esp8266_i2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct i2s_state {
// Callback function should be defined as 'void ICACHE_RAM_ATTR function_name()',
// and be placed in IRAM for faster execution. Avoid long computational tasks in this
// function, use it to set flags and process later.
bool driveClocks;
} i2s_state_t;

// RX = I2S receive (i.e. microphone), TX = I2S transmit (i.e. DAC)
Expand Down Expand Up @@ -493,6 +494,10 @@ float i2s_get_real_rate(){
}

bool i2s_rxtx_begin(bool enableRx, bool enableTx) {
return i2s_rxtxdrive_begin(enableRx, enableTx, true, true);
}

bool i2s_rxtxdrive_begin(bool enableRx, bool enableTx, bool driveRxClocks, bool driveTxClocks) {
if (tx || rx) {
i2s_end(); // Stop and free any ongoing stuff
}
Expand All @@ -503,22 +508,28 @@ bool i2s_rxtx_begin(bool enableRx, bool enableTx) {
// Nothing to clean up yet
return false; // OOM Error!
}
pinMode(I2SO_WS, FUNCTION_1);
tx->driveClocks = driveTxClocks;
pinMode(I2SO_DATA, FUNCTION_1);
pinMode(I2SO_BCK, FUNCTION_1);
if (driveTxClocks) {
pinMode(I2SO_WS, FUNCTION_1);
pinMode(I2SO_BCK, FUNCTION_1);
}
}
if (enableRx) {
rx = (i2s_state_t*)calloc(1, sizeof(*rx));
if (!rx) {
i2s_end(); // Clean up any TX or pin changes
return false; // OOM error!
}
pinMode(I2SI_WS, OUTPUT);
pinMode(I2SI_BCK, OUTPUT);
rx->driveClocks = driveRxClocks;
pinMode(I2SI_DATA, INPUT);
if (driveRxClocks) {
pinMode(I2SI_WS, OUTPUT);
pinMode(I2SI_BCK, OUTPUT);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_I2SI_BCK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_I2SI_WS);
}
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_I2SI_DATA);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_I2SI_BCK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_I2SI_WS);
}

if (!i2s_slc_begin()) {
Expand Down Expand Up @@ -579,15 +590,19 @@ void i2s_end() {

if (tx) {
pinMode(I2SO_DATA, INPUT);
pinMode(I2SO_BCK, INPUT);
pinMode(I2SO_WS, INPUT);
if (tx->driveClocks) {
pinMode(I2SO_BCK, INPUT);
pinMode(I2SO_WS, INPUT);
}
free(tx);
tx = NULL;
}
if (rx) {
pinMode(I2SI_DATA, INPUT);
pinMode(I2SI_BCK, INPUT);
pinMode(I2SI_WS, INPUT);
if (rx->driveClocks) {
pinMode(I2SI_BCK, INPUT);
pinMode(I2SI_WS, INPUT);
}
free(rx);
rx = NULL;
}
Expand Down
3 changes: 3 additions & 0 deletions cores/esp8266/i2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#ifndef I2S_h
#define I2S_h

#define I2S_HAS_BEGIN_RXTX_DRIVE_CLOCKS 1

/*
How does this work? Basically, to get sound, you need to:
- Connect an I2S codec to the I2S pins on the ESP.
Expand All @@ -42,6 +44,7 @@ extern "C" {

void i2s_begin(); // Enable TX only, for compatibility
bool i2s_rxtx_begin(bool enableRx, bool enableTx); // Allow TX and/or RX, returns false on OOM error
bool i2s_rxtxdrive_begin(bool enableRx, bool enableTx, bool driveRxClocks, bool driveTxClocks);
void i2s_end();
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
void i2s_set_dividers(uint8_t div1, uint8_t div2);//Direct control over output rate
Expand Down

0 comments on commit 1e016a4

Please sign in to comment.