ESPHome  2024.11.1
weikai.cpp
Go to the documentation of this file.
1 
6 #include "weikai.h"
7 
8 namespace esphome {
9 namespace weikai {
10 
63 static const char *const TAG = "weikai";
64 
68 inline std::string i2s(uint8_t val) { return std::bitset<8>(val).to_string(); }
70 #define I2S2CS(val) (i2s(val).c_str())
71 
75 uint32_t elapsed_ms(uint32_t &last_time) {
76  uint32_t e = millis() - last_time;
77  last_time = millis();
78  return e;
79 };
80 
84 const char *p2s(uart::UARTParityOptions parity) {
85  using namespace uart;
86  switch (parity) {
88  return "NONE";
90  return "EVEN";
92  return "ODD";
93  default:
94  return "UNKNOWN";
95  }
96 }
97 
99 void print_buffer(const uint8_t *data, size_t length) {
100  char hex_buffer[100];
101  hex_buffer[(3 * 32) + 1] = 0;
102  for (size_t i = 0; i < length; i++) {
103  snprintf(&hex_buffer[3 * (i % 32)], sizeof(hex_buffer), "%02X ", data[i]);
104  if (i % 32 == 31) {
105  ESP_LOGVV(TAG, " %s", hex_buffer);
106  }
107  }
108  if (length % 32) {
109  // null terminate if incomplete line
110  hex_buffer[3 * (length % 32) + 2] = 0;
111  ESP_LOGVV(TAG, " %s", hex_buffer);
112  }
113 }
114 
115 static const char *const REG_TO_STR_P0[16] = {"GENA", "GRST", "GMUT", "SPAGE", "SCR", "LCR", "FCR", "SIER",
116  "SIFR", "TFCNT", "RFCNT", "FSR", "LSR", "FDAT", "FWCR", "RS485"};
117 static const char *const REG_TO_STR_P1[16] = {"GENA", "GRST", "GMUT", "SPAGE", "BAUD1", "BAUD0", "PRES", "RFTL",
118  "TFTL", "FWTH", "FWTL", "XON1", "XOFF1", "SADR", "SAEN", "RTSDLY"};
119 
120 // method to print a register value as text: used in the log messages ...
121 const char *reg_to_str(int reg, bool page1) {
122  if (reg == WKREG_GPDAT) {
123  return "GPDAT";
124  } else if (reg == WKREG_GPDIR) {
125  return "GPDIR";
126  } else {
127  return page1 ? REG_TO_STR_P1[reg & 0x0F] : REG_TO_STR_P0[reg & 0x0F];
128  }
129 }
130 
131 enum RegType { REG = 0, FIFO = 1 };
132 
134 // The WeikaiRegister methods
137  write_reg(value);
138  return *this;
139 }
140 
142  value &= read_reg();
143  write_reg(value);
144  return *this;
145 }
146 
148  value |= read_reg();
149  write_reg(value);
150  return *this;
151 }
152 
154 // The WeikaiComponent methods
157  if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP)
158  return;
159 
160  // If there are some bytes in the receive FIFO we transfers them to the ring buffers
161  size_t transferred = 0;
162  for (auto *child : this->children_) {
163  // we look if some characters has been received in the fifo
164  transferred += child->xfer_fifo_to_buffer_();
165  }
166  if (transferred > 0) {
167  ESP_LOGV(TAG, "we transferred %d bytes from fifo to buffer...", transferred);
168  }
169 
170 #ifdef TEST_COMPONENT
171  static uint32_t loop_time = 0;
172  static uint32_t loop_count = 0;
173  uint32_t time = 0;
174 
175  if (test_mode_ == 1) { // test component in loopback
176  ESP_LOGI(TAG, "Component loop %" PRIu32 " for %s : %" PRIu32 " ms since last call ...", loop_count++,
177  this->get_name(), millis() - loop_time);
178  loop_time = millis();
179  char message[64];
180  elapsed_ms(time); // set time to now
181  for (int i = 0; i < this->children_.size(); i++) {
182  if (i != ((loop_count - 1) % this->children_.size())) // we do only one per loop
183  continue;
184  snprintf(message, sizeof(message), "%s:%s", this->get_name(), children_[i]->get_channel_name());
185  children_[i]->uart_send_test_(message);
186  uint32_t const start_time = millis();
187  while (children_[i]->tx_fifo_is_not_empty_()) { // wait until buffer empty
188  if (millis() - start_time > 1500) {
189  ESP_LOGE(TAG, "timeout while flushing - %d bytes left in buffer...", children_[i]->tx_in_fifo_());
190  break;
191  }
192  yield(); // reschedule our thread to avoid blocking
193  }
194  bool status = children_[i]->uart_receive_test_(message);
195  ESP_LOGI(TAG, "Test %s => send/received %u bytes %s - execution time %" PRIu32 " ms...", message,
196  RING_BUFFER_SIZE, status ? "correctly" : "with error", elapsed_ms(time));
197  }
198  }
199 
200  if (this->test_mode_ == 2) { // test component in echo mode
201  for (auto *child : this->children_) {
202  uint8_t data = 0;
203  if (child->available()) {
204  child->read_byte(&data);
205  ESP_LOGI(TAG, "echo mode: read -> send %02X", data);
206  child->write_byte(data);
207  }
208  }
209  }
210  if (test_mode_ == 3) {
211  test_gpio_input_();
212  }
213 
214  if (test_mode_ == 4) {
215  test_gpio_output_();
216  }
217 #endif
218 }
219 
220 #if defined(TEST_COMPONENT)
222  static bool init_input{false};
223  static uint8_t state{0};
224  uint8_t value;
225  if (!init_input) {
226  init_input = true;
227  // set all pins in input mode
228  this->reg(WKREG_GPDIR, 0) = 0x00;
229  ESP_LOGI(TAG, "initializing all pins to input mode");
230  state = this->reg(WKREG_GPDAT, 0);
231  ESP_LOGI(TAG, "initial input data state = %02X (%s)", state, I2S2CS(state));
232  }
233  value = this->reg(WKREG_GPDAT, 0);
234  if (value != state) {
235  ESP_LOGI(TAG, "Input data changed from %02X to %02X (%s)", state, value, I2S2CS(value));
236  state = value;
237  }
238 }
239 
241  static bool init_output{false};
242  static uint8_t state{0};
243  if (!init_output) {
244  init_output = true;
245  // set all pins in output mode
246  this->reg(WKREG_GPDIR, 0) = 0xFF;
247  ESP_LOGI(TAG, "initializing all pins to output mode");
248  this->reg(WKREG_GPDAT, 0) = state;
249  ESP_LOGI(TAG, "setting all outputs to 0");
250  }
251  state = ~state;
252  this->reg(WKREG_GPDAT, 0) = state;
253  ESP_LOGI(TAG, "Flipping all outputs to %02X (%s)", state, I2S2CS(state));
254  delay(100); // NOLINT
255 }
256 #endif
257 
259 // The WeikaiGPIOPin methods
262  this->input_state_ = this->reg(WKREG_GPDAT, 0);
263  ESP_LOGVV(TAG, "reading input pin %u = %u in_state %s", pin, this->input_state_ & (1 << pin), I2S2CS(input_state_));
264  return this->input_state_ & (1 << pin);
265 }
266 
267 void WeikaiComponent::write_pin_val_(uint8_t pin, bool value) {
268  if (value) {
269  this->output_state_ |= (1 << pin);
270  } else {
271  this->output_state_ &= ~(1 << pin);
272  }
273  ESP_LOGVV(TAG, "writing output pin %d with %d out_state %s", pin, uint8_t(value), I2S2CS(this->output_state_));
274  this->reg(WKREG_GPDAT, 0) = this->output_state_;
275 }
276 
278  if (flags == gpio::FLAG_INPUT) {
279  this->pin_config_ &= ~(1 << pin); // clear bit (input mode)
280  } else {
281  if (flags == gpio::FLAG_OUTPUT) {
282  this->pin_config_ |= 1 << pin; // set bit (output mode)
283  } else {
284  ESP_LOGE(TAG, "pin %d direction invalid", pin);
285  }
286  }
287  ESP_LOGVV(TAG, "setting pin %d direction to %d pin_config=%s", pin, flags, I2S2CS(this->pin_config_));
288  this->reg(WKREG_GPDIR, 0) = this->pin_config_; // TODO check ~
289 }
290 
292  ESP_LOGCONFIG(TAG, "Setting GPIO pin %d mode to %s", this->pin_,
293  flags_ == gpio::FLAG_INPUT ? "Input"
294  : this->flags_ == gpio::FLAG_OUTPUT ? "Output"
295  : "NOT SPECIFIED");
296  // ESP_LOGCONFIG(TAG, "Setting GPIO pins mode to '%s' %02X", I2S2CS(this->flags_), this->flags_);
297  this->pin_mode(this->flags_);
298 }
299 
300 std::string WeikaiGPIOPin::dump_summary() const {
301  char buffer[32];
302  snprintf(buffer, sizeof(buffer), "%u via WeiKai %s", this->pin_, this->parent_->get_name());
303  return buffer;
304 }
305 
307 // The WeikaiChannel methods
310  ESP_LOGCONFIG(TAG, " Setting up UART %s:%s ...", this->parent_->get_name(), this->get_channel_name());
311  // we enable transmit and receive on this channel
312  if (this->check_channel_down()) {
313  ESP_LOGCONFIG(TAG, " Error channel %s not working...", this->get_channel_name());
314  }
315  this->reset_fifo_();
316  this->receive_buffer_.clear();
317  this->set_line_param_();
318  this->set_baudrate_();
319 }
320 
322  ESP_LOGCONFIG(TAG, " UART %s ...", this->get_channel_name());
323  ESP_LOGCONFIG(TAG, " Baud rate: %" PRIu32 " Bd", this->baud_rate_);
324  ESP_LOGCONFIG(TAG, " Data bits: %u", this->data_bits_);
325  ESP_LOGCONFIG(TAG, " Stop bits: %u", this->stop_bits_);
326  ESP_LOGCONFIG(TAG, " Parity: %s", p2s(this->parity_));
327 }
328 
330  // enable transmission and reception
331  this->reg(WKREG_SCR) = SCR_RXEN | SCR_TXEN;
332  // we reset and enable transmit and receive FIFO
333  this->reg(WKREG_FCR) = FCR_TFEN | FCR_RFEN | FCR_TFRST | FCR_RFRST;
334 }
335 
337  this->data_bits_ = 8; // always equal to 8 for WeiKai (cant be changed)
338  uint8_t lcr = 0;
339  if (this->stop_bits_ == 2)
340  lcr |= LCR_STPL;
341  switch (this->parity_) { // parity selection settings
343  lcr |= (LCR_PAEN | LCR_PAR_ODD);
344  break;
346  lcr |= (LCR_PAEN | LCR_PAR_EVEN);
347  break;
348  default:
349  break; // no parity 000x
350  }
351  this->reg(WKREG_LCR) = lcr; // write LCR
352  ESP_LOGV(TAG, " line config: %d data_bits, %d stop_bits, parity %s register [%s]", this->data_bits_,
353  this->stop_bits_, p2s(this->parity_), I2S2CS(lcr));
354 }
355 
357  if (this->baud_rate_ > this->parent_->crystal_ / 16) {
358  baud_rate_ = this->parent_->crystal_ / 16;
359  ESP_LOGE(TAG, " Requested baudrate too high for crystal=%" PRIu32 " Hz. Has been reduced to %" PRIu32 " Bd",
360  this->parent_->crystal_, this->baud_rate_);
361  };
362  uint16_t const val_int = this->parent_->crystal_ / (this->baud_rate_ * 16) - 1;
363  uint16_t val_dec = (this->parent_->crystal_ % (this->baud_rate_ * 16)) / (this->baud_rate_ * 16);
364  uint8_t const baud_high = (uint8_t) (val_int >> 8);
365  uint8_t const baud_low = (uint8_t) (val_int & 0xFF);
366  while (val_dec > 0x0A)
367  val_dec /= 0x0A;
368  uint8_t const baud_dec = (uint8_t) (val_dec);
369 
370  this->parent_->page1_ = true; // switch to page 1
371  this->reg(WKREG_SPAGE) = 1;
372  this->reg(WKREG_BRH) = baud_high;
373  this->reg(WKREG_BRL) = baud_low;
374  this->reg(WKREG_BRD) = baud_dec;
375  this->parent_->page1_ = false; // switch back to page 0
376  this->reg(WKREG_SPAGE) = 0;
377 
378  ESP_LOGV(TAG, " Crystal=%" PRId32 " baudrate=%" PRId32 " => registers [%d %d %d]", this->parent_->crystal_,
379  this->baud_rate_, baud_high, baud_low, baud_dec);
380 }
381 
382 inline bool WeikaiChannel::tx_fifo_is_not_empty_() { return this->reg(WKREG_FSR) & FSR_TFDAT; }
383 
385  size_t tfcnt = this->reg(WKREG_TFCNT);
386  if (tfcnt == 0) {
387  uint8_t const fsr = this->reg(WKREG_FSR);
388  if (fsr & FSR_TFFULL) {
389  ESP_LOGVV(TAG, "tx FIFO full FSR=%s", I2S2CS(fsr));
390  tfcnt = FIFO_SIZE;
391  }
392  }
393  ESP_LOGVV(TAG, "tx FIFO contains %d bytes", tfcnt);
394  return tfcnt;
395 }
396 
398  size_t available = this->reg(WKREG_RFCNT);
399  uint8_t const fsr = this->reg(WKREG_FSR);
400  if (fsr & (FSR_RFOE | FSR_RFLB | FSR_RFFE | FSR_RFPE)) {
401  if (fsr & FSR_RFOE)
402  ESP_LOGE(TAG, "Receive data overflow FSR=%s", I2S2CS(fsr));
403  if (fsr & FSR_RFLB)
404  ESP_LOGE(TAG, "Receive line break FSR=%s", I2S2CS(fsr));
405  if (fsr & FSR_RFFE)
406  ESP_LOGE(TAG, "Receive frame error FSR=%s", I2S2CS(fsr));
407  if (fsr & FSR_RFPE)
408  ESP_LOGE(TAG, "Receive parity error FSR=%s", I2S2CS(fsr));
409  }
410  if ((available == 0) && (fsr & FSR_RFDAT)) {
411  // here we should be very careful because we can have something like this:
412  // - at time t0 we read RFCNT=0 because nothing yet received
413  // - at time t0+delta we might read FIFO not empty because one byte has just been received
414  // - so to be sure we need to do another read of RFCNT and if it is still zero -> buffer full
415  available = this->reg(WKREG_RFCNT);
416  if (available == 0) { // still zero ?
417  ESP_LOGV(TAG, "rx FIFO is full FSR=%s", I2S2CS(fsr));
418  available = FIFO_SIZE;
419  }
420  }
421  ESP_LOGVV(TAG, "rx FIFO contain %d bytes - FSR status=%s", available, I2S2CS(fsr));
422  return available;
423 }
424 
426  // to check if we channel is up we write to the LCR W/R register
427  // note that this will put a break on the tx line for few ms
428  WeikaiRegister &lcr = this->reg(WKREG_LCR);
429  lcr = 0x3F;
430  uint8_t val = lcr;
431  if (val != 0x3F) {
432  ESP_LOGE(TAG, "R/W of register failed expected 0x3F received 0x%02X", val);
433  return true;
434  }
435  lcr = 0;
436  val = lcr;
437  if (val != 0x00) {
438  ESP_LOGE(TAG, "R/W of register failed expected 0x00 received 0x%02X", val);
439  return true;
440  }
441  return false;
442 }
443 
444 bool WeikaiChannel::peek_byte(uint8_t *buffer) {
445  auto available = this->receive_buffer_.count();
446  if (!available)
447  xfer_fifo_to_buffer_();
448  return this->receive_buffer_.peek(*buffer);
449 }
450 
452  size_t available = this->receive_buffer_.count();
453  if (!available)
454  available = xfer_fifo_to_buffer_();
455  return available;
456 }
457 
458 bool WeikaiChannel::read_array(uint8_t *buffer, size_t length) {
459  bool status = true;
460  auto available = this->receive_buffer_.count();
461  if (length > available) {
462  ESP_LOGW(TAG, "read_array: buffer underflow requested %d bytes only %d bytes available...", length, available);
463  length = available;
464  status = false;
465  }
466  // retrieve the bytes from ring buffer
467  for (size_t i = 0; i < length; i++) {
468  this->receive_buffer_.pop(buffer[i]);
469  }
470  ESP_LOGVV(TAG, "read_array(ch=%d buffer[0]=%02X, length=%d): status %s", this->channel_, *buffer, length,
471  status ? "OK" : "ERROR");
472  return status;
473 }
474 
475 void WeikaiChannel::write_array(const uint8_t *buffer, size_t length) {
476  if (length > XFER_MAX_SIZE) {
477  ESP_LOGE(TAG, "Write_array: invalid call - requested %d bytes but max size %d ...", length, XFER_MAX_SIZE);
478  length = XFER_MAX_SIZE;
479  }
480  this->reg(0).write_fifo(const_cast<uint8_t *>(buffer), length);
481 }
482 
484  uint32_t const start_time = millis();
485  while (this->tx_fifo_is_not_empty_()) { // wait until buffer empty
486  if (millis() - start_time > 200) {
487  ESP_LOGW(TAG, "WARNING flush timeout - still %d bytes not sent after 200 ms...", this->tx_in_fifo_());
488  return;
489  }
490  yield(); // reschedule our thread to avoid blocking
491  }
492 }
493 
495  size_t to_transfer;
496  size_t free;
497  while ((to_transfer = this->rx_in_fifo_()) && (free = this->receive_buffer_.free())) {
498  // while bytes in fifo and some room in the buffer we transfer
499  if (to_transfer > XFER_MAX_SIZE)
500  to_transfer = XFER_MAX_SIZE; // we can only do so much
501  if (to_transfer > free)
502  to_transfer = free; // we'll do the rest next time
503  if (to_transfer) {
504  uint8_t data[to_transfer];
505  this->reg(0).read_fifo(data, to_transfer);
506  for (size_t i = 0; i < to_transfer; i++)
507  this->receive_buffer_.push(data[i]);
508  }
509  } // while work to do
510  return to_transfer;
511 }
512 
514 // TEST COMPONENT
515 //
516 #ifdef TEST_COMPONENT
517 
523 class Increment {
524  public:
526  Increment() : i_(0) {}
530  uint8_t operator()() { return i_++; }
531 
532  private:
533  uint8_t i_;
534 };
535 
538 void print_buffer(std::vector<uint8_t> buffer) {
539  char hex_buffer[100];
540  hex_buffer[(3 * 32) + 1] = 0;
541  for (size_t i = 0; i < buffer.size(); i++) {
542  snprintf(&hex_buffer[3 * (i % 32)], sizeof(hex_buffer), "%02X ", buffer[i]);
543  if (i % 32 == 31)
544  ESP_LOGI(TAG, " %s", hex_buffer);
545  }
546  if (buffer.size() % 32) {
547  // null terminate if incomplete line
548  hex_buffer[3 * (buffer.size() % 32) + 1] = 0;
549  ESP_LOGI(TAG, " %s", hex_buffer);
550  }
551 }
552 
554 void WeikaiChannel::uart_send_test_(char *message) {
555  auto start_exec = micros();
556  std::vector<uint8_t> output_buffer(XFER_MAX_SIZE);
557  generate(output_buffer.begin(), output_buffer.end(), Increment()); // fill with incrementing number
558  size_t to_send = RING_BUFFER_SIZE;
559  while (to_send) {
560  this->write_array(&output_buffer[0], XFER_MAX_SIZE); // we send the buffer
561  this->flush();
562  to_send -= XFER_MAX_SIZE;
563  }
564  ESP_LOGV(TAG, "%s => sent %d bytes - exec time %d µs ...", message, RING_BUFFER_SIZE, micros() - start_exec);
565 }
566 
569  auto start_exec = micros();
570  bool status = true;
571  size_t received = 0;
572  std::vector<uint8_t> buffer(RING_BUFFER_SIZE);
573 
574  // we wait until we have received all the bytes
575  uint32_t const start_time = millis();
576  status = true;
577  while (received < RING_BUFFER_SIZE) {
578  while (XFER_MAX_SIZE > this->available()) {
579  this->xfer_fifo_to_buffer_();
580  if (millis() - start_time > 1500) {
581  ESP_LOGE(TAG, "uart_receive_test_() timeout: only %d bytes received...", this->available());
582  break;
583  }
584  yield(); // reschedule our thread to avoid blocking
585  }
586  status = this->read_array(&buffer[received], XFER_MAX_SIZE) && status;
587  received += XFER_MAX_SIZE;
588  }
589 
590  uint8_t peek_value = 0;
591  this->peek_byte(&peek_value);
592  if (peek_value != 0) {
593  ESP_LOGE(TAG, "Peek first byte value error...");
594  status = false;
595  }
596 
597  for (size_t i = 0; i < RING_BUFFER_SIZE; i++) {
598  if (buffer[i] != i % XFER_MAX_SIZE) {
599  ESP_LOGE(TAG, "Read buffer contains error...b=%x i=%x", buffer[i], i % XFER_MAX_SIZE);
600  print_buffer(buffer);
601  status = false;
602  break;
603  }
604  }
605 
606  ESP_LOGV(TAG, "%s => received %d bytes status %s - exec time %d µs ...", message, received, status ? "OK" : "ERROR",
607  micros() - start_exec);
608  return status;
609 }
610 
612 #endif
613 
614 } // namespace weikai
615 } // namespace esphome
constexpr uint8_t LCR_PAR_ODD
Parity odd.
Definition: wk_reg_def.h:165
const uint32_t COMPONENT_STATE_LOOP
Definition: component.cpp:35
constexpr uint8_t WKREG_SCR
Serial Control Register - c0/c1 0100.
Definition: wk_reg_def.h:141
int available() override
Returns the number of bytes in the receive buffer.
Definition: weikai.cpp:451
constexpr uint8_t FCR_TFRST
Transmitter FIFO reset.
Definition: wk_reg_def.h:191
const char * p2s(uart::UARTParityOptions parity)
Converts the parity enum value to a C string.
Definition: weikai.cpp:84
constexpr uint8_t WKREG_BRL
Baud rate configuration register: low byte - c0/c1 0101.
Definition: wk_reg_def.h:290
size_t tx_in_fifo_()
Returns the number of bytes in the transmit fifo.
Definition: weikai.cpp:384
void uart_send_test_(char *message)
Test the write_array() method.
Definition: weikai.cpp:554
void set_baudrate_()
set the baud rate
Definition: weikai.cpp:356
void loop() override
override the Component loop()
Definition: weikai.cpp:156
void write_pin_val_(uint8_t pin, bool value)
Helper method to write the value of a pin.
Definition: weikai.cpp:267
size_t rx_in_fifo_()
Returns the number of bytes in the receive fifo.
Definition: weikai.cpp:397
constexpr uint8_t FSR_RFDAT
Receiver FIFO count (0: empty, 1: not empty)
Definition: wk_reg_def.h:251
virtual void dump_channel()
dump channel information
Definition: weikai.cpp:321
constexpr uint8_t WKREG_BRH
Baud rate configuration register: high byte - c0/c1 0100.
Definition: wk_reg_def.h:280
void set_line_param_()
set the line parameters
Definition: weikai.cpp:336
constexpr uint8_t FSR_TFFULL
Transmitter FIFO full (0: not full, 1: full)
Definition: wk_reg_def.h:255
mopeka_std_values val[4]
WeikaiRegister & operator &=(uint8_t value)
overloads the compound &= operator.
uint32_t elapsed_ms(uint32_t &last_time)
measure the time elapsed between two calls
Definition: weikai.cpp:75
const char * reg_to_str(int reg, bool page1)
Definition: weikai.cpp:121
constexpr uint8_t LCR_PAEN
Parity enable (0: no check, 1: check)
Definition: wk_reg_def.h:161
void reset_fifo_()
reset the weikai internal FIFO
Definition: weikai.cpp:329
uint32_t IRAM_ATTR HOT micros()
Definition: core.cpp:27
bool peek_byte(uint8_t *buffer) override
Reads the first byte in FIFO without removing it.
Definition: weikai.cpp:444
constexpr size_t XFER_MAX_SIZE
XFER_MAX_SIZE defines the maximum number of bytes allowed during one transfer.
Definition: weikai.h:34
constexpr uint8_t WKREG_FCR
FIFO Control Register - c0/c1 0110.
Definition: wk_reg_def.h:185
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
constexpr uint8_t WKREG_FSR
FIFO Status Register - c0/c1 1011.
Definition: wk_reg_def.h:241
void set_pin_direction_(uint8_t pin, gpio::Flags flags)
Helper method to set the pin mode of a pin.
Definition: weikai.cpp:277
constexpr uint8_t SCR_TXEN
transmission control (0: enable, 1: disable)
Definition: wk_reg_def.h:143
constexpr uint8_t FSR_RFLB
Receiver FIFO Line Break (0: no LB, 1: LB)
Definition: wk_reg_def.h:245
constexpr uint8_t FSR_TFDAT
Transmitter FIFO count (0: empty, 1: not empty)
Definition: wk_reg_def.h:253
std::string i2s(uint8_t val)
convert an int to binary representation as C++ std::string
Definition: weikai.cpp:68
constexpr uint8_t FSR_RFPE
Receiver Parity Error (0: no PE, 1: PE)
Definition: wk_reg_def.h:249
constexpr uint8_t LCR_STPL
Stop length (0: 1 bit, 1: 2 bits)
Definition: wk_reg_def.h:171
void write_array(const uint8_t *buffer, size_t length) override
Writes a specified number of bytes to a serial port.
Definition: weikai.cpp:475
bool uart_receive_test_(char *message)
Test the read_array() method.
Definition: weikai.cpp:568
void flush() override
Flush the output fifo.
Definition: weikai.cpp:483
std::string dump_summary() const override
Definition: weikai.cpp:300
constexpr uint8_t WKREG_BRD
Baud rate configuration register decimal part - c0/c1 0110.
Definition: wk_reg_def.h:293
bool read_array(uint8_t *buffer, size_t length) override
Reads a specified number of bytes from a serial port.
Definition: weikai.cpp:458
constexpr uint8_t LCR_PAR_EVEN
Parity even.
Definition: wk_reg_def.h:167
constexpr uint8_t FCR_RFEN
Receiver FIFO enable.
Definition: wk_reg_def.h:189
constexpr uint8_t FSR_RFOE
Receiver FIFO Overflow Error (0: no OE, 1: OE)
Definition: wk_reg_def.h:243
WeikaiRegister & operator|=(uint8_t value)
overloads the compound |= operator.
Definition: weikai.cpp:147
WeiKai component family - classes declaration.
constexpr uint8_t WKREG_GPDAT
Global GPIO data register - 11 0001.
Definition: wk_reg_def.h:99
const uint32_t COMPONENT_STATE_MASK
Definition: component.cpp:32
size_t xfer_fifo_to_buffer_()
transfer bytes from the weikai internal FIFO to the buffer (if any)
Definition: weikai.cpp:494
const uint32_t flags
Definition: stm32flash.h:85
constexpr uint8_t FCR_TFEN
Transmitter FIFO enable.
Definition: wk_reg_def.h:187
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:99
constexpr uint8_t WKREG_RFCNT
Receiver FIFO count - c0/c1 1010.
Definition: wk_reg_def.h:219
constexpr size_t RING_BUFFER_SIZE
size of the ring buffer set to size of the FIFO
Definition: weikai.h:43
uint8_t status
Definition: bl0942.h:74
virtual void setup_channel()
Setup the channel.
Definition: weikai.cpp:309
WeikaiRegister objects acts as proxies to access remote register independently of the bus type...
Definition: weikai.h:139
std::string to_string(int value)
Definition: helpers.cpp:81
void IRAM_ATTR HOT yield()
Definition: core.cpp:24
virtual bool check_channel_down()
check if channel is alive
Definition: weikai.cpp:425
constexpr uint8_t SCR_RXEN
receiving control (0: enable, 1: disable)
Definition: wk_reg_def.h:145
uint16_t length
Definition: tt21100.cpp:12
constexpr uint8_t WKREG_TFCNT
Transmitter FIFO Count - c0/c1 1001.
Definition: wk_reg_def.h:209
WeikaiRegister & operator=(uint8_t value)
overloads the = operator.
Definition: weikai.cpp:136
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
constexpr size_t FIFO_SIZE
size of the internal WeiKai FIFO
Definition: weikai.h:40
constexpr uint8_t FCR_RFRST
Receiver FIFO reset.
Definition: wk_reg_def.h:193
constexpr uint8_t WKREG_SPAGE
Global Page register c0/c1 0011.
Definition: wk_reg_def.h:127
bool read_pin_val_(uint8_t pin)
Helper method to read the value of a pin.
Definition: weikai.cpp:261
bool tx_fifo_is_not_empty_()
test if transmit buffer is not empty in the status register (optimization)
Definition: weikai.cpp:382
constexpr uint8_t WKREG_GPDIR
Global GPIO direction register - 10 0001.
Definition: wk_reg_def.h:85
constexpr uint8_t FSR_RFFE
Receiver FIFO Frame Error (0: no FE, 1: FE)
Definition: wk_reg_def.h:247
bool state
Definition: fan.h:34
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
constexpr uint8_t WKREG_LCR
Line Configuration Register - c0/c1 0101.
Definition: wk_reg_def.h:159