Skip to content

Commit

Permalink
Merge pull request #9 from uutzinger/main
Browse files Browse the repository at this point in the history
ES8388 debug and AudioTools Example
  • Loading branch information
pschatzmann authored Feb 26, 2024
2 parents f6ec09e + 51e2741 commit 21af213
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 33 deletions.
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

0 comments on commit 21af213

Please sign in to comment.