diff --git a/Devices/es3c28p/Source/Configuration.cpp b/Devices/es3c28p/Source/Configuration.cpp index 4e2a7e2c..7ac0884f 100644 --- a/Devices/es3c28p/Source/Configuration.cpp +++ b/Devices/es3c28p/Source/Configuration.cpp @@ -2,12 +2,95 @@ #include "devices/Display.h" #include +#include +#include +#include +#include +#include + #include using namespace tt::hal; +static constexpr auto* TAG = "ES3C28P"; +static constexpr uint8_t ES8311_I2C_ADDR = 0x18; + +static error_t initSound(::Device* i2c_controller) { + static constexpr uint8_t ENABLED_BULK_DATA[] = { + 0x00, 0x80, // RESET/CSM POWER ON + 0x01, 0x3F, // CLOCK_MANAGER/ use MCLK pin (external), all clocks on + 0x02, 0x00, // CLOCK_MANAGER/ pre_div=1 pre_multi=1 (256x MCLK is correct ratio) + 0x0D, 0x01, // SYSTEM/ Power up analog circuitry + 0x12, 0x00, // SYSTEM/ power-up DAC + 0x13, 0x10, // SYSTEM/ Enable output to HP drive + 0x32, 0xBF, // DAC/ DAC volume (0xBF == ±0 dB) + 0x37, 0x08, // DAC/ Bypass DAC equalizer + }; + + return i2c_controller_write_register_array( + i2c_controller, + ES8311_I2C_ADDR, + ENABLED_BULK_DATA, + sizeof(ENABLED_BULK_DATA), + pdMS_TO_TICKS(1000) + ); +} + +static error_t initMicrophone(::Device* i2c_controller) { + static constexpr uint8_t ENABLED_BULK_DATA[] = { + 0x00, 0x80, // RESET/CSM POWER ON + 0x01, 0x3F, // CLOCK_MANAGER/ use MCLK pin (external), all clocks on + 0x02, 0x00, // CLOCK_MANAGER/ pre_div=1 pre_multi=1 + 0x0D, 0x01, // SYSTEM/ Power up analog circuitry + 0x0E, 0x02, // SYSTEM/ Enable analog PGA, enable ADC modulator + 0x14, 0x10, // ADC_REG14: select Mic1p-Mic1n / PGA GAIN (minimum) + 0x17, 0xFF, // ADC_REG17: ADC_VOLUME (MAXGAIN) + 0x1C, 0x6A, // ADC_REG1C: ADC Equalizer bypass, cancel DC offset + }; + + return i2c_controller_write_register_array( + i2c_controller, + ES8311_I2C_ADDR, + ENABLED_BULK_DATA, + sizeof(ENABLED_BULK_DATA), + pdMS_TO_TICKS(1000) + ); +} + static bool initBoot() { - return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT); + // 1. Initialize display backlight + if (!driver::pwmbacklight::init(LCD_PIN_BACKLIGHT)) { + return false; + } + + // 2. Initialize and power on the FM8002E Audio Amplifier (GPIO 1, Active LOW) + gpio_config_t io_conf = {}; + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = (1ULL << GPIO_NUM_1); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + gpio_config(&io_conf); + + // Drive LOW to enable the speaker amplifier + gpio_set_level(GPIO_NUM_1, 0); + + // 3. Configure the ES8311 Codec over the I2C bus + auto* i2c_bus = device_find_by_name("i2c0"); + if (i2c_bus != nullptr) { + error_t error = initSound(i2c_bus); + if (error != ERROR_NONE) { + LOG_E(TAG, "Failed to enable ES8311 speaker: %s", error_to_string(error)); + } + error = initMicrophone(i2c_bus); + if (error != ERROR_NONE) { + LOG_E(TAG, "Failed to enable ES8311 microphone: %s", error_to_string(error)); + } + } else { + LOG_E(TAG, "i2c0 bus not found, skipping ES8311 initialization"); + } + + return true; } static DeviceVector createDevices() { diff --git a/Devices/es3c28p/es3c28p.dts b/Devices/es3c28p/es3c28p.dts index 2a87f25b..6b17a49e 100644 --- a/Devices/es3c28p/es3c28p.dts +++ b/Devices/es3c28p/es3c28p.dts @@ -6,6 +6,7 @@ #include #include #include +#include / { compatible = "root"; @@ -28,6 +29,16 @@ pin-scl = <&gpio0 15 GPIO_FLAG_NONE>; }; + i2s0 { + compatible = "espressif,esp32-i2s"; + port = ; + pin-bclk = <&gpio0 5 GPIO_FLAG_NONE>; + pin-ws = <&gpio0 7 GPIO_FLAG_NONE>; + pin-data-out = <&gpio0 6 GPIO_FLAG_NONE>; + pin-data-in = <&gpio0 8 GPIO_FLAG_NONE>; + pin-mclk = <&gpio0 4 GPIO_FLAG_NONE>; + }; + display_spi: spi0 { compatible = "espressif,esp32-spi"; host = ; diff --git a/Tactility/Source/app/AppInstall.cpp b/Tactility/Source/app/AppInstall.cpp index 4e4402e8..b3f09378 100644 --- a/Tactility/Source/app/AppInstall.cpp +++ b/Tactility/Source/app/AppInstall.cpp @@ -36,9 +36,7 @@ static bool untarFile(minitar* mp, const minitar_entry* entry, const std::string } // Note: fchmod() doesn't exist on ESP-IDF and chmod() does nothing on that platform - if (chmod(absolute_path.c_str(), entry->metadata.mode) < 0) { - return false; - } + chmod(absolute_path.c_str(), entry->metadata.mode); return true; }