ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
ch422g.cpp
Go to the documentation of this file.
1#include "ch422g.h"
2#include "esphome/core/log.h"
3
4namespace esphome::ch422g {
5
6static const uint8_t CH422G_REG_MODE = 0x24;
7static const uint8_t CH422G_MODE_OUTPUT = 0x01; // enables output mode on 0-7
8static const uint8_t CH422G_MODE_OPEN_DRAIN = 0x04; // enables open drain mode on 8-11
9static const uint8_t CH422G_REG_IN = 0x26; // read reg for input bits
10static const uint8_t CH422G_REG_OUT = 0x38; // write reg for output bits 0-7
11static const uint8_t CH422G_REG_OUT_UPPER = 0x23; // write reg for output bits 8-11
12
13static const char *const TAG = "ch422g";
14
16 // set outputs before mode
17 this->write_outputs_();
18 // Set mode and check for errors
19 if (!this->set_mode_(this->mode_value_) || !this->read_inputs_()) {
20 ESP_LOGE(TAG, "CH422G not detected at 0x%02X", this->address_);
21 this->mark_failed();
22 return;
23 }
24
25 ESP_LOGCONFIG(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
26 this->status_has_error());
27}
28
30 // Clear all the previously read flags.
31 this->pin_read_flags_ = 0x00;
32}
33
35 ESP_LOGCONFIG(TAG, "CH422G:");
36 LOG_I2C_DEVICE(this)
37 if (this->is_failed()) {
38 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
39 }
40}
41
43 if (pin < 8) {
45 this->mode_value_ |= CH422G_MODE_OUTPUT;
46 }
47 } else {
49 this->mode_value_ |= CH422G_MODE_OPEN_DRAIN;
50 }
51 }
52}
53
55 if (this->pin_read_flags_ == 0 || this->pin_read_flags_ & (1 << pin)) {
56 // Read values on first access or in case it's being read again in the same loop
57 this->read_inputs_();
58 }
59
60 this->pin_read_flags_ |= (1 << pin);
61 return (this->input_bits_ & (1 << pin)) != 0;
62}
63
64void CH422GComponent::digital_write(uint8_t pin, bool value) {
65 if (value) {
66 this->output_bits_ |= (1 << pin);
67 } else {
68 this->output_bits_ &= ~(1 << pin);
69 }
70 this->write_outputs_();
71}
72
74 if (this->is_failed()) {
75 return false;
76 }
77 uint8_t result;
78 // reading inputs requires the chip to be in input mode, possibly temporarily.
79 if (this->mode_value_ & CH422G_MODE_OUTPUT) {
80 this->set_mode_(this->mode_value_ & ~CH422G_MODE_OUTPUT);
81 result = this->read_reg_(CH422G_REG_IN);
82 this->set_mode_(this->mode_value_);
83 } else {
84 result = this->read_reg_(CH422G_REG_IN);
85 }
86 this->input_bits_ = result;
88 return true;
89}
90
91// Write a register. Can't use the standard write_byte() method because there is no single pre-configured i2c address.
92bool CH422GComponent::write_reg_(uint8_t reg, uint8_t value) {
93 auto err = this->bus_->write_readv(reg, &value, 1, nullptr, 0);
94 if (err != i2c::ERROR_OK) {
95 char buf[64];
96 snprintf(buf, sizeof(buf), "write failed for register 0x%X, error %d", reg, err);
97 this->status_set_warning(buf);
98 return false;
99 }
100 this->status_clear_warning();
101 return true;
102}
103
104uint8_t CH422GComponent::read_reg_(uint8_t reg) {
105 uint8_t value;
106 auto err = this->bus_->write_readv(reg, nullptr, 0, &value, 1);
107 if (err != i2c::ERROR_OK) {
108 char buf[64];
109 snprintf(buf, sizeof(buf), "read failed for register 0x%X, error %d", reg, err);
110 this->status_set_warning(buf);
111 return 0;
112 }
113 this->status_clear_warning();
114 return value;
115}
116
117bool CH422GComponent::set_mode_(uint8_t mode) { return this->write_reg_(CH422G_REG_MODE, mode); }
118
120 return this->write_reg_(CH422G_REG_OUT, static_cast<uint8_t>(this->output_bits_)) &&
121 this->write_reg_(CH422G_REG_OUT_UPPER, static_cast<uint8_t>(this->output_bits_ >> 8));
122}
123
125
127bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
128
129void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); }
130size_t CH422GGPIOPin::dump_summary(char *buffer, size_t len) const {
131 return buf_append_printf(buffer, len, 0, "EXIO%u via CH422G", this->pin_);
132}
134 flags_ = flags;
135 this->parent_->pin_mode(this->pin_, flags);
136}
137
138} // namespace esphome::ch422g
BedjetMode mode
BedJet operating mode.
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
bool status_has_warning() const
Definition component.h:278
bool status_has_error() const
Definition component.h:280
void status_clear_warning()
Definition component.h:289
uint16_t output_bits_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition ch422g.h:35
void setup() override
Check i2c availability and setup masks.
Definition ch422g.cpp:15
float get_setup_priority() const override
Definition ch422g.cpp:124
bool set_mode_(uint8_t mode)
Definition ch422g.cpp:117
void pin_mode(uint8_t pin, gpio::Flags flags)
Helper function to set the pin mode of a pin.
Definition ch422g.cpp:42
uint8_t pin_read_flags_
Flags to check if read previously during this loop.
Definition ch422g.h:37
void loop() override
Poll for input changes periodically.
Definition ch422g.cpp:29
uint8_t read_reg_(uint8_t reg)
Definition ch422g.cpp:104
uint8_t mode_value_
Copy of the mode value.
Definition ch422g.h:41
bool write_reg_(uint8_t reg, uint8_t value)
Definition ch422g.cpp:92
uint8_t input_bits_
Copy of last read values.
Definition ch422g.h:39
bool digital_read(uint8_t pin)
Helper function to read the value of a pin.
Definition ch422g.cpp:54
void digital_write(uint8_t pin, bool value)
Helper function to write the value of a pin.
Definition ch422g.cpp:64
CH422GComponent * parent_
Definition ch422g.h:61
size_t dump_summary(char *buffer, size_t len) const override
Definition ch422g.cpp:130
void set_flags(gpio::Flags flags)
Definition ch422g.cpp:133
bool digital_read() override
Definition ch422g.cpp:127
void pin_mode(gpio::Flags flags) override
Definition ch422g.cpp:126
void digital_write(bool value) override
Definition ch422g.cpp:129
virtual ErrorCode write_readv(uint8_t address, const uint8_t *write_buffer, size_t write_count, uint8_t *read_buffer, size_t read_count)=0
This virtual method writes bytes to an I2CBus from an array, then reads bytes into an array of ReadBu...
I2CBus * bus_
pointer to I2CBus instance
Definition i2c.h:271
uint8_t address_
store the address of the device on the bus
Definition i2c.h:270
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:152
uint16_t flags
@ FLAG_OUTPUT
Definition gpio.h:28
@ FLAG_OPEN_DRAIN
Definition gpio.h:29
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14
constexpr float IO
For components that represent GPIO pins like PCF8573.
Definition component.h:39
const void size_t len
Definition hal.h:64