diff --git a/cores/esp8266/core_esp8266_i2s.cpp b/cores/esp8266/core_esp8266_i2s.cpp index d783d1afc9..dccd7c1df8 100644 --- a/cores/esp8266/core_esp8266_i2s.cpp +++ b/cores/esp8266/core_esp8266_i2s.cpp @@ -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) @@ -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 } @@ -503,9 +508,12 @@ 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)); @@ -513,12 +521,15 @@ bool i2s_rxtx_begin(bool enableRx, bool enableTx) { 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()) { @@ -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; } diff --git a/cores/esp8266/i2s.h b/cores/esp8266/i2s.h index 70587fd2fb..f2978286af 100644 --- a/cores/esp8266/i2s.h +++ b/cores/esp8266/i2s.h @@ -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. @@ -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