ESPHome 2025.9.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 {
5namespace ch422g {
6
7static const uint8_t CH422G_REG_MODE = 0x24;
8static const uint8_t CH422G_MODE_OUTPUT = 0x01; // enables output mode on 0-7
9static const uint8_t CH422G_MODE_OPEN_DRAIN = 0x04; // enables open drain mode on 8-11
10static const uint8_t CH422G_REG_IN = 0x26; // read reg for input bits
11static const uint8_t CH422G_REG_OUT = 0x38; // write reg for output bits 0-7
12static const uint8_t CH422G_REG_OUT_UPPER = 0x23; // write reg for output bits 8-11
13
14static const char *const TAG = "ch422g";
15
17 // set outputs before mode
18 this->write_outputs_();
19 // Set mode and check for errors
20 if (!this->set_mode_(this->mode_value_) || !this->read_inputs_()) {
21 ESP_LOGE(TAG, "CH422G not detected at 0x%02X", this->address_);
22 this->mark_failed();
23 return;
24 }
25
26 ESP_LOGCONFIG(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
27 this->status_has_error());
28}
29
31 // Clear all the previously read flags.
32 this->pin_read_flags_ = 0x00;
33}
34
36 ESP_LOGCONFIG(TAG, "CH422G:");
37 LOG_I2C_DEVICE(this)
38 if (this->is_failed()) {
39 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
40 }
41}
42
43void CH422GComponent::pin_mode(uint8_t pin, gpio::Flags flags) {
44 if (pin < 8) {
45 if (flags & gpio::FLAG_OUTPUT) {
46 this->mode_value_ |= CH422G_MODE_OUTPUT;
47 }
48 } else {
49 if (flags & gpio::FLAG_OPEN_DRAIN) {
50 this->mode_value_ |= CH422G_MODE_OPEN_DRAIN;
51 }
52 }
53}
54
56 if (this->pin_read_flags_ == 0 || this->pin_read_flags_ & (1 << pin)) {
57 // Read values on first access or in case it's being read again in the same loop
58 this->read_inputs_();
59 }
60
61 this->pin_read_flags_ |= (1 << pin);
62 return (this->input_bits_ & (1 << pin)) != 0;
63}
64
65void CH422GComponent::digital_write(uint8_t pin, bool value) {
66 if (value) {
67 this->output_bits_ |= (1 << pin);
68 } else {
69 this->output_bits_ &= ~(1 << pin);
70 }
71 this->write_outputs_();
72}
73
75 if (this->is_failed()) {
76 return false;
77 }
78 uint8_t result;
79 // reading inputs requires the chip to be in input mode, possibly temporarily.
80 if (this->mode_value_ & CH422G_MODE_OUTPUT) {
81 this->set_mode_(this->mode_value_ & ~CH422G_MODE_OUTPUT);
82 result = this->read_reg_(CH422G_REG_IN);
83 this->set_mode_(this->mode_value_);
84 } else {
85 result = this->read_reg_(CH422G_REG_IN);
86 }
87 this->input_bits_ = result;
89 return true;
90}
91
92// Write a register. Can't use the standard write_byte() method because there is no single pre-configured i2c address.
93bool CH422GComponent::write_reg_(uint8_t reg, uint8_t value) {
94 auto err = this->bus_->write(reg, &value, 1);
95 if (err != i2c::ERROR_OK) {
96 this->status_set_warning(str_sprintf("write failed for register 0x%X, error %d", reg, err).c_str());
97 return false;
98 }
100 return true;
101}
102
103uint8_t CH422GComponent::read_reg_(uint8_t reg) {
104 uint8_t value;
105 auto err = this->bus_->read(reg, &value, 1);
106 if (err != i2c::ERROR_OK) {
107 this->status_set_warning(str_sprintf("read failed for register 0x%X, error %d", reg, err).c_str());
108 return 0;
109 }
110 this->status_clear_warning();
111 return value;
112}
113
114bool CH422GComponent::set_mode_(uint8_t mode) { return this->write_reg_(CH422G_REG_MODE, mode); }
115
117 return this->write_reg_(CH422G_REG_OUT, static_cast<uint8_t>(this->output_bits_)) &&
118 this->write_reg_(CH422G_REG_OUT_UPPER, static_cast<uint8_t>(this->output_bits_ >> 8));
119}
120
122
123// Run our loop() method very early in the loop, so that we cache read values
124// before other components call our digital_read() method.
125float CH422GComponent::get_loop_priority() const { return 9.0f; } // Just after WIFI
126
127void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
128bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
129
130void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); }
131std::string CH422GGPIOPin::dump_summary() const { return str_sprintf("EXIO%u via CH422G", pin_); }
133 flags_ = flags;
134 this->parent_->pin_mode(this->pin_, flags);
135}
136
137} // namespace ch422g
138} // namespace esphome
BedjetMode mode
BedJet operating mode.
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
bool status_has_warning() const
bool status_has_error() const
void status_clear_warning()
uint16_t output_bits_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition ch422g.h:37
void setup() override
Check i2c availability and setup masks.
Definition ch422g.cpp:16
float get_setup_priority() const override
Definition ch422g.cpp:121
bool set_mode_(uint8_t mode)
Definition ch422g.cpp:114
void pin_mode(uint8_t pin, gpio::Flags flags)
Helper function to set the pin mode of a pin.
Definition ch422g.cpp:43
uint8_t pin_read_flags_
Flags to check if read previously during this loop.
Definition ch422g.h:39
void loop() override
Poll for input changes periodically.
Definition ch422g.cpp:30
float get_loop_priority() const override
Definition ch422g.cpp:125
uint8_t read_reg_(uint8_t reg)
Definition ch422g.cpp:103
uint8_t mode_value_
Copy of the mode value.
Definition ch422g.h:43
bool write_reg_(uint8_t reg, uint8_t value)
Definition ch422g.cpp:93
uint8_t input_bits_
Copy of last read values.
Definition ch422g.h:41
bool digital_read(uint8_t pin)
Helper function to read the value of a pin.
Definition ch422g.cpp:55
void digital_write(uint8_t pin, bool value)
Helper function to write the value of a pin.
Definition ch422g.cpp:65
CH422GComponent * parent_
Definition ch422g.h:63
std::string dump_summary() const override
Definition ch422g.cpp:131
void set_flags(gpio::Flags flags)
Definition ch422g.cpp:132
bool digital_read() override
Definition ch422g.cpp:128
void pin_mode(gpio::Flags flags) override
Definition ch422g.cpp:127
void digital_write(bool value) override
Definition ch422g.cpp:130
virtual ErrorCode read(uint8_t address, uint8_t *buffer, size_t len)
Creates a ReadBuffer and calls the virtual readv() method to read bytes into this buffer.
Definition i2c_bus.h:47
virtual ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len)
Definition i2c_bus.h:62
I2CBus * bus_
pointer to I2CBus instance
Definition i2c.h:274
uint8_t address_
store the address of the device on the bus
Definition i2c.h:273
@ FLAG_OUTPUT
Definition gpio.h:19
@ FLAG_OPEN_DRAIN
Definition gpio.h:20
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
const float IO
For components that represent GPIO pins like PCF8573.
Definition component.cpp:48
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string str_sprintf(const char *fmt,...)
Definition helpers.cpp:208