Skip to content

Commit 21af213

Browse files
authored
Merge pull request #9 from uutzinger/main
ES8388 debug and AudioTools Example
2 parents f6ec09e + 51e2741 commit 21af213

File tree

7 files changed

+121
-33
lines changed

7 files changed

+121
-33
lines changed

examples/audiotools/audiotools-custom-max/audiotools-custom-max.ino

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,58 @@
77
#include "AudioTools.h" // install https://github.com/pschatzmann/arduino-audio-tools
88
#include "AudioLibs/I2SCodecStream.h"
99

10-
AudioInfo info(44100, 2, 16);
11-
SineWaveGenerator<int16_t> sineWave(32000);
12-
GeneratedSoundStream<int16_t> sound(sineWave);
13-
DriverPins my_pins;
14-
AudioBoard board(AudioDriverES8388, my_pins);
15-
I2SCodecStream out(board);
16-
StreamCopy copier(out, sound);
10+
// I2C
11+
#define SDAPIN 3 // I2C Data, Adafruit ESP32 S3 3, Sparkfun Thing Plus C 23
12+
#define SCLPIN 4 // I2C Clock, Adafruit ESP32 S3 4, Sparkfun Thing Plus C 22
13+
#define I2CSPEED 100000 // Clock Rate
14+
#define ES8388ADDR 0x10 // Address of ES8388 I2C port
15+
16+
// I2S, your configuration for the ES8388 board
17+
#define MCLKPIN 14 // Master Clock
18+
#define BCLKPIN 36 // Bit Clock
19+
#define WSPIN 8 // Word select
20+
#define DOPIN 37 // This is connected to DI on ES8388 (MISO)
21+
#define DIPIN 35 // This is connected to DO on ES8388 (MOSI)
22+
23+
AudioInfo audio_info(44200, 2, 16); // sampling rate, # channels, bit depth
24+
SineWaveGenerator<int16_t> sine_wave(32000); // amplitude
25+
GeneratedSoundStream<int16_t> sound_stream(sine_wave); // sound generator
26+
DriverPins my_pins; // board pins
27+
AudioBoard audio_board(AudioDriverES8388, my_pins); // audio board
28+
I2SCodecStream i2s_out_stream(audio_board); // i2s coded
29+
StreamCopy copier(i2s_out_stream, sound_stream); // stream copy sound generator to i2s codec
30+
TwoWire myWire = TwoWire(0); // universal I2C interface
1731

1832
void setup() {
1933
// Setup logging
2034
Serial.begin(115200);
2135
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
2236
LOGLEVEL_AUDIODRIVER = AudioDriverWarning;
37+
delay(2000);
38+
39+
Serial.println("Setup starting...");
2340

24-
// setup pins
25-
// - add i2c codec pins: scl, sda, port, (I2C object)
26-
my_pins.addI2C(PinFunction::CODEC, 32, 22, 0x20, 100000, Wire);
27-
// - add i2s pins: mclk, bclk, ws, data_out, data_in
28-
my_pins.addI2S(PinFunction::CODEC, 0, 14, 15, 22);
41+
Serial.println("I2C pin ...");
42+
my_pins.addI2C(PinFunction::CODEC, SCLPIN, SDAPIN, ES8388ADDR, I2CSPEED, myWire);
43+
Serial.println("I2S pin ...");
44+
my_pins.addI2S(PinFunction::CODEC, MCLKPIN, BCLKPIN, WSPIN, DOPIN, DIPIN);
2945

30-
31-
// start I2S & codec with i2c and i2s configured above
32-
Serial.println("starting I2S...");
33-
auto config = out.defaultConfig();
34-
config.copyFrom(info);
35-
out.begin(config);
46+
Serial.println("Pins begin ...");
47+
my_pins.begin();
48+
49+
Serial.println("Board begin ...");
50+
audio_board.begin();
51+
52+
Serial.println("I2S begin ...");
53+
auto i2s_config = i2s_out_stream.defaultConfig();
54+
i2s_config.copyFrom(audio_info);
55+
i2s_out_stream.begin(i2s_config); // this should apply I2C and I2S configuration
3656

3757
// Setup sine wave
38-
sineWave.begin(info, N_B4);
58+
Serial.println("Sine wave begin...");
59+
sine_wave.begin(audio_info, N_B4); // 493.88 Hz
60+
61+
Serial.println("Setup completed ...");
3962
}
4063

4164
// Arduino loop - copy sound to out

src/AudioBoard.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ class AudioBoard {
2323
}
2424

