Skip to content

Commit 7641889

Browse files
committed
add second i2s support
1 parent b612109 commit 7641889

File tree

3 files changed

+291
-4
lines changed

3 files changed

+291
-4
lines changed

src/audio_module.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ void Audio_Setup(void)
208208
#endif
209209
#endif
210210

211+
#if defined(DUAL_CODEC_ENABLED) && defined(ES8388_ENABLED)
212+
ES8388_SelectCodec(1);
213+
ES8388_Setup();
214+
ES8388_SetIn2OoutVOL(0, 0);
215+
ES8388_SelectCodec(0);
216+
#endif
211217

212218
#ifdef WM8978_ENABLED
213219
WM8978_Setup();

src/es8388.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ void ES8388_SetOUT1VOL(float vol);
5757
void ES8388_SetOUT1VOL(uint8_t unused, float vol);
5858
void ES8388_SetOUT2VOL(float vol);
5959
void ES8388_SetOUT2VOL(uint8_t unused, float vol);
60-
60+
#ifdef DUAL_CODEC_ENABLED
61+
void ES8388_SelectCodec(bool select);
62+
#endif
6163

6264
#endif // ES8388_ENABLED
6365
#endif // #ifdef ML_SYNTH_INLINE_DECLARATION
@@ -75,6 +77,7 @@ void ES8388_SetOUT2VOL(uint8_t unused, float vol);
7577
/* ES8388 address */
7678
//#define ES8388_ADDR 0x20 /*!< 0x22:CE=1;0x20:CE=0*/
7779
#define ES8388_ADDR 0x10 /*!< 0x22:CE=1;0x20:CE=0*/
80+
#define ES8388_ADDR_SECONDARY 0x11 /*!< 0x22:CE=1;0x20:CE=0*/
7881

7982

8083
/* ES8388 register */
@@ -139,15 +142,35 @@ void ES8388_SetOUT2VOL(uint8_t unused, float vol);
139142
#define ES8388_DACCONTROL29 0x33
140143
#define ES8388_DACCONTROL30 0x34
141144

145+
bool selected_codec_id = 0;
146+
uint16_t codecAddress = ES8388_ADDR;
147+
148+
void ES8388_SelectCodec(bool select)
149+
{
150+
if (selected_codec_id != select)
151+
{
152+
if (select)
153+
{
154+
codecAddress = ES8388_ADDR_SECONDARY;
155+
selected_codec_id = 1;
156+
}
157+
else
158+
{
159+
codecAddress = ES8388_ADDR;
160+
selected_codec_id = 0;
161+
}
162+
}
163+
return;
164+
}
142165

