Skip to content

Commit 4ba7df1

Browse files
authored
Add support for I2S MCLK. (#594)
1 parent 0b5da0e commit 4ba7df1

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/AudioOutputI2S.cpp

+35-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int
4949
bclkPin = 26;
5050
wclkPin = 25;
5151
doutPin = 22;
52+
mclkPin = 0;
5253
SetGain(1.0);
5354
}
5455

@@ -61,6 +62,8 @@ AudioOutputI2S::AudioOutputI2S(long sampleRate, pin_size_t sck, pin_size_t data)
6162
hertz = sampleRate;
6263
bclkPin = sck;
6364
doutPin = data;
65+
mclkPin = 0;
66+
use_mclk = false;
6467
SetGain(1.0);
6568
}
6669
#endif
@@ -78,7 +81,7 @@ bool AudioOutputI2S::SetPinout()
7881

7982
i2s_pin_config_t pins = {
8083
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
81-
.mck_io_num = 0, // Unused
84+
.mck_io_num = mclkPin,
8285
#endif
8386
.bck_io_num = bclkPin,
8487
.ws_io_num = wclkPin,
@@ -90,6 +93,8 @@ bool AudioOutputI2S::SetPinout()
9093
(void)bclkPin;
9194
(void)wclkPin;
9295
(void)doutPin;
96+
(void)mclkPin;
97+
(void)use_mclk;
9398
return false;
9499
#endif
95100
}
@@ -104,6 +109,22 @@ bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout)
104109

105110
return true;
106111
}
112+
113+
bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout, int mclk)
114+
{
115+
bclkPin = bclk;
116+
wclkPin = wclk;
117+
doutPin = dout;
118+
#ifdef ESP32
119+
mclkPin = mclk;
120+
if (i2sOn)
121+
return SetPinout();
122+
#else
123+
(void)mclk;
124+
#endif
125+
return true;
126+
}
127+
107128
bool AudioOutputI2S::SetRate(int hz)
108129
{
109130
// TODO - have a list of allowable rates from constructor, check them
@@ -147,6 +168,17 @@ bool AudioOutputI2S::SetLsbJustified(bool lsbJustified)
147168
return true;
148169
}
149170

171+
bool AudioOutputI2S::SetMclk(bool enabled){
172+
(void)enabled;
173+
#ifdef ESP32
174+
if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM)
175+
return false; // Not allowed
176+
177+
use_mclk = enabled;
178+
#endif
179+
return true;
180+
}
181+
150182
bool AudioOutputI2S::begin(bool txDAC)
151183
{
152184
#ifdef ESP32
@@ -219,9 +251,9 @@ bool AudioOutputI2S::begin(bool txDAC)
219251
.dma_buf_len = 128,
220252
.use_apll = use_apll, // Use audio PLL
221253
.tx_desc_auto_clear = true, // Silence on underflow
222-
.fixed_mclk = 0, // Unused
254+
.fixed_mclk = use_mclk, // Unused
223255
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
224-
.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT, // Unused
256+
.mclk_multiple = I2S_MCLK_MULTIPLE_256, // Unused
225257
.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT // Use bits per sample
226258
#endif
227259
};

src/AudioOutputI2S.h

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class AudioOutputI2S : public AudioOutput
3838
AudioOutputI2S(long sampleRate = 44100, pin_size_t sck = 26, pin_size_t data = 28);
3939
#endif
4040
bool SetPinout(int bclkPin, int wclkPin, int doutPin);
41+
bool SetPinout(int bclkPin, int wclkPin, int doutPin, int mclkPin);
4142
virtual ~AudioOutputI2S() override;
4243
virtual bool SetRate(int hz) override;
4344
virtual bool SetBitsPerSample(int bits) override;
@@ -50,6 +51,7 @@ class AudioOutputI2S : public AudioOutput
5051
bool begin(bool txDAC);
5152
bool SetOutputModeMono(bool mono); // Force mono output no matter the input
5253
bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211
54+
bool SetMclk(bool enabled); // Enable MCLK output (if supported)
5355

5456
protected:
5557
bool SetPinout();
@@ -61,13 +63,15 @@ class AudioOutputI2S : public AudioOutput
6163
bool i2sOn;
6264
int dma_buf_count;
6365
int use_apll;
66+
bool use_mclk;
6467
// We can restore the old values and free up these pins when in NoDAC mode
6568
uint32_t orig_bck;
6669
uint32_t orig_ws;
6770

6871
uint8_t bclkPin;
6972
uint8_t wclkPin;
7073
uint8_t doutPin;
74+
uint8_t mclkPin;
7175

7276
#if defined(ARDUINO_ARCH_RP2040)
7377
I2S i2s;

0 commit comments

Comments
 (0)