#pragma once #include "esphome/components/i2c/i2c.h" #include "esphome/core/component.h" #include namespace esphome::sy6970 { // SY6970 Register addresses with descriptive names static const uint8_t SY6970_REG_INPUT_CURRENT_LIMIT = 0x00; // Input current limit control static const uint8_t SY6970_REG_VINDPM = 0x01; // Input voltage limit static const uint8_t SY6970_REG_ADC_CONTROL = 0x02; // ADC control and function disable static const uint8_t SY6970_REG_SYS_CONTROL = 0x03; // Charge enable and system config static const uint8_t SY6970_REG_CHARGE_CURRENT = 0x04; // Fast charge current limit static const uint8_t SY6970_REG_PRECHARGE_CURRENT = 0x05; // Pre-charge/termination current static const uint8_t SY6970_REG_CHARGE_VOLTAGE = 0x06; // Charge voltage limit static const uint8_t SY6970_REG_TIMER_CONTROL = 0x07; // Charge timer and status LED control static const uint8_t SY6970_REG_IR_COMP = 0x08; // IR compensation static const uint8_t SY6970_REG_FORCE_DPDM = 0x09; // Force DPDM detection static const uint8_t SY6970_REG_BOOST_CONTROL = 0x0A; // Boost mode voltage/current static const uint8_t SY6970_REG_STATUS = 0x0B; // System status (bus, charge status) static const uint8_t SY6970_REG_FAULT = 0x0C; // Fault status (NTC) static const uint8_t SY6970_REG_VINDPM_STATUS = 0x0D; // Input voltage limit status (also sys voltage) static const uint8_t SY6970_REG_BATV = 0x0E; // Battery voltage static const uint8_t SY6970_REG_VBUS_VOLTAGE = 0x11; // VBUS voltage static const uint8_t SY6970_REG_CHARGE_CURRENT_MONITOR = 0x12; // Charge current static const uint8_t SY6970_REG_INPUT_VOLTAGE_LIMIT = 0x13; // Input voltage limit static const uint8_t SY6970_REG_DEVICE_ID = 0x14; // Part information // Constants for voltage and current calculations static const uint16_t VBUS_BASE_MV = 2600; // mV static const uint16_t VBUS_STEP_MV = 100; // mV static const uint16_t VBAT_BASE_MV = 2304; // mV static const uint16_t VBAT_STEP_MV = 20; // mV static const uint16_t VSYS_BASE_MV = 2304; // mV static const uint16_t VSYS_STEP_MV = 20; // mV static const uint16_t CHG_CURRENT_STEP_MA = 50; // mA static const uint16_t PRE_CHG_BASE_MA = 64; // mA static const uint16_t PRE_CHG_STEP_MA = 64; // mA static const uint16_t CHG_VOLTAGE_BASE = 3840; // mV static const uint16_t CHG_VOLTAGE_STEP = 16; // mV static const uint16_t INPUT_CURRENT_MIN = 100; // mA static const uint16_t INPUT_CURRENT_STEP = 50; // mA // Bus Status values (REG_0B[7:5]) enum BusStatus { BUS_STATUS_NO_INPUT = 0, BUS_STATUS_USB_SDP = 1, BUS_STATUS_USB_CDP = 2, BUS_STATUS_USB_DCP = 3, BUS_STATUS_HVDCP = 4, BUS_STATUS_ADAPTER = 5, BUS_STATUS_NO_STD_ADAPTER = 6, BUS_STATUS_OTG = 7, }; // Charge Status values (REG_0B[4:3]) enum ChargeStatus { CHARGE_STATUS_NOT_CHARGING = 0, CHARGE_STATUS_PRE_CHARGE = 1, CHARGE_STATUS_FAST_CHARGE = 2, CHARGE_STATUS_CHARGE_DONE = 3, }; // Structure to hold all register data read in one transaction struct SY6970Data { uint8_t registers[21]; // Registers 0x00-0x14 (includes unused 0x0F, 0x10) }; // Listener interface for components that want to receive SY6970 data updates class SY6970Listener { public: virtual void on_data(const SY6970Data &data) = 0; }; class SY6970Component : public PollingComponent, public i2c::I2CDevice { public: SY6970Component(bool led_enabled, uint16_t input_current_limit, uint16_t charge_voltage, uint16_t charge_current, uint16_t precharge_current, bool charge_enabled, bool enable_adc) : led_enabled_(led_enabled), input_current_limit_(input_current_limit), charge_voltage_(charge_voltage), charge_current_(charge_current), precharge_current_(precharge_current), charge_enabled_(charge_enabled), enable_adc_(enable_adc) {} void setup() override; void dump_config() override; void update() override; // Listener registration void add_listener(SY6970Listener *listener) { this->listeners_.push_back(listener); } // Configuration methods to be called from lambdas void set_input_current_limit(uint16_t milliamps); void set_charge_target_voltage(uint16_t millivolts); void set_precharge_current(uint16_t milliamps); void set_charge_current(uint16_t milliamps); void set_charge_enabled(bool enabled); void set_led_enabled(bool enabled); void set_enable_adc_measure(bool enabled = true); protected: bool read_all_registers_(); bool write_register_(uint8_t reg, uint8_t value); bool update_register_(uint8_t reg, uint8_t mask, uint8_t value); SY6970Data data_{}; std::vector listeners_; // Configuration values to set during setup() bool led_enabled_; uint16_t input_current_limit_; uint16_t charge_voltage_; uint16_t charge_current_; uint16_t precharge_current_; bool charge_enabled_; bool enable_adc_; }; } // namespace esphome::sy6970