9static const char *
const TAG =
"mcp4461";
13 auto err = this->
write(
nullptr, 0);
21 for (uint8_t i = 0; i < 8; i++) {
22 if (this->
reg_[i].initial_value.has_value()) {
23 uint16_t initial_state =
static_cast<uint16_t
>(*this->
reg_[i].
initial_value * 256.0f);
26 if (this->
reg_[i].enabled) {
40 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
45 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
61 this->
write_protected_ =
static_cast<bool>((status_register_value >> 0) & 0x01);
69 ESP_LOGCONFIG(TAG,
"mcp4461:");
75 for (uint8_t i = 0; i < 8; ++i) {
80 ESP_LOGCONFIG(TAG,
" ├── Volatile wiper [%u] level: %u, Status: %s, HW: %s, A: %s, B: %s, W: %s", i,
81 this->
reg_[i].
state, ONOFF(this->
reg_[i].terminal_hw), ONOFF(this->
reg_[i].terminal_a),
82 ONOFF(this->
reg_[i].terminal_b), ONOFF(this->
reg_[i].terminal_w), ONOFF(this->
reg_[i].enabled));
84 ESP_LOGCONFIG(TAG,
" ├── Nonvolatile wiper [%u] level: %u", i, this->
reg_[i].
state);
93 for (uint8_t i = 0; i < 8; i++) {
94 if (this->
reg_[i].update_level) {
104 if (this->
reg_[i].update_terminal) {
109 ESP_LOGV(TAG,
"updating terminal %u to new value %u",
static_cast<uint8_t
>(terminal_connector),
130 uint8_t msb = buf >> 8;
131 uint8_t lsb =
static_cast<uint8_t
>(buf & 0x00ff);
132 if (msb != 1 || ((lsb >> 7) & 0x01) != 1 || ((lsb >> 1) & 0x01) != 1) {
145 ESP_LOGI(TAG,
"D7: %u, WL3: %u, WL2: %u, EEWA: %u, WL1: %u, WL0: %u, R1: %u, WP: %u",
146 ((status_register_value >> 7) & 0x01), ((status_register_value >> 6) & 0x01),
147 ((status_register_value >> 5) & 0x01), ((status_register_value >> 4) & 0x01),
148 ((status_register_value >> 3) & 0x01), ((status_register_value >> 2) & 0x01),
149 ((status_register_value >> 1) & 0x01), ((status_register_value >> 0) & 0x01));
158 err = this->
read(
reinterpret_cast<uint8_t *
>(buf), 2);
168 bool nonvolatile =
false;
187 ESP_LOGW(TAG,
"unknown wiper specified");
201 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
202 if (!(this->
reg_[wiper_idx].enabled)) {
206 if (!(this->
reg_[wiper_idx].enabled)) {
207 ESP_LOGW(TAG,
"reading from disabled volatile wiper %u, returning 0", wiper_idx);
225 ESP_LOGW(TAG,
"Error fetching %swiper %u value", (wiper_idx > 3) ?
"nonvolatile " :
"", wiper_idx);
236 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
237 if (!(this->
reg_[wiper_idx].enabled)) {
242 ESP_LOGV(TAG,
"Got value %u from wiper %u",
data, wiper_idx);
252 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
257 if (!(this->
reg_[wiper_idx].enabled)) {
261 if (this->
reg_[wiper_idx].wiper_lock_active) {
265 ESP_LOGV(TAG,
"Setting MCP4461 wiper %u to %u", wiper_idx, value);
272 bool nonvolatile = wiper > 3;
276 ESP_LOGW(TAG,
"Error writing %swiper %u level %u", (wiper > 3) ?
"nonvolatile " :
"", wiper, value);
285 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
286 if ((this->
reg_[wiper_idx].enabled)) {
290 if (this->
reg_[wiper_idx].wiper_lock_active) {
294 ESP_LOGV(TAG,
"Enabling wiper %u", wiper_idx);
307 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
308 if (!(this->
reg_[wiper_idx].enabled)) {
312 if (this->
reg_[wiper_idx].wiper_lock_active) {
316 ESP_LOGV(TAG,
"Disabling wiper %u", wiper_idx);
329 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
330 if (!(this->
reg_[wiper_idx].enabled)) {
334 if (this->
reg_[wiper_idx].wiper_lock_active) {
338 if (this->
reg_[wiper_idx].
state == 256) {
339 ESP_LOGV(TAG,
"Maximum wiper level reached, further increase of wiper %u prohibited", wiper_idx);
342 ESP_LOGV(TAG,
"Increasing wiper %u", wiper_idx);
360 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
361 if (!(this->
reg_[wiper_idx].enabled)) {
365 if (this->
reg_[wiper_idx].wiper_lock_active) {
370 ESP_LOGV(TAG,
"Minimum wiper level reached, further decrease of wiper %u prohibited", wiper_idx);
373 ESP_LOGV(TAG,
"Decreasing wiper %u", wiper_idx);
387 uint8_t i =
static_cast<uint8_t
>(terminal_connector) <= 1 ? 0 : 2;
388 uint8_t new_value_byte = 0;
390 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[i].
terminal_w) << 1;
391 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[i].
terminal_a) << 2;
392 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[i].
terminal_hw) << 3;
393 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[(i + 1)].
terminal_b) << 4;
394 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[(i + 1)].
terminal_w) << 5;
395 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[(i + 1)].
terminal_a) << 6;
396 new_value_byte +=
static_cast<uint8_t
>(this->
reg_[(i + 1)].
terminal_hw) << 7;
397 return new_value_byte;
410 return static_cast<uint8_t
>(buf & 0x00ff);
414 ESP_LOGW(TAG,
"Error fetching terminal register value");
424 if ((
static_cast<uint8_t
>(terminal_connector) != 0 &&
static_cast<uint8_t
>(terminal_connector) != 1)) {
428 if (terminal_data == 0) {
431 ESP_LOGV(TAG,
"Got terminal register %u data 0x%02X",
static_cast<uint8_t
>(terminal_connector), terminal_data);
432 uint8_t wiper_index = 0;
433 if (
static_cast<uint8_t
>(terminal_connector) == 1) {
436 this->
reg_[wiper_index].
terminal_b = ((terminal_data >> 0) & 0x01);
437 this->
reg_[wiper_index].
terminal_w = ((terminal_data >> 1) & 0x01);
438 this->
reg_[wiper_index].
terminal_a = ((terminal_data >> 2) & 0x01);
440 this->
reg_[(wiper_index + 1)].terminal_b = ((terminal_data >> 4) & 0x01);
441 this->
reg_[(wiper_index + 1)].terminal_w = ((terminal_data >> 5) & 0x01);
442 this->
reg_[(wiper_index + 1)].terminal_a = ((terminal_data >> 6) & 0x01);
443 this->
reg_[(wiper_index + 1)].terminal_hw = ((terminal_data >> 7) & 0x01);
452 if (
static_cast<uint8_t
>(terminal_connector) == 0) {
454 }
else if (
static_cast<uint8_t
>(terminal_connector) == 1) {
457 ESP_LOGW(TAG,
"Invalid terminal connector id %u specified",
static_cast<uint8_t
>(terminal_connector));
473 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
474 ESP_LOGV(TAG,
"Enabling terminal %c of wiper %u", terminal, wiper_idx);
489 ESP_LOGW(TAG,
"Unknown terminal %c specified", terminal);
500 uint8_t wiper_idx =
static_cast<uint8_t
>(wiper);
501 ESP_LOGV(TAG,
"Disabling terminal %c of wiper %u", terminal, wiper_idx);
516 ESP_LOGW(TAG,
"Unknown terminal %c specified", terminal);
537 ESP_LOGW(TAG,
"Error fetching EEPROM location value");
559 ESP_LOGW(TAG,
"Error writing EEPROM value");
584 return ready_for_write;
588 const uint32_t start_millis =
millis();
590 ESP_LOGV(TAG,
"Waiting until EEPROM is ready for write, start_millis = %" PRIu32, start_millis);
597 if (ready_for_write) {
598 ESP_LOGV(TAG,
"EEPROM is ready for new write, elapsed_millis = %" PRIu32,
millis() - start_millis);
614 uint8_t
reg =
data > 0xff ? 1 : 0;
615 uint8_t value_byte =
static_cast<uint8_t
>(
data & 0x00ff);
616 ESP_LOGV(TAG,
"Writing value %u to address %u",
data, addr);
virtual void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message=nullptr)
bool status_has_warning() const
void status_clear_warning()
ErrorCode write(const uint8_t *data, size_t len) const
writes an array of bytes to a device using an I2CBus
ErrorCode read(uint8_t *data, size_t len) const
reads an array of bytes from the device using an I2CBus
uint8_t address_
store the address of the device on the bus
bool write_byte(uint8_t a_register, uint8_t data) const
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
void set_initial_value(Mcp4461WiperIdx wiper, float initial_value)
public function used to set initial value
bool increase_wiper_(Mcp4461WiperIdx wiper)
uint8_t calc_terminal_connector_byte_(Mcp4461TerminalIdx terminal_connector)
uint8_t get_terminal_register_(Mcp4461TerminalIdx terminal_connector)
void update_terminal_register_(Mcp4461TerminalIdx terminal_connector)
uint16_t get_eeprom_value(Mcp4461EepromLocation location)
get eeprom value from location
void dump_config() override
bool set_eeprom_value(Mcp4461EepromLocation location, uint16_t value)
set eeprom value at specified location
void disable_wiper_(Mcp4461WiperIdx wiper)
void initialize_terminal_disabled(Mcp4461WiperIdx wiper, char terminal)
public function used to set disable terminal config
void enable_wiper_(Mcp4461WiperIdx wiper)
void update_write_protection_status_()
uint16_t read_wiper_level_(uint8_t wiper)
bool mcp4461_write_(uint8_t addr, uint16_t data, bool nonvolatile=false)
bool read_16_(uint8_t address, uint16_t *buf)
bool last_eeprom_write_timed_out_
void enable_terminal_(Mcp4461WiperIdx wiper, char terminal)
bool is_eeprom_ready_for_writing_(bool wait_if_not_ready)
uint16_t get_wiper_level_(Mcp4461WiperIdx wiper)
uint8_t get_status_register_()
static const LogString * get_message_string(int status)
bool update_wiper_level_(Mcp4461WiperIdx wiper)
uint8_t get_wiper_address_(uint8_t wiper)
void disable_terminal_(Mcp4461WiperIdx, char terminal)
@ MCP4461_STATUS_REGISTER_INVALID
@ MCP4461_STATUS_REGISTER_ERROR
@ MCP4461_WRITE_PROTECTED
@ MCP4461_STATUS_I2C_ERROR
void write_wiper_level_(uint8_t wiper, uint16_t value)
bool decrease_wiper_(Mcp4461WiperIdx wiper)
bool set_terminal_register_(Mcp4461TerminalIdx terminal_connector, uint8_t data)
bool set_wiper_level_(Mcp4461WiperIdx wiper, uint16_t value)
void read_status_register_to_log()
read status register to log
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
@ ERROR_OK
No error found during execution of method.
constexpr uint8_t EEPROM_WRITE_TIMEOUT_MS
Providing packet encoding functions for exchanging data with a remote host.
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
void IRAM_ATTR HOT yield()
uint32_t IRAM_ATTR HOT millis()
optional< float > initial_value