Skip to content

ES8388 debug and AudioTools Example #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions examples/audiotools/audiotools-custom-max/audiotools-custom-max.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,58 @@
#include "AudioTools.h" // install https://github.com/pschatzmann/arduino-audio-tools
#include "AudioLibs/I2SCodecStream.h"

AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave(32000);
GeneratedSoundStream<int16_t> sound(sineWave);
DriverPins my_pins;
AudioBoard board(AudioDriverES8388, my_pins);
I2SCodecStream out(board);
StreamCopy copier(out, sound);
// I2C
#define SDAPIN 3 // I2C Data, Adafruit ESP32 S3 3, Sparkfun Thing Plus C 23
#define SCLPIN 4 // I2C Clock, Adafruit ESP32 S3 4, Sparkfun Thing Plus C 22
#define I2CSPEED 100000 // Clock Rate
#define ES8388ADDR 0x10 // Address of ES8388 I2C port

// I2S, your configuration for the ES8388 board
#define MCLKPIN 14 // Master Clock
#define BCLKPIN 36 // Bit Clock
#define WSPIN 8 // Word select
#define DOPIN 37 // This is connected to DI on ES8388 (MISO)
#define DIPIN 35 // This is connected to DO on ES8388 (MOSI)

AudioInfo audio_info(44200, 2, 16); // sampling rate, # channels, bit depth
SineWaveGenerator<int16_t> sine_wave(32000); // amplitude
GeneratedSoundStream<int16_t> sound_stream(sine_wave); // sound generator
DriverPins my_pins; // board pins
AudioBoard audio_board(AudioDriverES8388, my_pins); // audio board
I2SCodecStream i2s_out_stream(audio_board); // i2s coded
StreamCopy copier(i2s_out_stream, sound_stream); // stream copy sound generator to i2s codec
TwoWire myWire = TwoWire(0); // universal I2C interface

void setup() {
// Setup logging
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
LOGLEVEL_AUDIODRIVER = AudioDriverWarning;
delay(2000);

Serial.println("Setup starting...");

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


// start I2S & codec with i2c and i2s configured above
Serial.println("starting I2S...");
auto config = out.defaultConfig();
config.copyFrom(info);
out.begin(config);
Serial.println("Pins begin ...");
my_pins.begin();

Serial.println("Board begin ...");
audio_board.begin();

Serial.println("I2S begin ...");
auto i2s_config = i2s_out_stream.defaultConfig();
i2s_config.copyFrom(audio_info);
i2s_out_stream.begin(i2s_config); // this should apply I2C and I2S configuration

// Setup sine wave
sineWave.begin(info, N_B4);
Serial.println("Sine wave begin...");
sine_wave.begin(audio_info, N_B4); // 493.88 Hz

Serial.println("Setup completed ...");
}

// Arduino loop - copy sound to out
Expand Down
11 changes: 8 additions & 3 deletions src/AudioBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ class AudioBoard {
}

bool begin(){
AD_LOGD("AudioBoard::begin");
bool result = pins.begin() && driver->begin(codec_cfg, pins);
AD_LOGD("AudioBoard::pins::begin");
bool result_pins = pins.begin();
AD_LOGD("AudioBoard::pins::begin::returned:%s", result_pins ? "true" : "false");
AD_LOGD("AudioBoard::driver::begin");
bool result_driver = driver->begin(codec_cfg, pins);
AD_LOGD("AudioBoard::driver::begin::returned:%s", result_driver ? "true" : "false");
setVolume(DRIVER_DEFAULT_VOLUME);
return result;
AD_LOGD("AudioBoard::volume::set");
return result_pins && result_driver;
}

/// Starts the processing
Expand Down
29 changes: 19 additions & 10 deletions src/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const samplerate_t rate_code[8] = {RATE_8K, RATE_11K, RATE_16K, RATE_22K,
RATE_24K, RATE_32K, RATE_44K, RATE_48K};

