1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-08 17:02:26 +03:00

i2s: adds i2s_rxtxdrive_begin(enableRx, enableTx, driveRxClocks, driveTxClocks) (#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.
This commit is contained in:
david gauchard
2020-12-12 01:41:30 +01:00
committed by GitHub
parent e76a98d335
commit 1e016a4237
2 changed files with 28 additions and 10 deletions

View File

@ -64,6 +64,7 @@ typedef struct i2s_state {
// Callback function should be defined as 'void ICACHE_RAM_ATTR function_name()', // 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 // and be placed in IRAM for faster execution. Avoid long computational tasks in this
// function, use it to set flags and process later. // function, use it to set flags and process later.
bool driveClocks;
} i2s_state_t; } i2s_state_t;
// RX = I2S receive (i.e. microphone), TX = I2S transmit (i.e. DAC) // 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) { 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) { if (tx || rx) {
i2s_end(); // Stop and free any ongoing stuff i2s_end(); // Stop and free any ongoing stuff
} }
@ -503,23 +508,29 @@ bool i2s_rxtx_begin(bool enableRx, bool enableTx) {
// Nothing to clean up yet // Nothing to clean up yet
return false; // OOM Error! return false; // OOM Error!
} }
pinMode(I2SO_WS, FUNCTION_1); tx->driveClocks = driveTxClocks;
pinMode(I2SO_DATA, FUNCTION_1); pinMode(I2SO_DATA, FUNCTION_1);
if (driveTxClocks) {
pinMode(I2SO_WS, FUNCTION_1);
pinMode(I2SO_BCK, FUNCTION_1); pinMode(I2SO_BCK, FUNCTION_1);
} }
}
if (enableRx) { if (enableRx) {
rx = (i2s_state_t*)calloc(1, sizeof(*rx)); rx = (i2s_state_t*)calloc(1, sizeof(*rx));
if (!rx) { if (!rx) {
i2s_end(); // Clean up any TX or pin changes i2s_end(); // Clean up any TX or pin changes
return false; // OOM error! return false; // OOM error!
} }
rx->driveClocks = driveRxClocks;
pinMode(I2SI_DATA, INPUT);
if (driveRxClocks) {
pinMode(I2SI_WS, OUTPUT); pinMode(I2SI_WS, OUTPUT);
pinMode(I2SI_BCK, OUTPUT); pinMode(I2SI_BCK, OUTPUT);
pinMode(I2SI_DATA, INPUT);
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_MTCK_U, FUNC_I2SI_BCK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_I2SI_WS); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_I2SI_WS);
} }
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_I2SI_DATA);
}
if (!i2s_slc_begin()) { if (!i2s_slc_begin()) {
// OOM in SLC memory allocations, tear it all down and abort! // OOM in SLC memory allocations, tear it all down and abort!
@ -579,15 +590,19 @@ void i2s_end() {
if (tx) { if (tx) {
pinMode(I2SO_DATA, INPUT); pinMode(I2SO_DATA, INPUT);
if (tx->driveClocks) {
pinMode(I2SO_BCK, INPUT); pinMode(I2SO_BCK, INPUT);
pinMode(I2SO_WS, INPUT); pinMode(I2SO_WS, INPUT);
}
free(tx); free(tx);
tx = NULL; tx = NULL;
} }
if (rx) { if (rx) {
pinMode(I2SI_DATA, INPUT); pinMode(I2SI_DATA, INPUT);
if (rx->driveClocks) {
pinMode(I2SI_BCK, INPUT); pinMode(I2SI_BCK, INPUT);
pinMode(I2SI_WS, INPUT); pinMode(I2SI_WS, INPUT);
}
free(rx); free(rx);
rx = NULL; rx = NULL;
} }

View File

@ -21,6 +21,8 @@
#ifndef I2S_h #ifndef I2S_h
#define I2S_h #define I2S_h
#define I2S_HAS_BEGIN_RXTX_DRIVE_CLOCKS 1
/* /*
How does this work? Basically, to get sound, you need to: How does this work? Basically, to get sound, you need to:
- Connect an I2S codec to the I2S pins on the ESP. - 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 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_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_end();
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000) 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 void i2s_set_dividers(uint8_t div1, uint8_t div2);//Direct control over output rate