ESPHome  2024.8.3
weikai_spi.cpp
Go to the documentation of this file.
1 
6 #include "weikai_spi.h"
7 
8 namespace esphome {
9 namespace weikai_spi {
10 using namespace weikai;
11 static const char *const TAG = "weikai_spi";
12 
16 inline std::string i2s(uint8_t val) { return std::bitset<8>(val).to_string(); }
18 #define I2S2CS(val) (i2s(val).c_str())
19 
23 uint32_t elapsed_ms(uint32_t &last_time) {
24  uint32_t e = millis() - last_time;
25  last_time = millis();
26  return e;
27 };
28 
32 const char *p2s(uart::UARTParityOptions parity) {
33  using namespace uart;
34  switch (parity) {
36  return "NONE";
38  return "EVEN";
40  return "ODD";
41  default:
42  return "UNKNOWN";
43  }
44 }
45 
47 void print_buffer(const uint8_t *data, size_t length) {
48  char hex_buffer[100];
49  hex_buffer[(3 * 32) + 1] = 0;
50  for (size_t i = 0; i < length; i++) {
51  snprintf(&hex_buffer[3 * (i % 32)], sizeof(hex_buffer), "%02X ", data[i]);
52  if (i % 32 == 31) {
53  ESP_LOGVV(TAG, " %s", hex_buffer);
54  }
55  }
56  if (length % 32) {
57  // null terminate if incomplete line
58  hex_buffer[3 * (length % 32) + 2] = 0;
59  ESP_LOGVV(TAG, " %s", hex_buffer);
60  }
61 }
62 
63 static const char *const REG_TO_STR_P0[16] = {"GENA", "GRST", "GMUT", "SPAGE", "SCR", "LCR", "FCR", "SIER",
64  "SIFR", "TFCNT", "RFCNT", "FSR", "LSR", "FDAT", "FWCR", "RS485"};
65 static const char *const REG_TO_STR_P1[16] = {"GENA", "GRST", "GMUT", "SPAGE", "BAUD1", "BAUD0", "PRES", "RFTL",
66  "TFTL", "FWTH", "FWTL", "XON1", "XOFF1", "SADR", "SAEN", "RTSDLY"};
67 
68 // method to print a register value as text: used in the log messages ...
69 const char *reg_to_str(int reg, bool page1) {
70  if (reg == WKREG_GPDAT) {
71  return "GPDAT";
72  } else if (reg == WKREG_GPDIR) {
73  return "GPDIR";
74  } else {
75  return page1 ? REG_TO_STR_P1[reg & 0x0F] : REG_TO_STR_P0[reg & 0x0F];
76  }
77 }
78 
79 enum RegType { REG = 0, FIFO = 1 };
80 enum CmdType { WRITE_CMD = 0, READ_CMD = 1 };
81 
96 inline static uint8_t cmd_byte(RegType fifo, CmdType transfer_type, uint8_t channel, uint8_t reg) {
97  return (fifo << 7 | transfer_type << 6 | channel << 4 | reg << 0);
98 }
99 
101 // The WeikaiRegisterSPI methods
104  auto *spi_comp = static_cast<WeikaiComponentSPI *>(this->comp_);
105  uint8_t cmd = cmd_byte(REG, READ_CMD, this->channel_, this->register_);
106  spi_comp->enable();
107  spi_comp->write_byte(cmd);
108  uint8_t val = spi_comp->read_byte();
109  spi_comp->disable();
110  ESP_LOGVV(TAG, "WeikaiRegisterSPI::read_reg() cmd=%s(%02X) reg=%s ch=%d buf=%02X", I2S2CS(cmd), cmd,
111  reg_to_str(this->register_, this->comp_->page1()), this->channel_, val);
112  return val;
113 }
114 
115 void WeikaiRegisterSPI::read_fifo(uint8_t *data, size_t length) const {
116  auto *spi_comp = static_cast<WeikaiComponentSPI *>(this->comp_);
117  uint8_t cmd = cmd_byte(FIFO, READ_CMD, this->channel_, this->register_);
118  spi_comp->enable();
119  spi_comp->write_byte(cmd);
120  spi_comp->read_array(data, length);
121  spi_comp->disable();
122 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
123  ESP_LOGVV(TAG, "WeikaiRegisterSPI::read_fifo() cmd=%s(%02X) ch=%d len=%d buffer", I2S2CS(cmd), cmd, this->channel_,
124  length);
125  print_buffer(data, length);
126 #endif
127 }
128 
129 void WeikaiRegisterSPI::write_reg(uint8_t value) {
130  auto *spi_comp = static_cast<WeikaiComponentSPI *>(this->comp_);
131  uint8_t buf[2]{cmd_byte(REG, WRITE_CMD, this->channel_, this->register_), value};
132  spi_comp->enable();
133  spi_comp->write_array(buf, 2);
134  spi_comp->disable();
135  ESP_LOGVV(TAG, "WeikaiRegisterSPI::write_reg() cmd=%s(%02X) reg=%s ch=%d buf=%02X", I2S2CS(buf[0]), buf[0],
136  reg_to_str(this->register_, this->comp_->page1()), this->channel_, buf[1]);
137 }
138 
139 void WeikaiRegisterSPI::write_fifo(uint8_t *data, size_t length) {
140  auto *spi_comp = static_cast<WeikaiComponentSPI *>(this->comp_);
141  uint8_t cmd = cmd_byte(FIFO, WRITE_CMD, this->channel_, this->register_);
142  spi_comp->enable();
143  spi_comp->write_byte(cmd);
144  spi_comp->write_array(data, length);
145  spi_comp->disable();
146 
147 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
148  ESP_LOGVV(TAG, "WeikaiRegisterSPI::write_fifo() cmd=%s(%02X) ch=%d len=%d buffer", I2S2CS(cmd), cmd, this->channel_,
149  length);
150  print_buffer(data, length);
151 #endif
152 }
153 
155 // The WeikaiComponentSPI methods
158  using namespace weikai;
159  ESP_LOGCONFIG(TAG, "Setting up wk2168_spi: %s with %d UARTs...", this->get_name(), this->children_.size());
160  this->spi_setup();
161  // enable all channels
162  this->reg(WKREG_GENA, 0) = GENA_C1EN | GENA_C2EN | GENA_C3EN | GENA_C4EN;
163  // reset all channels
164  this->reg(WKREG_GRST, 0) = GRST_C1RST | GRST_C2RST | GRST_C3RST | GRST_C4RST;
165  // initialize the spage register to page 0
166  this->reg(WKREG_SPAGE, 0) = 0;
167  this->page1_ = false;
168 
169  // we setup our children channels
170  for (auto *child : this->children_) {
171  child->setup_channel();
172  }
173 }
174 
176  ESP_LOGCONFIG(TAG, "Initialization of %s with %d UARTs completed", this->get_name(), this->children_.size());
177  ESP_LOGCONFIG(TAG, " Crystal: %" PRIu32 "", this->crystal_);
178  if (test_mode_)
179  ESP_LOGCONFIG(TAG, " Test mode: %d", test_mode_);
180  ESP_LOGCONFIG(TAG, " Transfer buffer size: %d", XFER_MAX_SIZE);
181  LOG_PIN(" CS Pin: ", this->cs_);
182 
183  for (auto *child : this->children_) {
184  child->dump_channel();
185  }
186 }
187 
188 } // namespace weikai_spi
189 } // namespace esphome
constexpr uint8_t GRST_C2RST
Channel 2 soft reset (0: not reset, 1: reset)
Definition: wk_reg_def.h:60
constexpr uint8_t GRST_C4RST
Channel 4 soft reset (0: not reset, 1: reset)
Definition: wk_reg_def.h:56
constexpr uint8_t WKREG_GENA
Global Control Register - 00 0000.
Definition: wk_reg_def.h:32
const char * p2s(uart::UARTParityOptions parity)
Converts the parity enum value to a C string.
Definition: weikai_spi.cpp:32
constexpr uint8_t WKREG_GRST
Global Reset Register - 00 0001.
Definition: wk_reg_def.h:54
void write_fifo(uint8_t *data, size_t length) override
Definition: weikai_spi.cpp:139
constexpr uint8_t GENA_C2EN
Channel 2 enable clock (0: disable, 1: enable)
Definition: wk_reg_def.h:38
mopeka_std_values val[4]
void print_buffer(const uint8_t *data, size_t length)
Display a buffer in hexadecimal format (32 hex values / line).
Definition: weikai_spi.cpp:47
constexpr size_t XFER_MAX_SIZE
XFER_MAX_SIZE defines the maximum number of bytes allowed during one transfer.
Definition: weikai.h:34
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
The WeikaiComponentSPI class stores the information to the WeiKai component connected through an SPI ...
Definition: weikai_spi.h:36
void write_reg(uint8_t value) override
Definition: weikai_spi.cpp:129
const char * reg_to_str(int reg, bool page1)
Definition: weikai_spi.cpp:69
constexpr uint8_t GENA_C3EN
Channel 3 enable clock (0: disable, 1: enable)
Definition: wk_reg_def.h:36
constexpr uint8_t WKREG_GPDAT
Global GPIO data register - 11 0001.
Definition: wk_reg_def.h:99
constexpr uint8_t GRST_C1RST
Channel 1 soft reset (0: not reset, 1: reset)
Definition: wk_reg_def.h:62
std::string i2s(uint8_t val)
convert an int to binary representation as C++ std::string
Definition: weikai_spi.cpp:16
void read_fifo(uint8_t *data, size_t length) const override
Definition: weikai_spi.cpp:115
std::string to_string(int value)
Definition: helpers.cpp:82
uint16_t length
Definition: tt21100.cpp:12
constexpr uint8_t GRST_C3RST
Channel 3 soft reset (0: not reset, 1: reset)
Definition: wk_reg_def.h:58
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
constexpr uint8_t WKREG_SPAGE
Global Page register c0/c1 0011.
Definition: wk_reg_def.h:127
constexpr uint8_t WKREG_GPDIR
Global GPIO direction register - 10 0001.
Definition: wk_reg_def.h:85
constexpr uint8_t GENA_C1EN
Channel 1 enable clock (0: disable, 1: enable)
Definition: wk_reg_def.h:40
uint8_t read_reg() const override
Definition: weikai_spi.cpp:103
stm32_cmd_t * cmd
Definition: stm32flash.h:96
constexpr uint8_t GENA_C4EN
Channel 4 enable clock (0: disable, 1: enable)
Definition: wk_reg_def.h:34
uint32_t elapsed_ms(uint32_t &last_time)
measure the time elapsed between two calls
Definition: weikai_spi.cpp:23