/**
* @brief I2S configuration and defition of input and output with default values
* @brief I2S configuration and definition of input and output with default values
* @ingroup audio_driver
* @author Phil Schatzmann
* @copyright GPLv3
Expand Down Expand Up @@ -157,28 +157,38 @@ class CodecConfig : public codec_config_t {
class AudioDriver {
public:
virtual bool begin(CodecConfig codecCfg, DriverPins &pins) {
AD_LOGD("AudioDriver::begin");
AD_LOGD("AudioDriver::begin:pins");
p_pins = &pins;
AD_LOGD("AudioDriver::begin:setSPI");
pins.setSPIActiveForSD(codecCfg.sd_active);
AD_LOGD("AudioDriver::begin:setConfig");
int result = setConfig(codecCfg);
AD_LOGD("AudioDriver::begin:setPAPower");
setPAPower(true);
AD_LOGD("AudioDriver::begin:completed");
return result;
}
virtual bool setConfig(CodecConfig codecCfg) {
codec_cfg = codecCfg;
if (!init(codec_cfg)) {
AD_LOGE("init failed");
AD_LOGE("AudioDriver::begin::init failed");
return false;
} else {
AD_LOGD("AudioDriver::begin::init succeeded");
}
codec_mode_t codec_mode = codec_cfg.get_mode();
if (!controlState(codec_mode)) {
AD_LOGE("controlState failed");
AD_LOGE("AudioDriver::begin::controlState failed");
return false;
} else {
AD_LOGD("AudioDriver::begin::controlState succeeded");
}
bool result = configInterface(codec_mode, codec_cfg.i2s);
if (!result) {
AD_LOGE("configInterface failed");
AD_LOGE("AudioDriver::begin::configInterface failed");
return false;
} else {
AD_LOGD("AudioDriver::begin::configInterface succeeded");
}
return result;
}
Expand All @@ -196,8 +206,7 @@ class AudioDriver {
/// Sets the PA Power pin to active or inactive
bool setPAPower(bool enable) {
GpioPin pin = pins().getPinID(PinFunction::PA);
if (pin == -1)
return false;
if (pin == -1) { return false; }
AD_LOGI("setPAPower pin %d -> %d", pin, enable);
digitalWrite(pin, enable ? HIGH : LOW);
return true;
Expand All @@ -207,7 +216,7 @@ class AudioDriver {
CodecConfig codec_cfg;
DriverPins *p_pins = nullptr;

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

/// Configuration: enable/diable PLL (active by default)
/// Configuration: enable/disable PLL (active by default)
void setEnablePLL(bool active) { vs1053_enable_pll = active; }

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

virtual bool begin(CodecConfig codecCfg, DriverPins &pins) {
codec_cfg = codecCfg;
// manage reset pin -> acive high
// manage reset pin -> active high
setPAPower(true);
delay(10);
p_pins = &pins;
Expand Down
12 changes: 11 additions & 1 deletion src/Driver/es8388/es8388.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ error_t es8388_stop(codec_mode_t mode)


/**
* @brief Config I2s clock in MSATER mode
* @brief Config I2s clock in MASTER mode
*
* @param cfg.sclkDiv: generate SCLK by dividing MCLK in MSATER mode
* @param cfg.lclkDiv: generate LCLK by dividing MCLK in MSATER mode
Expand Down Expand Up @@ -225,6 +225,16 @@ error_t es8388_init(codec_config_t *cfg, i2c_bus_handle_t handle)
i2c_handle = handle;

int res = 0;

// Here check if ES8388 is responding on the I2C bus
res = i2c_bus_check(handle, ES8388_ADDR);
if (res != 0) {
AD_LOGE("ES8388 not found on I2C bus, check wiring");
return res;
} else {
AD_LOGI("Found ES8388");
}

#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
headphone_detect_init(get_headphone_detect_gpio());
#endif
Expand Down
14 changes: 14 additions & 0 deletions src/DriverPins.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ struct PinsSPI {
p_spi->begin();
#endif
}
} else {
AD_LOGI("SPI, not active, MOSI, MISO, SCLK, SSEL not modified");
}
return true;
}
Expand Down Expand Up @@ -190,6 +192,8 @@ struct PinsI2C {
}
AD_LOGI("Setting i2c clock: %u", frequency);
p_wire->setClock(frequency);
} else {
AD_LOGI("I2C, not active, SDA, SCL, i2c clock not modified");
}
return true;
}
Expand Down Expand Up @@ -315,11 +319,14 @@ class DriverPins {
AD_LOGD("DriverPins::begin");

// setup function pins
AD_LOGD("DriverPins::begin::setupPinMode");
setupPinMode();

// setup spi
AD_LOGD("DriverPins::begin::SPI");
bool result = true;
for (auto &tmp : spi) {
AD_LOGD("DriverPins::begin::SPI::begin");
if (tmp.function == PinFunction::SD)
if (sd_active)
result &= tmp.begin();
Expand All @@ -328,7 +335,9 @@ class DriverPins {
}

// setup i2c
AD_LOGD("DriverPins::begin::I2C");
for (auto &tmp : i2c) {
AD_LOGD("DriverPins::begin::I2C::begin");
result &= tmp.begin();
}
return result;
Expand All @@ -337,10 +346,12 @@ class DriverPins {
void end() {
// setup spi
for (auto &tmp : spi) {
AD_LOGD("DriverPins::begin::SPI::end");
tmp.end();
}
// setup i2c
for (auto &tmp : i2c) {
AD_LOGD("DriverPins::begin::I2C::end");
tmp.end();
}
}
Expand Down Expand Up @@ -388,7 +399,10 @@ class DriverPins {
AD_LOGW("Pin '%d' not set up because of conflict", tmp.pin);
tmp.active = false;
}
} else {
AD_LOGD("Pin is -1");
}
AD_LOGD("Pin %d set", tmp.pin);
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/Utils/I2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ error_t i2c_bus_write_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg,
return result;
}

// this method is used !
error_t i2c_bus_check(i2c_bus_handle_t bus, int addr) {
AD_LOGD("i2c_bus_check: addr=0x%X",addr);
TwoWire *p_wire = (TwoWire *)bus;
assert(p_wire!=nullptr);
int result = RESULT_OK;
p_wire->beginTransmission(addr);
int rc = p_wire->endTransmission(I2C_END);
if (rc != 0) {
AD_LOGE("->p_wire->endTransmission: %d", rc);
result = RESULT_FAIL;
}
return result;
}


/// This method is used
error_t i2c_bus_read_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg,
Expand Down
12 changes: 12 additions & 0 deletions src/Utils/I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ extern "C" {
*/
error_t i2c_bus_write_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg, int regLen, uint8_t *data, int datalen);

/**
* @brief Requests ACK from I2C device
*
* @param bus I2C bus handle
* @param addr The address of the device
*
* @return
* - NULL Fail
* - Others Success
*/
error_t i2c_bus_check(i2c_bus_handle_t bus, int addr);


/**
* @brief Read bytes to I2C bus
Expand Down