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:
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user