ESPHome  2024.9.0
ch422g.cpp
Go to the documentation of this file.
1 #include "ch422g.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace ch422g {
6 
7 const uint8_t CH422G_REG_IN = 0x26;
8 const uint8_t CH422G_REG_OUT = 0x38;
9 const uint8_t OUT_REG_DEFAULT_VAL = 0xdf;
10 
11 static const char *const TAG = "ch422g";
12 
14  ESP_LOGCONFIG(TAG, "Setting up CH422G...");
15  // Test to see if device exists
16  if (!this->read_inputs_()) {
17  ESP_LOGE(TAG, "CH422G not detected at 0x%02X", this->address_);
18  this->mark_failed();
19  return;
20  }
21 
22  // restore defaults over whatever got saved on last boot
23  if (!this->restore_value_) {
24  this->write_output_(OUT_REG_DEFAULT_VAL);
25  }
26 
27  ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
28  this->status_has_error());
29 }
30 
32  // Clear all the previously read flags.
33  this->pin_read_cache_ = 0x00;
34 }
35 
37  ESP_LOGCONFIG(TAG, "CH422G:");
38  LOG_I2C_DEVICE(this)
39  if (this->is_failed()) {
40  ESP_LOGE(TAG, "Communication with CH422G failed!");
41  }
42 }
43 
44 // ch422g doesn't have any flag support (needs docs?)
46 
47 bool CH422GComponent::digital_read(uint8_t pin) {
48  if (this->pin_read_cache_ == 0 || this->pin_read_cache_ & (1 << pin)) {
49  // Read values on first access or in case it's being read again in the same loop
50  this->read_inputs_();
51  }
52 
53  this->pin_read_cache_ |= (1 << pin);
54  return this->state_mask_ & (1 << pin);
55 }
56 
57 void CH422GComponent::digital_write(uint8_t pin, bool value) {
58  if (value) {
59  this->write_output_(this->state_mask_ | (1 << pin));
60  } else {
61  this->write_output_(this->state_mask_ & ~(1 << pin));
62  }
63 }
64 
66  if (this->is_failed()) {
67  return false;
68  }
69 
70  uint8_t temp = 0;
71  if ((this->last_error_ = this->read(&temp, 1)) != esphome::i2c::ERROR_OK) {
72  this->status_set_warning(str_sprintf("read_inputs_(): I2C I/O error: %d", (int) this->last_error_).c_str());
73  return false;
74  }
75 
76  uint8_t output = 0;
77  if ((this->last_error_ = this->bus_->read(CH422G_REG_IN, &output, 1)) != esphome::i2c::ERROR_OK) {
78  this->status_set_warning(str_sprintf("read_inputs_(): I2C I/O error: %d", (int) this->last_error_).c_str());
79  return false;
80  }
81 
82  this->state_mask_ = output;
83  this->status_clear_warning();
84 
85  return true;
86 }
87 
88 bool CH422GComponent::write_output_(uint8_t value) {
89  const uint8_t temp = 1;
90  if ((this->last_error_ = this->write(&temp, 1, false)) != esphome::i2c::ERROR_OK) {
91  this->status_set_warning(str_sprintf("write_output_(): I2C I/O error: %d", (int) this->last_error_).c_str());
92  return false;
93  }
94 
95  uint8_t write_mask = value;
96  if ((this->last_error_ = this->bus_->write(CH422G_REG_OUT, &write_mask, 1)) != esphome::i2c::ERROR_OK) {
97  this->status_set_warning(
98  str_sprintf("write_output_(): I2C I/O error: %d for write_mask: %d", (int) this->last_error_, (int) write_mask)
99  .c_str());
100  return false;
101  }
102 
103  this->state_mask_ = value;
104  this->status_clear_warning();
105  return true;
106 }
107 
109 
110 // Run our loop() method very early in the loop, so that we cache read values
111 // before other components call our digital_read() method.
112 float CH422GComponent::get_loop_priority() const { return 9.0f; } // Just after WIFI
113 
114 void CH422GGPIOPin::setup() { pin_mode(flags_); }
115 void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
116 bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
117 
118 void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
119 std::string CH422GGPIOPin::dump_summary() const { return str_sprintf("EXIO%u via CH422G", pin_); }
120 
121 } // namespace ch422g
122 } // namespace esphome
float get_loop_priority() const override
Definition: ch422g.cpp:112
std::string dump_summary() const override
Definition: ch422g.cpp:119
void setup() override
Check i2c availability and setup masks.
Definition: ch422g.cpp:13
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
bool status_has_warning() const
Definition: component.cpp:149
void loop() override
Poll for input changes periodically.
Definition: ch422g.cpp:31
void digital_write(uint8_t pin, bool value)
Helper function to write the value of a pin.
Definition: ch422g.cpp:57
bool is_failed() const
Definition: component.cpp:143
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition: i2c.h:160
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition: i2c.h:186
bool status_has_error() const
Definition: component.cpp:150
uint8_t pin_read_cache_
Flags to check if read previously during this loop.
Definition: ch422g.h:41
No error found during execution of method.
Definition: i2c_bus.h:13
std::string str_sprintf(const char *fmt,...)
Definition: helpers.cpp:312
const uint8_t OUT_REG_DEFAULT_VAL
Definition: ch422g.cpp:9
void status_clear_warning()
Definition: component.cpp:166
uint8_t state_mask_
The mask to write as output state - 1 means HIGH, 0 means LOW.
Definition: ch422g.h:39
bool digital_read(uint8_t pin)
Helper function to read the value of a pin.
Definition: ch422g.cpp:47
bool write_output_(uint8_t value)
Definition: ch422g.cpp:88
void dump_config() override
Definition: ch422g.cpp:36
void pin_mode(uint8_t pin, gpio::Flags flags)
Helper function to set the pin mode of a pin.
Definition: ch422g.cpp:45
esphome::i2c::ErrorCode last_error_
Storage for last I2C error seen.
Definition: ch422g.h:43
const uint32_t flags
Definition: stm32flash.h:85
float get_setup_priority() const override
Definition: ch422g.cpp:108
uint8_t address_
store the address of the device on the bus
Definition: i2c.h:269
const uint8_t CH422G_REG_IN
Definition: ch422g.cpp:7
I2CBus * bus_
pointer to I2CBus instance
Definition: i2c.h:270
const uint8_t CH422G_REG_OUT
Definition: ch422g.cpp:8
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
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
const float IO
For components that represent GPIO pins like PCF8573.
Definition: component.cpp:17
bool restore_value_
Whether we want to override stored values on expander.
Definition: ch422g.h:45
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool digital_read() override
Definition: ch422g.cpp:116
void digital_write(bool value) override
Definition: ch422g.cpp:118
void pin_mode(gpio::Flags flags) override
Definition: ch422g.cpp:115