98 lines
3.1 KiB
C++
98 lines
3.1 KiB
C++
#include "max17043.h"
|
|
#include "esphome/core/log.h"
|
|
|
|
namespace esphome {
|
|
namespace max17043 {
|
|
|
|
// MAX174043 is a 1-Cell Fuel Gauge with ModelGauge and Low-Battery Alert
|
|
// Consult the datasheet at https://www.analog.com/en/products/max17043.html
|
|
|
|
static const char *const TAG = "max17043";
|
|
|
|
static const uint8_t MAX17043_VCELL = 0x02;
|
|
static const uint8_t MAX17043_SOC = 0x04;
|
|
static const uint8_t MAX17043_CONFIG = 0x0c;
|
|
|
|
static const uint16_t MAX17043_CONFIG_POWER_UP_DEFAULT = 0x971C;
|
|
static const uint16_t MAX17043_CONFIG_SAFE_MASK = 0xFF1F; // mask out sleep bit (7), unused bit (6) and alert bit (4)
|
|
static const uint16_t MAX17043_CONFIG_SLEEP_MASK = 0x0080;
|
|
|
|
void MAX17043Component::update() {
|
|
uint16_t raw_voltage, raw_percent;
|
|
|
|
if (this->voltage_sensor_ != nullptr) {
|
|
if (!this->read_byte_16(MAX17043_VCELL, &raw_voltage)) {
|
|
this->status_set_warning("Unable to read MAX17043_VCELL");
|
|
} else {
|
|
float voltage = (1.25 * (float) (raw_voltage >> 4)) / 1000.0;
|
|
this->voltage_sensor_->publish_state(voltage);
|
|
this->status_clear_warning();
|
|
}
|
|
}
|
|
if (this->battery_remaining_sensor_ != nullptr) {
|
|
if (!this->read_byte_16(MAX17043_SOC, &raw_percent)) {
|
|
this->status_set_warning("Unable to read MAX17043_SOC");
|
|
} else {
|
|
float percent = (float) ((raw_percent >> 8) + 0.003906f * (raw_percent & 0x00ff));
|
|
this->battery_remaining_sensor_->publish_state(percent);
|
|
this->status_clear_warning();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MAX17043Component::setup() {
|
|
ESP_LOGCONFIG(TAG, "Running setup");
|
|
|
|
uint16_t config_reg;
|
|
if (this->write(&MAX17043_CONFIG, 1) != i2c::ERROR_OK) {
|
|
this->status_set_warning();
|
|
return;
|
|
}
|
|
|
|
if (this->read(reinterpret_cast<uint8_t *>(&config_reg), 2) != i2c::ERROR_OK) {
|
|
this->status_set_warning();
|
|
return;
|
|
}
|
|
|
|
config_reg = i2c::i2ctohs(config_reg) & MAX17043_CONFIG_SAFE_MASK;
|
|
ESP_LOGV(TAG, "MAX17043 CONFIG register reads 0x%X", config_reg);
|
|
|
|
if (config_reg != MAX17043_CONFIG_POWER_UP_DEFAULT) {
|
|
ESP_LOGE(TAG, "Device does not appear to be a MAX17043");
|
|
this->status_set_error("unrecognised");
|
|
this->mark_failed();
|
|
return;
|
|
}
|
|
|
|
// need to write back to config register to reset the sleep bit
|
|
if (!this->write_byte_16(MAX17043_CONFIG, MAX17043_CONFIG_POWER_UP_DEFAULT)) {
|
|
this->status_set_error("sleep reset failed");
|
|
this->mark_failed();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void MAX17043Component::dump_config() {
|
|
ESP_LOGCONFIG(TAG, "MAX17043:");
|
|
LOG_I2C_DEVICE(this);
|
|
if (this->is_failed()) {
|
|
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
|
}
|
|
LOG_UPDATE_INTERVAL(this);
|
|
LOG_SENSOR(" ", "Battery Voltage", this->voltage_sensor_);
|
|
LOG_SENSOR(" ", "Battery Level", this->battery_remaining_sensor_);
|
|
}
|
|
|
|
float MAX17043Component::get_setup_priority() const { return setup_priority::DATA; }
|
|
|
|
void MAX17043Component::sleep_mode() {
|
|
if (!this->is_failed()) {
|
|
if (!this->write_byte_16(MAX17043_CONFIG, MAX17043_CONFIG_POWER_UP_DEFAULT | MAX17043_CONFIG_SLEEP_MASK)) {
|
|
ESP_LOGW(TAG, "Unable to write the sleep bit to config register");
|
|
this->status_set_warning();
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace max17043
|
|
} // namespace esphome
|