143166
uint8_t ES8388_ReadReg(uint8_t reg)
144167
{
145-
Wire.beginTransmission(ES8388_ADDR);
168+
Wire.beginTransmission(codecAddress);
146169
Wire.write(reg);
147170
Wire.endTransmission(false);
148171

149172
uint8_t val = 0u;
150-
if (1 == Wire.requestFrom(uint16_t(ES8388_ADDR), uint8_t(1), true))
173+
if (1 == Wire.requestFrom(uint16_t(codecAddress), uint8_t(1), true))
151174
{
152175
val = Wire.read();
153176
}
@@ -157,7 +180,7 @@ uint8_t ES8388_ReadReg(uint8_t reg)
157180

158181
bool ES8388_WriteReg(uint8_t reg, uint8_t val)
159182
{
160-
Wire.beginTransmission(ES8388_ADDR);
183+
Wire.beginTransmission(codecAddress);
161184
Wire.write(reg);
162185
Wire.write(val);
163186
return 0 == Wire.endTransmission(true);

src/i2s_interface.h

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@
5252
void setup_i2s();
5353
bool i2s_write_stereo_samples_i16(const int16_t *fl_sample, const int16_t *fr_sample, const int buffLen);
5454
bool i2s_write_stereo_samples_buff(const float *fl_sample, const float *fr_sample, const int buffLen);
55+
bool i2s_write_stereo_samples_buff_dual(const float *fl_sample, const float *fr_sample, const int buffLen, uint8_t codec_num);
56+
bool i2s_write_stereo_samples_i16_dual(const int16_t *fl_sample, const int16_t *fr_sample, const int buffLen, uint8_t codec_num);
5557
void i2s_read_stereo_samples_buff(float *fl_sample, float *fr_sample, const int buffLen);
5658
void i2s_read_stereo_samples_buff(int16_t *fl_sample, int16_t *fr_sample, const int buffLen);
59+
void i2s_read_stereo_samples_buff_dual(float *fl_sample, float *fr_sample, const int buffLen, uint8_t codec_num);
60+
void i2s_read_stereo_samples_i16_dual(int16_t *fl_sample, int16_t *fr_sample, const int buffLen, uint8_t codec_num);
5761

5862
#endif /* ML_SYNTH_INLINE_DECLARATION */
5963

@@ -139,6 +143,10 @@ union sampleTUNT
139143

140144
const i2s_port_t i2s_port_number = I2S_NUM_0;
141145

146+
#ifdef DUAL_CODEC_ENABLED
147+
const i2s_port_t i2s_port_number_secondary = I2S_NUM_1;
148+
#endif
149+
142150
/*
143151
* please refer to https://www.hackster.io/janost/audio-hacking-on-the-esp8266-fa9464#toc-a-simple-909-drum-synth-0
144152
* for the following implementation
@@ -510,6 +518,70 @@ i2s_config_t i2s_configuration =
510518
};
511519
#endif
512520

521+
#ifdef DUAL_CODEC_ENABLED
522+
/* Secondary I2S configuration for dual codec setup */
523+
i2s_config_t i2s_configuration_secondary =
524+
{
525+
.mode = (i2s_mode_t)(I2S_MODE_SLAVE | I2S_MODE_TX | I2S_MODE_RX),
526+
.sample_rate = SAMPLE_RATE * I2S_OVERSAMPLE,
527+
#ifdef SAMPLE_SIZE_32BIT
528+
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
529+
#endif
530+
#ifdef SAMPLE_SIZE_24BIT
531+
.bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT,
532+
#endif
533+
#ifdef SAMPLE_SIZE_16BIT
534+
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
535+
#endif
536+
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
537+
#ifdef ARDUINO_RUNNING_CORE
538+
#ifdef MAX_98357A_ENABLED
539+
.communication_format = I2S_COMM_FORMAT_STAND_PCM_LONG,
540+
#else
541+
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
542+
#endif
543+
#else
544+
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
545+
#endif
546+
.intr_alloc_flags = 0,
547+
.dma_buf_count = 2,
548+
.dma_buf_len = SAMPLE_BUFFER_SIZE,
549+
#ifdef I2S_USE_APLL
550+
.use_apll = true,
551+
#else
552+
.use_apll = false,
553+
#endif
554+
555+
#ifdef ARDUINO_RUNNING_CORE
556+
.tx_desc_auto_clear = true,
557+
.fixed_mclk = 0,
558+
#ifdef I2S_MCLK_MULTIPLE_DEFAULT
559+
.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
560+
#else
561+
.mclk_multiple = I2S_MCLK_MULTIPLE_256,
562+
#endif
563+
#ifdef SAMPLE_SIZE_16BIT
564+
.bits_per_chan = I2S_BITS_PER_CHAN_16BIT,
565+
#endif
566+
#ifdef SAMPLE_SIZE_24BIT
567+
.bits_per_chan = I2S_BITS_PER_CHAN_24BIT,
568+
#endif
569+
#ifdef SAMPLE_SIZE_32BIT
570+
.bits_per_chan = I2S_BITS_PER_CHAN_32BIT,
571+
#endif
572+
#endif
573+
574+
#if SOC_I2S_SUPPORTS_TDM
575+
.chan_mask = I2S_CHANNEL_STEREO,
576+
.total_chan = 0,
577+
.left_align = 0,
578+
.big_edin = 0,
579+
.bit_order_msb = 0,
580+
.skip_msk = 0,
581+
#endif
582+
};
583+
#endif
584+
513585

514586
#ifdef I2S_NODAC
515587
#ifdef ESP8266
@@ -535,6 +607,40 @@ i2s_pin_config_t pins =
535607
};
536608
#endif /* (defined I2S_BCLK_PIN) && (defined I2S_WCLK_PIN) && (defined I2S_DOUT_PIN) */
537609

610+
#ifdef DUAL_CODEC_ENABLED
611+
#if (defined I2S_DOUT_PIN_SECONDARY) || (defined I2S_DIN_PIN_SECONDARY)
612+
/* Secondary I2S pin configuration for dual codec setup */
613+
i2s_pin_config_t pins_secondary =
614+
{
615+
#ifdef I2S_MCLK_PIN_SECONDARY
616+
.mck_io_num = I2S_MCLK_PIN_SECONDARY,
617+
#else
618+
.mck_io_num = I2S_PIN_NO_CHANGE,
619+
#endif
620+
#ifdef I2S_BCLK_PIN_SECONDARY
621+
.bck_io_num = I2S_BCLK_PIN_SECONDARY,
622+
#else
623+
.bck_io_num = I2S_PIN_NO_CHANGE,
624+
#endif
625+
#ifdef I2S_WCLK_PIN_SECONDARY
626+
.ws_io_num = I2S_WCLK_PIN_SECONDARY,
627+
#else
628+
.ws_io_num = I2S_PIN_NO_CHANGE,
629+
#endif
630+
#ifdef I2S_DOUT_PIN_SECONDARY
631+
.data_out_num = I2S_DOUT_PIN_SECONDARY,
632+
#else
633+
.data_out_num = I2S_PIN_NO_CHANGE,
634+
#endif
635+
#ifdef I2S_DIN_PIN_SECONDARY
636+
.data_in_num = I2S_DIN_PIN_SECONDARY,
637+
#else
638+
.data_in_num = I2S_PIN_NO_CHANGE,
639+
#endif
640+
};
641+
#endif /* (defined I2S_BCLK_PIN_SECONDARY) && (defined I2S_WCLK_PIN_SECONDARY) && (defined I2S_DOUT_PIN_SECONDARY) */
642+
#endif /* DUAL_CODEC_ENABLED */
643+
538644
#endif
539645

540646
#if (defined I2S_BCLK_PIN) && (defined I2S_WCLK_PIN) && (defined I2S_DOUT_PIN)
@@ -569,7 +675,49 @@ void setup_i2s()
569675
Serial.printf(" MCLK: %d\n", pins.mck_io_num);
570676
#endif
571677
i2s_set_sample_rates(i2s_port_number, SAMPLE_RATE);
678+
#ifdef DUAL_CODEC_ENABLED
679+
#if (defined I2S_BCLK_PIN_SECONDARY) || (defined I2S_WCLK_PIN_SECONDARY) || (defined I2S_DOUT_PIN_SECONDARY) || (defined I2S_DIN_PIN_SECONDARY)
680+
/* Setup secondary codec */
681+
i2s_driver_install(i2s_port_number_secondary, &i2s_configuration_secondary, 0, NULL);
682+
Serial.printf("Secondary i2s_configuration:\n");
683+
Serial.printf("\ttx_desc_auto_clear: %d\n", i2s_configuration_secondary.tx_desc_auto_clear);
684+
Serial.printf("\tfixed_mclk: %d\n", i2s_configuration_secondary.fixed_mclk);
685+
Serial.printf("\tmclk_multiple: %d\n", i2s_configuration_secondary.mclk_multiple);
686+
Serial.printf("\tbits_per_chan: %d\n", i2s_configuration_secondary.bits_per_chan);
687+
688+
i2s_set_pin(i2s_port_number_secondary, &pins_secondary);
689+
690+
Serial.printf("Secondary I2S_NUM_%d configured using following pins:\n", i2s_port_number_secondary);
691+
Serial.printf(" BCLK,BCK: %d\n", pins_secondary.bck_io_num);
692+
Serial.printf(" WCLK,LCK: %d\n", pins_secondary.ws_io_num);
693+
Serial.printf(" DOUT: %d\n", pins_secondary.data_out_num);
694+
Serial.printf(" DIN: %d\n", pins_secondary.data_in_num);
695+
Serial.printf(" MCLK: %d\n", pins_secondary.mck_io_num);
696+
697+
i2s_set_sample_rates(i2s_port_number_secondary, SAMPLE_RATE);
698+
699+
Serial.printf("Secondary I2S configured using following pins:\n");
700+
Serial.printf(" BCLK,BCK: %d\n", pins_secondary.bck_io_num);
701+
Serial.printf(" WCLK,LCK: %d\n", pins_secondary.ws_io_num);
702+
Serial.printf(" DOUT: %d\n", pins_secondary.data_out_num);
703+
Serial.printf(" DIN: %d\n", pins_secondary.data_in_num);
704+
Serial.printf(" MCLK: %d\n", pins_secondary.mck_io_num);
705+
706+
#endif /* (defined I2S_BCLK_PIN_SECONDARY) && (defined I2S_WCLK_PIN_SECONDARY) && (defined I2S_DOUT_PIN_SECONDARY) */
707+
#include "esp_rom_gpio.h"
708+
#include "soc/i2s_periph.h"
709+
/* Connnect both BCLK signals */
710+
esp_rom_gpio_connect_out_signal(I2S_BCLK_PIN_SECONDARY, i2s_periph_signal[0].m_tx_bck_sig, 0, 0);
711+
esp_rom_gpio_connect_in_signal(I2S_BCLK_PIN_SECONDARY, i2s_periph_signal[1].s_rx_bck_sig, 0);
712+
/* Connect both WS signals */
713+
esp_rom_gpio_connect_out_signal(I2S_WCLK_PIN_SECONDARY, i2s_periph_signal[0].m_tx_ws_sig, 0, 0);
714+
esp_rom_gpio_connect_in_signal(I2S_WCLK_PIN_SECONDARY, i2s_periph_signal[1].s_rx_ws_sig, 0);
715+
i2s_start(i2s_port_number);
716+
i2s_start(i2s_port_number_secondary);
717+
#else
572718
i2s_start(i2s_port_number);
719+
#endif /* DUAL_CODEC_ENABLED */
720+
573721
#ifdef ES8388_ENABLED
574722
#ifdef PIN_CTRL
575723
REG_WRITE(PIN_CTRL, 0xFFFFFFF0);
@@ -606,6 +754,116 @@ void setup_i2s()
606754
}
607755
#endif /* (defined I2S_BCLK_PIN) && (defined I2S_WCLK_PIN) && (defined I2S_DOUT_PIN) */
608756