2525
bool begin(){
26-
AD_LOGD("AudioBoard::begin");
27-
bool result = pins.begin() && driver->begin(codec_cfg, pins);
26+
AD_LOGD("AudioBoard::pins::begin");
27+
bool result_pins = pins.begin();
28+
AD_LOGD("AudioBoard::pins::begin::returned:%s", result_pins ? "true" : "false");
29+
AD_LOGD("AudioBoard::driver::begin");
30+
bool result_driver = driver->begin(codec_cfg, pins);
31+
AD_LOGD("AudioBoard::driver::begin::returned:%s", result_driver ? "true" : "false");
2832
setVolume(DRIVER_DEFAULT_VOLUME);
29-
return result;
33+
AD_LOGD("AudioBoard::volume::set");
34+
return result_pins && result_driver;
3035
}
3136

3237
/// Starts the processing

src/Driver.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const samplerate_t rate_code[8] = {RATE_8K, RATE_11K, RATE_16K, RATE_22K,
2323
RATE_24K, RATE_32K, RATE_44K, RATE_48K};
2424

2525
/**
26-
* @brief I2S configuration and defition of input and output with default values
26+
* @brief I2S configuration and definition of input and output with default values
2727
* @ingroup audio_driver
2828
* @author Phil Schatzmann
2929
* @copyright GPLv3
@@ -157,28 +157,38 @@ class CodecConfig : public codec_config_t {
157157
class AudioDriver {
158158
public:
159159
virtual bool begin(CodecConfig codecCfg, DriverPins &pins) {
160-
AD_LOGD("AudioDriver::begin");
160+
AD_LOGD("AudioDriver::begin:pins");
161161
p_pins = &pins;
162+
AD_LOGD("AudioDriver::begin:setSPI");
162163
pins.setSPIActiveForSD(codecCfg.sd_active);
164+
AD_LOGD("AudioDriver::begin:setConfig");
163165
int result = setConfig(codecCfg);
166+
AD_LOGD("AudioDriver::begin:setPAPower");
164167
setPAPower(true);
168+
AD_LOGD("AudioDriver::begin:completed");
165169
return result;
166170
}
167171
virtual bool setConfig(CodecConfig codecCfg) {
168172
codec_cfg = codecCfg;
169173
if (!init(codec_cfg)) {
170-
AD_LOGE("init failed");
174+
AD_LOGE("AudioDriver::begin::init failed");
171175
return false;
176+
} else {
177+
AD_LOGD("AudioDriver::begin::init succeeded");
172178
}
173179
codec_mode_t codec_mode = codec_cfg.get_mode();
174180
if (!controlState(codec_mode)) {
175-
AD_LOGE("controlState failed");
181+
AD_LOGE("AudioDriver::begin::controlState failed");
176182
return false;
183+
} else {
184+
AD_LOGD("AudioDriver::begin::controlState succeeded");
177185
}
178186
bool result = configInterface(codec_mode, codec_cfg.i2s);
179187
if (!result) {
180-
AD_LOGE("configInterface failed");
188+
AD_LOGE("AudioDriver::begin::configInterface failed");
181189
return false;
190+
} else {
191+
AD_LOGD("AudioDriver::begin::configInterface succeeded");
182192
}
183193
return result;
184194
}
@@ -196,8 +206,7 @@ class AudioDriver {
196206
/// Sets the PA Power pin to active or inactive
197207
bool setPAPower(bool enable) {
198208
GpioPin pin = pins().getPinID(PinFunction::PA);
199-
if (pin == -1)
200-
return false;
209+
if (pin == -1) { return false; }
201210
AD_LOGI("setPAPower pin %d -> %d", pin, enable);
202211
digitalWrite(pin, enable ? HIGH : LOW);
203212
return true;
@@ -207,7 +216,7 @@ class AudioDriver {
207216
CodecConfig codec_cfg;
208217
DriverPins *p_pins = nullptr;
209218

210-
/// Detemine the TwoWire object from the I2C config or use Wire
219+
/// Determine the TwoWire object from the I2C config or use Wire
211220
TwoWire* getI2C() {
212221
if (p_pins == nullptr) return &Wire;
213222
auto i2c = pins().getI2CPins(PinFunction::CODEC);
@@ -724,7 +733,7 @@ class AudioDriverWM8960Class : public AudioDriver {
724733
/// Configuration: define retry count (default : 0)
725734
void setI2CRetryCount(int cnt) { i2c_retry_count = cnt; }
726735

727-
/// Configuration: enable/diable PLL (active by default)
736+
/// Configuration: enable/disable PLL (active by default)
728737
void setEnablePLL(bool active) { vs1053_enable_pll = active; }
729738

730739
/// Configuration: define master clock frequency (default: 0)
@@ -853,7 +862,7 @@ class AudioDriverWM8994Class : public AudioDriver {
853862

854863
virtual bool begin(CodecConfig codecCfg, DriverPins &pins) {
855864
codec_cfg = codecCfg;
856-
// manage reset pin -> acive high
865+
// manage reset pin -> active high
857866
setPAPower(true);
858867
delay(10);
859868
p_pins = &pins;

src/Driver/es8388/es8388.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ error_t es8388_stop(codec_mode_t mode)
183183

184184

185185
/**
186-
* @brief Config I2s clock in MSATER mode
186+
* @brief Config I2s clock in MASTER mode
187187
*
188188
* @param cfg.sclkDiv: generate SCLK by dividing MCLK in MSATER mode
189189
* @param cfg.lclkDiv: generate LCLK by dividing MCLK in MSATER mode
@@ -225,6 +225,16 @@ error_t es8388_init(codec_config_t *cfg, i2c_bus_handle_t handle)
225225
i2c_handle = handle;
226226

227227
int res = 0;
228+
229+
// Here check if ES8388 is responding on the I2C bus
230+
res = i2c_bus_check(handle, ES8388_ADDR);
231+
if (res != 0) {
232+
AD_LOGE("ES8388 not found on I2C bus, check wiring");
233+
return res;
234+
} else {
235+
AD_LOGI("Found ES8388");
236+
}
237+
228238
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
229239
headphone_detect_init(get_headphone_detect_gpio());
230240
#endif

src/DriverPins.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ struct PinsSPI {
128128
p_spi->begin();
129129
#endif
130130
}
131+
} else {
132+
AD_LOGI("SPI, not active, MOSI, MISO, SCLK, SSEL not modified");
131133
}
132134
return true;
133135
}
@@ -190,6 +192,8 @@ struct PinsI2C {
190192
}
191193
AD_LOGI("Setting i2c clock: %u", frequency);
192194
p_wire->setClock(frequency);
195+
} else {
196+
AD_LOGI("I2C, not active, SDA, SCL, i2c clock not modified");
193197
}
194198
return true;
195199
}
@@ -315,11 +319,14 @@ class DriverPins {
315319
AD_LOGD("DriverPins::begin");
316320

317321
// setup function pins
322+
AD_LOGD("DriverPins::begin::setupPinMode");
318323
setupPinMode();
319324

320325
// setup spi
326+
AD_LOGD("DriverPins::begin::SPI");
321327
bool result = true;
322328
for (auto &tmp : spi) {
329+
AD_LOGD("DriverPins::begin::SPI::begin");
323330
if (tmp.function == PinFunction::SD)
324331
if (sd_active)
325332
result &= tmp.begin();
@@ -328,7 +335,9 @@ class DriverPins {
328335
}
329336

330337
// setup i2c
338+
AD_LOGD("DriverPins::begin::I2C");
331339
for (auto &tmp : i2c) {
340+
AD_LOGD("DriverPins::begin::I2C::begin");
332341
result &= tmp.begin();
333342
}
334343
return result;
@@ -337,10 +346,12 @@ class DriverPins {
337346
void end() {
338347
// setup spi
339348
for (auto &tmp : spi) {
349+
AD_LOGD("DriverPins::begin::SPI::end");
340350
tmp.end();
341351
}
342352
// setup i2c
343353
for (auto &tmp : i2c) {
354+
AD_LOGD("DriverPins::begin::I2C::end");
344355
tmp.end();
345356
}
346357
}
@@ -388,7 +399,10 @@ class DriverPins {
388399
AD_LOGW("Pin '%d' not set up because of conflict", tmp.pin);
389400
tmp.active = false;
390401
}
402+
} else {
403+
AD_LOGD("Pin is -1");
391404
}
405+
AD_LOGD("Pin %d set", tmp.pin);
392406
}
393407
}
394408

src/Utils/I2C.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ error_t i2c_bus_write_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg,
2929
return result;
3030
}
3131

32+
// this method is used !
33+
error_t i2c_bus_check(i2c_bus_handle_t bus, int addr) {
34+
AD_LOGD("i2c_bus_check: addr=0x%X",addr);
35+
TwoWire *p_wire = (TwoWire *)bus;
36+
assert(p_wire!=nullptr);
37+
int result = RESULT_OK;
38+
p_wire->beginTransmission(addr);
39+
int rc = p_wire->endTransmission(I2C_END);
40+
if (rc != 0) {
41+
AD_LOGE("->p_wire->endTransmission: %d", rc);
42+
result = RESULT_FAIL;
43+
}
44+
return result;
45+
}
46+
3247

3348
/// This method is used
3449
error_t i2c_bus_read_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg,

src/Utils/I2C.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ extern "C" {
2424
*/
2525
error_t i2c_bus_write_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg, int regLen, uint8_t *data, int datalen);
2626

27+
/**
28+
* @brief Requests ACK from I2C device
29+
*
30+
* @param bus I2C bus handle
31+
* @param addr The address of the device
32+
*
33+
* @return
34+
* - NULL Fail
35+
* - Others Success
36+
*/
37+
error_t i2c_bus_check(i2c_bus_handle_t bus, int addr);
38+
2739

2840
/**
2941
* @brief Read bytes to I2C bus

0 commit comments

Comments
 (0)