ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
sy6970.cpp
Go to the documentation of this file.
1#include "sy6970.h"
2#include "esphome/core/hal.h"
3#include "esphome/core/log.h"
4
5namespace esphome::sy6970 {
6
7static const char *const TAG = "sy6970";
8
10 // Read all registers from 0x00 to 0x14 in one transaction (21 bytes)
11 // This includes unused registers 0x0F, 0x10 for performance
12 if (!this->read_bytes(SY6970_REG_INPUT_CURRENT_LIMIT, this->data_.registers, 21)) {
13 ESP_LOGW(TAG, "Failed to read registers 0x00-0x14");
14 return false;
15 }
16
17 return true;
18}
19
20bool SY6970Component::write_register_(uint8_t reg, uint8_t value) {
21 if (!this->write_byte(reg, value)) {
22 ESP_LOGW(TAG, "Failed to write register 0x%02X", reg);
23 return false;
24 }
25 return true;
26}
27
28bool SY6970Component::update_register_(uint8_t reg, uint8_t mask, uint8_t value) {
29 uint8_t reg_value;
30 if (!this->read_byte(reg, &reg_value)) {
31 ESP_LOGW(TAG, "Failed to read register 0x%02X for update", reg);
32 return false;
33 }
34 reg_value = (reg_value & ~mask) | (value & mask);
35 return this->write_register_(reg, reg_value);
36}
37
39 ESP_LOGV(TAG, "Setting up SY6970...");
40
41 // Try to read chip ID
42 uint8_t reg_value;
43 if (!this->read_byte(SY6970_REG_DEVICE_ID, &reg_value)) {
44 ESP_LOGE(TAG, "Failed to communicate with SY6970");
45 this->mark_failed();
46 return;
47 }
48
49 uint8_t chip_id = reg_value & 0x03;
50 if (chip_id != 0x00) {
51 ESP_LOGW(TAG, "Unexpected chip ID: 0x%02X (expected 0x00)", chip_id);
52 }
53
54 // Apply configuration options (all have defaults now)
55 ESP_LOGV(TAG, "Setting LED enabled to %s", ONOFF(this->led_enabled_));
56 this->set_led_enabled(this->led_enabled_);
57
58 ESP_LOGV(TAG, "Setting input current limit to %u mA", this->input_current_limit_);
60
61 ESP_LOGV(TAG, "Setting charge voltage to %u mV", this->charge_voltage_);
63
64 ESP_LOGV(TAG, "Setting charge current to %u mA", this->charge_current_);
66
67 ESP_LOGV(TAG, "Setting precharge current to %u mA", this->precharge_current_);
69
70 ESP_LOGV(TAG, "Setting charge enabled to %s", ONOFF(this->charge_enabled_));
72
73 ESP_LOGV(TAG, "Setting ADC measurements to %s", ONOFF(this->enable_adc_));
75
76 ESP_LOGV(TAG, "SY6970 initialized successfully");
77}
78
80 ESP_LOGCONFIG(TAG,
81 "SY6970:\n"
82 " LED Enabled: %s\n"
83 " Input Current Limit: %u mA\n"
84 " Charge Voltage: %u mV\n"
85 " Charge Current: %u mA\n"
86 " Precharge Current: %u mA\n"
87 " Charge Enabled: %s\n"
88 " ADC Enabled: %s",
89 ONOFF(this->led_enabled_), this->input_current_limit_, this->charge_voltage_, this->charge_current_,
90 this->precharge_current_, ONOFF(this->charge_enabled_), ONOFF(this->enable_adc_));
91 LOG_I2C_DEVICE(this);
92 LOG_UPDATE_INTERVAL(this);
93 if (this->is_failed()) {
94 ESP_LOGE(TAG, "Communication with SY6970 failed!");
95 }
96}
97
99 if (this->is_failed()) {
100 return;
101 }
102
103 // Read all registers in one transaction
104 if (!this->read_all_registers_()) {
105 ESP_LOGW(TAG, "Failed to read registers during update");
106 this->status_set_warning();
107 return;
108 }
109
110 this->status_clear_warning();
111
112 // Notify all listeners with the new data
113 for (auto *listener : this->listeners_) {
114 listener->on_data(this->data_);
115 }
116}
117
119 if (this->is_failed())
120 return;
121
122 if (milliamps < INPUT_CURRENT_MIN) {
123 milliamps = INPUT_CURRENT_MIN;
124 }
125
126 uint8_t val = (milliamps - INPUT_CURRENT_MIN) / INPUT_CURRENT_STEP;
127 if (val > 0x3F) {
128 val = 0x3F;
129 }
130
131 this->update_register_(SY6970_REG_INPUT_CURRENT_LIMIT, 0x3F, val);
132}
133
135 if (this->is_failed())
136 return;
137
138 if (millivolts < CHG_VOLTAGE_BASE) {
139 millivolts = CHG_VOLTAGE_BASE;
140 }
141
142 uint8_t val = (millivolts - CHG_VOLTAGE_BASE) / CHG_VOLTAGE_STEP;
143 if (val > 0x3F) {
144 val = 0x3F;
145 }
146
147 this->update_register_(SY6970_REG_CHARGE_VOLTAGE, 0xFC, val << 2);
148}
149
151 if (this->is_failed())
152 return;
153
154 if (milliamps < PRE_CHG_BASE_MA) {
155 milliamps = PRE_CHG_BASE_MA;
156 }
157
158 uint8_t val = (milliamps - PRE_CHG_BASE_MA) / PRE_CHG_STEP_MA;
159 if (val > 0x0F) {
160 val = 0x0F;
161 }
162
163 this->update_register_(SY6970_REG_PRECHARGE_CURRENT, 0xF0, val << 4);
164}
165
166void SY6970Component::set_charge_current(uint16_t milliamps) {
167 if (this->is_failed())
168 return;
169
170 uint8_t val = milliamps / 64;
171 if (val > 0x7F) {
172 val = 0x7F;
173 }
174
175 this->update_register_(SY6970_REG_CHARGE_CURRENT, 0x7F, val);
176}
177
179 if (this->is_failed())
180 return;
181
182 this->update_register_(SY6970_REG_SYS_CONTROL, 0x10, enabled ? 0x10 : 0x00);
183}
184
186 if (this->is_failed())
187 return;
188
189 // Bit 6: 0 = LED enabled, 1 = LED disabled
190 this->update_register_(SY6970_REG_TIMER_CONTROL, 0x40, enabled ? 0x00 : 0x40);
191}
192
194 if (this->is_failed())
195 return;
196
197 // Set bits to enable ADC conversion
198 this->update_register_(SY6970_REG_ADC_CONTROL, 0xC0, enabled ? 0xC0 : 0x00);
199}
200
201} // namespace esphome::sy6970
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:266
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:241
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:153
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:218
void set_charge_target_voltage(uint16_t millivolts)
Definition sy6970.cpp:134
void set_enable_adc_measure(bool enabled=true)
Definition sy6970.cpp:193
void set_input_current_limit(uint16_t milliamps)
Definition sy6970.cpp:118
void set_charge_enabled(bool enabled)
Definition sy6970.cpp:178
void set_precharge_current(uint16_t milliamps)
Definition sy6970.cpp:150
bool write_register_(uint8_t reg, uint8_t value)
Definition sy6970.cpp:20
void set_led_enabled(bool enabled)
Definition sy6970.cpp:185
void set_charge_current(uint16_t milliamps)
Definition sy6970.cpp:166
std::vector< SY6970Listener * > listeners_
Definition sy6970.h:109
bool update_register_(uint8_t reg, uint8_t mask, uint8_t value)
Definition sy6970.cpp:28
mopeka_std_values val[4]
const char *const TAG
Definition spi.cpp:7