ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
waveshare_io_ch32v003.cpp
Go to the documentation of this file.
2#include "esphome/core/log.h"
3
5
6static const uint8_t IO_EXTENSION_DIRECTION = 0x02;
7static const uint8_t IO_EXTENSION_IO_OUTPUT_ADDR = 0x03;
8static const uint8_t IO_EXTENSION_IO_INPUT_ADDR = 0x04;
9static const uint8_t IO_EXTENSION_PWM_ADDR = 0x05;
10static const uint8_t IO_EXTENSION_ADC_ADDR = 0x06;
11static const uint8_t IO_EXTENSION_RTC_INT_ADDR = 0x07;
12
13static const char *const TAG = "waveshare_io_ch32v003";
14
16 this->mode_mask_ = 0xFF; // Set all pins to output mode
17 this->output_mask_ = 0xFF; // Set all pins to high (output mode)
18
19 bool step1 = this->write_gpio_modes_();
20 bool step2 = this->write_gpio_outputs_();
21
22 if (!step1 || !step2) {
23 ESP_LOGE(TAG, "Failed to initialize Waveshare IO expander");
24 this->mark_failed();
25 return;
26 }
27
28 this->disable_loop();
29}
30
32 // bits: 0 = input, 1 = output
33 if (flags == gpio::FLAG_INPUT) {
34 // Clear mode mask bit
35 this->mode_mask_ &= ~(1 << pin);
36 this->enable_loop();
37 } else if (flags == gpio::FLAG_OUTPUT) {
38 // Set mode mask bit
39 this->mode_mask_ |= 1 << pin;
40 }
41 this->write_gpio_modes_();
42}
43
45
47 ESP_LOGCONFIG(TAG, "WaveshareIO:");
48 LOG_I2C_DEVICE(this)
49 if (this->is_failed()) {
50 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
51 }
52}
53
55 if (this->is_failed())
56 return 0;
57
58 uint8_t data[2];
59 if (!this->read_bytes(IO_EXTENSION_ADC_ADDR, data, 2)) {
60 this->status_set_warning(LOG_STR("Failed to read ADC register"));
61 return 0;
62 }
63 uint16_t adc_value = (data[1] << 8) | data[0];
65 return adc_value;
66}
67
69 if (this->is_failed())
70 return 0;
71
72 uint8_t data = 0;
73 if (!this->read_bytes(IO_EXTENSION_RTC_INT_ADDR, &data, 1)) {
74 this->status_set_warning(LOG_STR("Failed to read RTC interrupt register"));
75 return 0;
76 }
78 return data;
79}
80
82 if (this->is_failed())
83 return;
84
85 // PWM limits are enforced at the output component level to protect hardware
86 // based on circuit schematic requirements. This follows the pattern from the
87 // original Waveshare IO library function "void IO_EXTENSION_Pwm_Output(uint8_t Value)".
88
89 if (!this->write_byte(IO_EXTENSION_PWM_ADDR, value)) {
90 this->status_set_warning(LOG_STR("Failed to set PWM duty cycle"));
91 return;
92 }
93
95}
96
98 if (this->is_failed())
99 return false;
100 if (!this->write_byte(IO_EXTENSION_DIRECTION, this->mode_mask_)) {
101 this->status_set_warning(LOG_STR("Failed to write mode register"));
102 return false;
103 }
104 this->status_clear_warning();
105 return true;
106}
107
109 if (this->is_failed())
110 return false;
111 if (!this->write_byte(IO_EXTENSION_IO_OUTPUT_ADDR, this->output_mask_)) {
112 this->status_set_warning(LOG_STR("Failed to write output register"));
113 return false;
114 }
115 this->status_clear_warning();
116 return true;
117}
118
120 if (this->is_failed())
121 return false;
122
123 uint8_t data = 0;
124 if (!this->read_bytes(IO_EXTENSION_IO_INPUT_ADDR, &data, 1)) {
125 this->status_set_warning(LOG_STR("Failed to read input register"));
126 return false;
127 }
128 this->input_mask_ = data;
129
130 this->status_clear_warning();
131 return true;
132}
133
135 if (this->is_failed())
136 return;
137
138 if (value) {
139 this->output_mask_ |= (1 << pin);
140 } else {
141 this->output_mask_ &= ~(1 << pin);
142 }
143
144 uint8_t data = this->output_mask_;
145 if (!this->write_byte(IO_EXTENSION_IO_OUTPUT_ADDR, data)) {
146 this->status_set_warning(LOG_STR("Failed to write output register"));
147 return;
148 }
149
150 this->status_clear_warning();
151}
152
153bool WaveshareIOCH32V003Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); }
155
157void WaveshareIOCH32V003GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
158bool WaveshareIOCH32V003GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
159
161 this->parent_->digital_write(this->pin_, value ^ this->inverted_);
162}
163
164size_t WaveshareIOCH32V003GPIOPin::dump_summary(char *buffer, size_t len) const {
165 return buf_append_printf(buffer, len, 0, "EXIO%u via WaveshareIO", this->pin_);
166}
167
168} // namespace esphome::waveshare_io_ch32v003
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
void enable_loop()
Enable this component's loop.
Definition component.h:246
void disable_loop()
Disable this component's loop.
void status_clear_warning()
Definition component.h:289
WaveshareIOCH32V003Component * parent_
Definition helpers.h:1886
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:265
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:217
size_t dump_summary(char *buffer, size_t len) const override
uint16_t flags
@ FLAG_OUTPUT
Definition gpio.h:26
@ FLAG_INPUT
Definition gpio.h:25
constexpr float IO
For components that represent GPIO pins like PCF8573.
Definition component.h:41
const char *const TAG
Definition spi.cpp:7
const void size_t len
Definition hal.h:64