ESPHome 2025.5.0
Loading...
Searching...
No Matches
weikai_i2c.cpp
Go to the documentation of this file.
1
5
6#include "weikai_i2c.h"
7
8namespace esphome {
9namespace weikai_i2c {
10static const char *const TAG = "weikai_i2c";
11
13void print_buffer(const uint8_t *data, size_t length) {
14 char hex_buffer[100];
15 hex_buffer[(3 * 32) + 1] = 0;
16 for (size_t i = 0; i < length; i++) {
17 snprintf(&hex_buffer[3 * (i % 32)], sizeof(hex_buffer), "%02X ", data[i]);
18 if (i % 32 == 31) {
19 ESP_LOGVV(TAG, " %s", hex_buffer);
20 }
21 }
22 if (length % 32) {
23 // null terminate if incomplete line
24 hex_buffer[3 * (length % 32) + 2] = 0;
25 ESP_LOGVV(TAG, " %s", hex_buffer);
26 }
27}
28
29static const char *const REG_TO_STR_P0[16] = {"GENA", "GRST", "GMUT", "SPAGE", "SCR", "LCR", "FCR", "SIER",
30 "SIFR", "TFCNT", "RFCNT", "FSR", "LSR", "FDAT", "FWCR", "RS485"};
31static const char *const REG_TO_STR_P1[16] = {"GENA", "GRST", "GMUT", "SPAGE", "BAUD1", "BAUD0", "PRES", "RFTL",
32 "TFTL", "FWTH", "FWTL", "XON1", "XOFF1", "SADR", "SAEN", "RTSDLY"};
33using namespace weikai;
34// method to print a register value as text: used in the log messages ...
35const char *reg_to_str(int reg, bool page1) {
36 if (reg == WKREG_GPDAT) {
37 return "GPDAT";
38 } else if (reg == WKREG_GPDIR) {
39 return "GPDIR";
40 } else {
41 return page1 ? REG_TO_STR_P1[reg & 0x0F] : REG_TO_STR_P0[reg & 0x0F];
42 }
43}
44enum RegType { REG = 0, FIFO = 1 };
45
51inline uint8_t i2c_address(uint8_t base_address, uint8_t channel, RegType fifo) {
52 // the address of the device is:
53 // +----+----+----+----+----+----+----+----+
54 // | 0 | A1 | A0 | 1 | 0 | C1 | C0 | F |
55 // +----+----+----+----+----+----+----+----+
56 // where:
57 // - A1,A0 is the address read from A1,A0 switch
58 // - C1,C0 is the channel number (in practice only 00 or 01)
59 // - F is: 0 when accessing register, one when accessing FIFO
60 uint8_t const addr = base_address | channel << 1 | fifo << 0;
61 return addr;
62}
63
65// The WeikaiRegisterI2C methods
68 uint8_t value = 0x00;
69 WeikaiComponentI2C *comp_i2c = static_cast<WeikaiComponentI2C *>(this->comp_);
70 uint8_t address = i2c_address(comp_i2c->base_address_, this->channel_, REG);
71 comp_i2c->set_i2c_address(address);
72 auto error = comp_i2c->read_register(this->register_, &value, 1);
73 if (error == i2c::NO_ERROR) {
75 ESP_LOGVV(TAG, "WeikaiRegisterI2C::read_reg() @%02X reg=%s ch=%u I2C_code:%d, buf=%02X", address,
76 reg_to_str(this->register_, comp_i2c->page1()), this->channel_, (int) error, value);
77 } else { // error
79 ESP_LOGE(TAG, "WeikaiRegisterI2C::read_reg() @%02X reg=%s ch=%u I2C_code:%d, buf=%02X", address,
80 reg_to_str(this->register_, comp_i2c->page1()), this->channel_, (int) error, value);
81 }
82 return value;
83}
84
85void WeikaiRegisterI2C::read_fifo(uint8_t *data, size_t length) const {
86 WeikaiComponentI2C *comp_i2c = static_cast<WeikaiComponentI2C *>(this->comp_);
87 uint8_t address = i2c_address(comp_i2c->base_address_, this->channel_, FIFO);
88 comp_i2c->set_i2c_address(address);
89 auto error = comp_i2c->read(data, length);
90 if (error == i2c::NO_ERROR) {
92#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
93 ESP_LOGVV(TAG, "WeikaiRegisterI2C::read_fifo() @%02X ch=%d I2C_code:%d len=%d buffer", address, this->channel_,
94 (int) error, length);
95 print_buffer(data, length);
96#endif
97 } else { // error
99 ESP_LOGE(TAG, "WeikaiRegisterI2C::read_fifo() @%02X reg=N/A ch=%d I2C_code:%d len=%d buf=%02X...", address,
100 this->channel_, (int) error, length, data[0]);
101 }
102}
103
104void WeikaiRegisterI2C::write_reg(uint8_t value) {
105 WeikaiComponentI2C *comp_i2c = static_cast<WeikaiComponentI2C *>(this->comp_);
106 uint8_t address = i2c_address(comp_i2c->base_address_, this->channel_, REG); // update the i2c bus
107 comp_i2c->set_i2c_address(address);
108 auto error = comp_i2c->write_register(this->register_, &value, 1);
109 if (error == i2c::NO_ERROR) {
111 ESP_LOGVV(TAG, "WK2168Reg::write_reg() @%02X reg=%s ch=%d I2C_code:%d buf=%02X", address,
112 reg_to_str(this->register_, comp_i2c->page1()), this->channel_, (int) error, value);
113 } else { // error
114 this->comp_->status_set_warning();
115 ESP_LOGE(TAG, "WK2168Reg::write_reg() @%02X reg=%s ch=%d I2C_code:%d buf=%d", address,
116 reg_to_str(this->register_, comp_i2c->page1()), this->channel_, (int) error, value);
117 }
118}
119
120void WeikaiRegisterI2C::write_fifo(uint8_t *data, size_t length) {
121 WeikaiComponentI2C *comp_i2c = static_cast<WeikaiComponentI2C *>(this->comp_);
122 uint8_t address = i2c_address(comp_i2c->base_address_, this->channel_, FIFO); // set fifo flag
123 comp_i2c->set_i2c_address(address);
124 auto error = comp_i2c->write(data, length);
125 if (error == i2c::NO_ERROR) {
127#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
128 ESP_LOGVV(TAG, "WK2168Reg::write_fifo() @%02X ch=%d I2C_code:%d len=%d buffer", address, this->channel_,
129 (int) error, length);
130 print_buffer(data, length);
131#endif
132 } else { // error
133 this->comp_->status_set_warning();
134 ESP_LOGE(TAG, "WK2168Reg::write_fifo() @%02X reg=N/A, ch=%d I2C_code:%d len=%d, buf=%02X...", address,
135 this->channel_, (int) error, length, data[0]);
136 }
137}
138
140// The WeikaiComponentI2C methods
143 // before any manipulation we store the address to base_address_ for future use
144 this->base_address_ = this->address_;
145 ESP_LOGCONFIG(TAG, "Setting up wk2168_i2c: %s with %d UARTs at @%02X ...", this->get_name(), this->children_.size(),
146 this->base_address_);
147
148 // enable all channels
150 // reset all channels
152 // initialize the spage register to page 0
153 this->reg(WKREG_SPAGE, 0) = 0;
154 this->page1_ = false;
155
156 // we setup our children channels
157 for (auto *child : this->children_) {
158 child->setup_channel();
159 }
160}
161
163 ESP_LOGCONFIG(TAG, "Initialization of %s with %d UARTs completed", this->get_name(), this->children_.size());
164 ESP_LOGCONFIG(TAG, " Crystal: %" PRIu32, this->crystal_);
165 if (test_mode_)
166 ESP_LOGCONFIG(TAG, " Test mode: %d", test_mode_);
167 ESP_LOGCONFIG(TAG, " Transfer buffer size: %d", XFER_MAX_SIZE);
168 this->address_ = this->base_address_; // we restore the base_address before display (less confusing)
169 LOG_I2C_DEVICE(this);
170
171 for (auto *child : this->children_) {
172 child->dump_channel();
173 }
174}
175
176} // namespace weikai_i2c
177} // namespace esphome
uint8_t address
Definition bl0906.h:4
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a specific register in the I²C device
Definition i2c.cpp:25
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:190
uint8_t address_
store the address of the device on the bus
Definition i2c.h:273
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:10
void set_i2c_address(uint8_t address)
We store the address of the device on the bus.
Definition i2c.h:140
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition i2c.h:164
int test_mode_
test mode value (0 -> no tests)
Definition weikai.h:262
uint32_t crystal_
crystal value;
Definition weikai.h:261
bool page1_
set to true when in "page1 mode"
Definition weikai.h:263
std::vector< WeikaiChannel * > children_
the list of WeikaiChannel UART children
Definition weikai.h:264
const char * get_name()
Get the name of the component.
Definition weikai.h:216
uint8_t register_
address of the register
Definition weikai.h:186
uint8_t channel_
channel for this register
Definition weikai.h:187
WeikaiComponent *const comp_
pointer to our parent (aggregation)
Definition weikai.h:185
The WeikaiComponentI2C class stores the information to the WeiKai component connected through an I2C ...
Definition weikai_i2c.h:42
weikai::WeikaiRegister & reg(uint8_t reg, uint8_t channel) override
Definition weikai_i2c.h:44
uint8_t base_address_
base address of I2C device
Definition weikai_i2c.h:56
void write_fifo(uint8_t *data, size_t length) override
uint8_t read_reg() const override
void write_reg(uint8_t value) override
void read_fifo(uint8_t *data, size_t length) const override
constexpr uint8_t WKREG_SPAGE
Global Page register c0/c1 0011.
Definition wk_reg_def.h:127
constexpr uint8_t GRST_C4RST
Channel 4 soft reset (0: not reset, 1: reset)
Definition wk_reg_def.h:56
constexpr uint8_t WKREG_GPDIR
Global GPIO direction register - 10 0001.
Definition wk_reg_def.h:85
constexpr uint8_t WKREG_GPDAT
Global GPIO data register - 11 0001.
Definition wk_reg_def.h:99
constexpr uint8_t GRST_C2RST
Channel 2 soft reset (0: not reset, 1: reset)
Definition wk_reg_def.h:60
constexpr uint8_t WKREG_GRST
Global Reset Register - 00 0001.
Definition wk_reg_def.h:54
constexpr uint8_t GRST_C3RST
Channel 3 soft reset (0: not reset, 1: reset)
Definition wk_reg_def.h:58
constexpr uint8_t GENA_C2EN
Channel 2 enable clock (0: disable, 1: enable)
Definition wk_reg_def.h:38
constexpr uint8_t GRST_C1RST
Channel 1 soft reset (0: not reset, 1: reset)
Definition wk_reg_def.h:62
constexpr uint8_t GENA_C3EN
Channel 3 enable clock (0: disable, 1: enable)
Definition wk_reg_def.h:36
constexpr uint8_t GENA_C4EN
Channel 4 enable clock (0: disable, 1: enable)
Definition wk_reg_def.h:34
constexpr uint8_t WKREG_GENA
Global Control Register - 00 0000.
Definition wk_reg_def.h:32
constexpr uint8_t GENA_C1EN
Channel 1 enable clock (0: disable, 1: enable)
Definition wk_reg_def.h:40
@ NO_ERROR
No error found during execution of method.
Definition i2c_bus.h:12
uint8_t i2c_address(uint8_t base_address, uint8_t channel, RegType fifo)
Computes the I²C bus's address used to access the component.
constexpr size_t XFER_MAX_SIZE
XFER_MAX_SIZE defines the maximum number of bytes allowed during one transfer.
Definition weikai.h:34
const char * reg_to_str(int reg, bool page1)
Definition weikai.cpp:69
void print_buffer(const uint8_t *data, size_t length)
Display a buffer in hexadecimal format (32 hex values / line) for debug.
Definition weikai.cpp:47
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint16_t length
Definition tt21100.cpp:0
WeiKai component family - classes declaration.