#include "PwmBacklight.h" #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() { // 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() { return { createDisplay() }; } extern const Configuration hardwareConfiguration = { .initBoot = initBoot, .createDevices = createDevices };