757+
#ifdef DUAL_CODEC_ENABLED
758+
#ifdef SAMPLE_BUFFER_SIZE
759+
/* Dual codec write function - allows writing to specific codec */
760+
bool i2s_write_stereo_samples_buff_dual(const float *fl_sample, const float *fr_sample, const int buffLen, uint8_t codec_num)
761+
{
762+
static union sampleTUNT sampleDataU[SAMPLE_BUFFER_SIZE];
763+
i2s_port_t target_port = (codec_num == 0) ? i2s_port_number : i2s_port_number_secondary;
764+
765+
for (int n = 0; n < buffLen; n++)
766+
{
767+
/* Using RIGHT_LEFT format for both codecs */
768+
sampleDataU[n].ch[0] = (SAMPLE_DATA_TYPE)(fr_sample[n] * MULTIPLIER_CONST);
769+
sampleDataU[n].ch[1] = (SAMPLE_DATA_TYPE)(fl_sample[n] * MULTIPLIER_CONST);
770+
}
771+
772+
static size_t bytes_written = 0;
773+
774+
#ifdef CYCLE_MODULE_ENABLED
775+
calcCycleCountPre();
776+
#endif
777+
i2s_write(target_port, (const char *)&sampleDataU[0].sample, 2 * BYTES_PER_SAMPLE * buffLen, &bytes_written, portMAX_DELAY);
778+
#ifdef CYCLE_MODULE_ENABLED
779+
calcCycleCount();
780+
#endif
781+
782+
if (bytes_written > 0)
783+
{
784+
return true;
785+
}
786+
else
787+
{
788+
return false;
789+
}
790+
}
791+
792+
/* Dual codec write function for int16 - allows writing to specific codec */
793+
bool i2s_write_stereo_samples_i16_dual(const int16_t *fl_sample, const int16_t *fr_sample, const int buffLen, uint8_t codec_num)
794+
{
795+
static union sampleTUNT sampleDataU[SAMPLE_BUFFER_SIZE];
796+
i2s_port_t target_port = (codec_num == 0) ? i2s_port_number : i2s_port_number_secondary;
797+
798+
for (int n = 0; n < buffLen; n++)
799+
{
800+
/* Using RIGHT_LEFT format for both codecs */
801+
sampleDataU[n].ch[0] = fr_sample[n];
802+
sampleDataU[n].ch[1] = fl_sample[n];
803+
}
804+
805+
static size_t bytes_written = 0;
806+
807+
#ifdef CYCLE_MODULE_ENABLED
808+
calcCycleCountPre();
809+
#endif
810+
i2s_write(target_port, (const char *)&sampleDataU[0].sample, 2 * BYTES_PER_SAMPLE * buffLen, &bytes_written, portMAX_DELAY);
811+
#ifdef CYCLE_MODULE_ENABLED
812+
calcCycleCount();
813+
#endif
814+
815+
if (bytes_written > 0)
816+
{
817+
return true;
818+
}
819+
else
820+
{
821+
return false;
822+
}
823+
}
824+
825+
/* Dual codec read function - allows reading from specific codec */
826+
void i2s_read_stereo_samples_buff_dual(float *fl_sample, float *fr_sample, const int buffLen, uint8_t codec_num)
827+
{
828+
i2s_port_t target_port = (codec_num == 0) ? i2s_port_number : i2s_port_number_secondary;
829+
830+
#ifdef I2S_DIN_PIN
831+
static size_t bytes_read = 0;
832+
static union sampleTUNT sampleData[SAMPLE_BUFFER_SIZE];
833+
834+
i2s_read(target_port, (char *)&sampleData[0].sample, 2 * BYTES_PER_SAMPLE * buffLen, &bytes_read, 0);
835+
836+
for (int n = 0; n < buffLen; n++)
837+
{
838+
/* Using RIGHT_LEFT format */
839+
fr_sample[n] = ((float)sampleData[n].ch[0] * (1.0f / MULTIPLIER_CONST));
840+
fl_sample[n] = ((float)sampleData[n].ch[1] * (1.0f / MULTIPLIER_CONST));
841+
}
842+
#endif
843+
}
844+
845+
/* Dual codec read function for int16 - allows reading from specific codec */
846+
void i2s_read_stereo_samples_i16_dual(int16_t *fl_sample, int16_t *fr_sample, const int buffLen, uint8_t codec_num)
847+
{
848+
i2s_port_t target_port = (codec_num == 0) ? i2s_port_number : i2s_port_number_secondary;
849+
850+
#ifdef I2S_DIN_PIN
851+
static size_t bytes_read = 0;
852+
static union sampleTUNT sampleData[SAMPLE_BUFFER_SIZE];
853+
854+
i2s_read(target_port, (char *)&sampleData[0].sample, 2 * BYTES_PER_SAMPLE * buffLen, &bytes_read, 0);
855+
856+
for (int n = 0; n < buffLen; n++)
857+
{
858+
/* Using RIGHT_LEFT format */
859+
fr_sample[n] = sampleData[n].ch[0];
860+
fl_sample[n] = sampleData[n].ch[1];
861+
}
862+
#endif
863+
}
864+
#endif /* SAMPLE_BUFFER_SIZE */
865+
#endif /* DUAL_CODEC_ENABLED */
866+
609867
#endif /* ESP32 */
610868

611869

0 commit comments

Comments
 (0)