1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00
Files
esphome/esphome/components/sy6970/sy6970.h
2026-01-25 08:31:26 +11:00

123 lines
5.1 KiB
C++

#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#include <vector>
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;
float get_setup_priority() const override { return setup_priority::DATA; }
// 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<SY6970Listener *> 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