#include "PwmBacklight.h" #include "devices/Display.h" #include "devices/Power.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 initCodec(::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) 0x03, 0x10, // CLOCK_MANAGER/ fs_mode=0, adc_osr=16 0x04, 0x10, // CLOCK_MANAGER/ dac_osr=16 0x05, 0x00, // CLOCK_MANAGER/ adc_div=1, dac_div=1 0x06, 0x03, // CLOCK_MANAGER/ bclk_div=4 0x07, 0x00, // CLOCK_MANAGER/ lrck_h=0 0x08, 0xFF, // CLOCK_MANAGER/ lrck_l=255 (div=256) 0x09, 0x0C, // SDPIN_REG09/ DAC SDP format = standard I2S, word length = 16-bit 0x0A, 0x0C, // SDPOUT_REG0A/ ADC SDP format = standard I2S, word length = 16-bit 0x0D, 0x01, // SYSTEM/ Power up analog circuitry 0x0E, 0x02, // SYSTEM/ Enable analog PGA, enable ADC modulator 0x12, 0x00, // SYSTEM/ power-up DAC 0x13, 0x10, // SYSTEM/ Enable output to HP drive (headphone/speaker) 0x14, 0x1A, // SYSTEM/ Select Mic1p-Mic1n / max PGA gain (+30dB) 0x17, 0xFF, // ADC_REG17/ ADC Volume (MAXGAIN) 0x1C, 0x6A, // ADC_REG1C/ ADC Equalizer bypass, cancel DC offset in digital 0x32, 0xBF, // DAC_REG32/ DAC Volume (0xBF = 191) 0x37, 0x08, // DAC_REG37/ 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 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 = initCodec(i2c_bus); if (error != ERROR_NONE) { LOG_E(TAG, "Failed to initialize ES8311 codec: %s", error_to_string(error)); } } else { LOG_E(TAG, "i2c0 bus not found, skipping ES8311 initialization"); } return true; } static DeviceVector createDevices() { return { createDisplay(), createPower() }; } extern const Configuration hardwareConfiguration = { .initBoot = initBoot, .createDevices = createDevices };