11static const char *
const TAG =
"weikai";
16inline std::string
i2s(uint8_t
val) {
return std::bitset<8>(
val).to_string(); }
18#define I2S2CS(val) (i2s(val).c_str())
24 uint32_t e =
millis() - last_time;
35 case UART_CONFIG_PARITY_NONE:
37 case UART_CONFIG_PARITY_EVEN:
39 case UART_CONFIG_PARITY_ODD:
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]);
53 ESP_LOGVV(TAG,
" %s", hex_buffer);
58 hex_buffer[3 * (
length % 32) + 2] = 0;
59 ESP_LOGVV(TAG,
" %s", hex_buffer);
63static 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"};
65static 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"};
75 return page1 ? REG_TO_STR_P1[reg & 0x0F] : REG_TO_STR_P0[reg & 0x0F];
109 size_t transferred = 0;
112 transferred += child->xfer_fifo_to_buffer_();
114 if (transferred > 0) {
115 ESP_LOGV(TAG,
"we transferred %d bytes from fifo to buffer...", transferred);
119 static uint32_t loop_time = 0;
120 static uint32_t loop_count = 0;
124 ESP_LOGI(TAG,
"Component loop %" PRIu32
" for %s : %" PRIu32
" ms since last call ...", loop_count++,
129 for (
int i = 0; i < this->children_.size(); i++) {
130 if (i != ((loop_count - 1) % this->children_.size()))
132 snprintf(message,
sizeof(message),
"%s:%s", this->
get_name(), children_[i]->get_channel_name());
134 uint32_t
const start_time =
millis();
135 while (
children_[i]->tx_fifo_is_not_empty_()) {
136 if (
millis() - start_time > 1500) {
137 ESP_LOGE(TAG,
"timeout while flushing - %d bytes left in buffer...",
children_[i]->tx_in_fifo_());
143 ESP_LOGI(TAG,
"Test %s => send/received %u bytes %s - execution time %" PRIu32
" ms...", message,
149 for (
auto *child : this->children_) {
151 if (child->available()) {
152 child->read_byte(&data);
153 ESP_LOGI(TAG,
"echo mode: read -> send %02X", data);
154 child->write_byte(data);
168#if defined(TEST_COMPONENT)
170 static bool init_input{
false};
171 static uint8_t
state{0};
177 ESP_LOGI(TAG,
"initializing all pins to input mode");
179 ESP_LOGI(TAG,
"initial input data state = %02X (%s)",
state, I2S2CS(
state));
182 if (value !=
state) {
183 ESP_LOGI(TAG,
"Input data changed from %02X to %02X (%s)",
state, value, I2S2CS(value));
189 static bool init_output{
false};
190 static uint8_t
state{0};
195 ESP_LOGI(TAG,
"initializing all pins to output mode");
197 ESP_LOGI(TAG,
"setting all outputs to 0");
201 ESP_LOGI(TAG,
"Flipping all outputs to %02X (%s)",
state, I2S2CS(
state));
211 ESP_LOGVV(TAG,
"reading input pin %u = %u in_state %s", pin, this->
input_state_ & (1 << pin), I2S2CS(
input_state_));
221 ESP_LOGVV(TAG,
"writing output pin %d with %d out_state %s", pin, uint8_t(value), I2S2CS(this->
output_state_));
232 ESP_LOGE(TAG,
"pin %d direction invalid", pin);
235 ESP_LOGVV(TAG,
"setting pin %d direction to %d pin_config=%s", pin, flags, I2S2CS(this->
pin_config_));
240 ESP_LOGCONFIG(TAG,
"Setting GPIO pin %d mode to %s", this->
pin_,
250 snprintf(buffer,
sizeof(buffer),
"%u via WeiKai %s", this->
pin_, this->
parent_->
get_name());
258 ESP_LOGCONFIG(TAG,
" Setting up UART %s:%s ...", this->
parent_->
get_name(), this->get_channel_name());
261 ESP_LOGCONFIG(TAG,
" Error channel %s not working...", this->
get_channel_name());
271 ESP_LOGCONFIG(TAG,
" Baud rate: %" PRIu32
" Bd", this->
baud_rate_);
272 ESP_LOGCONFIG(TAG,
" Data bits: %u", this->
data_bits_);
273 ESP_LOGCONFIG(TAG,
" Stop bits: %u", this->
stop_bits_);
274 ESP_LOGCONFIG(TAG,
" Parity: %s",
p2s(this->
parity_));
300 ESP_LOGV(TAG,
" line config: %d data_bits, %d stop_bits, parity %s register [%s]", this->
data_bits_,
307 ESP_LOGE(TAG,
" Requested baudrate too high for crystal=%" PRIu32
" Hz. Has been reduced to %" PRIu32
" Bd",
312 uint8_t
const baud_high = (uint8_t) (val_int >> 8);
313 uint8_t
const baud_low = (uint8_t) (val_int & 0xFF);
314 while (val_dec > 0x0A)
316 uint8_t
const baud_dec = (uint8_t) (val_dec);
326 ESP_LOGV(TAG,
" Crystal=%" PRId32
" baudrate=%" PRId32
" => registers [%d %d %d]", this->
parent_->
crystal_,
327 this->baud_rate_, baud_high, baud_low, baud_dec);
337 ESP_LOGVV(TAG,
"tx FIFO full FSR=%s", I2S2CS(fsr));
341 ESP_LOGVV(TAG,
"tx FIFO contains %d bytes", tfcnt);
350 ESP_LOGE(TAG,
"Receive data overflow FSR=%s", I2S2CS(fsr));
352 ESP_LOGE(TAG,
"Receive line break FSR=%s", I2S2CS(fsr));
354 ESP_LOGE(TAG,
"Receive frame error FSR=%s", I2S2CS(fsr));
356 ESP_LOGE(TAG,
"Receive parity error FSR=%s", I2S2CS(fsr));
364 if (available == 0) {
365 ESP_LOGV(TAG,
"rx FIFO is full FSR=%s", I2S2CS(fsr));
369 ESP_LOGVV(TAG,
"rx FIFO contain %d bytes - FSR status=%s",
available, I2S2CS(fsr));
380 ESP_LOGE(TAG,
"R/W of register failed expected 0x3F received 0x%02X",
val);
386 ESP_LOGE(TAG,
"R/W of register failed expected 0x00 received 0x%02X",
val);
410 ESP_LOGW(TAG,
"read_array: buffer underflow requested %d bytes only %d bytes available...",
length,
available);
415 for (
size_t i = 0; i <
length; i++) {
418 ESP_LOGVV(TAG,
"read_array(ch=%d buffer[0]=%02X, length=%d): status %s", this->
channel_, *buffer,
length,
425 ESP_LOGE(TAG,
"Write_array: invalid call - requested %d bytes but max size %d ...",
length,
XFER_MAX_SIZE);
432 uint32_t
const start_time =
millis();
434 if (
millis() - start_time > 200) {
435 ESP_LOGW(TAG,
"WARNING flush timeout - still %d bytes not sent after 200 ms...", this->
tx_in_fifo_());
449 if (to_transfer > free)
452 uint8_t data[to_transfer];
454 for (
size_t i = 0; i < to_transfer; i++)
474 Increment() : i_(0) {}
478 uint8_t operator()() {
return i_++; }
487 char hex_buffer[100];
488 hex_buffer[(3 * 32) + 1] = 0;
489 for (
size_t i = 0; i < buffer.size(); i++) {
490 snprintf(&hex_buffer[3 * (i % 32)],
sizeof(hex_buffer),
"%02X ", buffer[i]);
492 ESP_LOGI(TAG,
" %s", hex_buffer);
494 if (buffer.size() % 32) {
496 hex_buffer[3 * (buffer.size() % 32) + 1] = 0;
497 ESP_LOGI(TAG,
" %s", hex_buffer);
503 auto start_exec =
micros();
505 generate(output_buffer.begin(), output_buffer.end(), Increment());
512 ESP_LOGV(TAG,
"%s => sent %d bytes - exec time %d µs ...", message,
RING_BUFFER_SIZE,
micros() - start_exec);
517 auto start_exec =
micros();
523 uint32_t
const start_time =
millis();
528 if (
millis() - start_time > 1500) {
529 ESP_LOGE(TAG,
"uart_receive_test_() timeout: only %d bytes received...", this->
available());
538 uint8_t peek_value = 0;
540 if (peek_value != 0) {
541 ESP_LOGE(TAG,
"Peek first byte value error...");
547 ESP_LOGE(TAG,
"Read buffer contains error...b=%x i=%x", buffer[i], i %
XFER_MAX_SIZE);
554 ESP_LOGV(TAG,
"%s => received %d bytes status %s - exec time %d µs ...", message, received,
status ?
"OK" :
"ERROR",
uint32_t component_state_
State of this component.
UARTParityOptions parity_
size_t free()
returns the number of free positions in the buffer
bool push(const T item)
pushes an item at the tail of the fifo
bool peek(T &item)
return the value of the item at fifo's head without removing it
void clear()
clear the buffer content
bool pop(T &item)
return and remove the item at head of the fifo
size_t count()
return the number of item in the ring buffer
virtual void dump_channel()
dump channel information
virtual void setup_channel()
Setup the channel.
WeikaiRegister & reg(uint8_t reg)
Factory method to create a WeikaiRegister proxy object.
void flush() override
Flush the output fifo.
void set_line_param_()
set the line parameters
void set_baudrate_()
set the baud rate
bool peek_byte(uint8_t *buffer) override
Reads the first byte in FIFO without removing it.
size_t xfer_fifo_to_buffer_()
transfer bytes from the weikai internal FIFO to the buffer (if any)
virtual bool check_channel_down()
check if channel is alive
const char * get_channel_name()
Get the channel name.
WeikaiComponent * parent_
our WK2168component parent
WKRingBuffer< uint8_t, RING_BUFFER_SIZE > receive_buffer_
the buffer where we store temporarily the bytes received
bool read_array(uint8_t *buffer, size_t length) override
Reads a specified number of bytes from a serial port.
void reset_fifo_()
reset the weikai internal FIFO
bool tx_fifo_is_not_empty_()
test if transmit buffer is not empty in the status register (optimization)
uint8_t channel_
our Channel number
size_t rx_in_fifo_()
Returns the number of bytes in the receive fifo.
int available() override
Returns the number of bytes in the receive buffer.
size_t tx_in_fifo_()
Returns the number of bytes in the transmit fifo.
void write_array(const uint8_t *buffer, size_t length) override
Writes a specified number of bytes to a serial port.
int test_mode_
test mode value (0 -> no tests)
virtual WeikaiRegister & reg(uint8_t reg, uint8_t channel)=0
Factory method to create a Register object.
uint8_t input_state_
input pin states: 1 means HIGH, 0 means LOW
uint32_t crystal_
crystal value;
void write_pin_val_(uint8_t pin, bool value)
Helper method to write the value of a pin.
bool read_pin_val_(uint8_t pin)
Helper method to read the value of a pin.
uint8_t output_state_
output state: 1 means HIGH, 0 means LOW
bool page1_
set to true when in "page1 mode"
std::vector< WeikaiChannel * > children_
the list of WeikaiChannel UART children
void loop() override
override the Component loop()
void set_pin_direction_(uint8_t pin, gpio::Flags flags)
Helper method to set the pin mode of a pin.
uint8_t pin_config_
pin config mask: 1 means OUTPUT, 0 means INPUT
const char * get_name()
Get the name of the component.
void pin_mode(gpio::Flags flags) override
std::string dump_summary() const override
WeikaiComponent * parent_
WeikaiRegister objects acts as proxies to access remote register independently of the bus type.
virtual void write_reg(uint8_t value)=0
writes the register
WeikaiRegister & operator|=(uint8_t value)
overloads the compound |= operator.
WeikaiRegister & operator&=(uint8_t value)
overloads the compound &= operator.
virtual void write_fifo(uint8_t *data, size_t length)=0
write an array of bytes to the transmitter fifo
WeikaiRegister & operator=(uint8_t value)
overloads the = operator.
virtual uint8_t read_reg() const =0
reads the register
virtual void read_fifo(uint8_t *data, size_t length) const =0
read an array of bytes from the receiver fifo
constexpr uint8_t FSR_TFDAT
Transmitter FIFO count (0: empty, 1: not empty)
constexpr uint8_t FCR_RFRST
Receiver FIFO reset.
constexpr uint8_t FSR_RFPE
Receiver Parity Error (0: no PE, 1: PE)
constexpr uint8_t WKREG_RFCNT
Receiver FIFO count - c0/c1 1010.
constexpr uint8_t SCR_RXEN
receiving control (0: enable, 1: disable)
constexpr uint8_t WKREG_FCR
FIFO Control Register - c0/c1 0110.
constexpr uint8_t LCR_STPL
Stop length (0: 1 bit, 1: 2 bits)
constexpr uint8_t FCR_TFRST
Transmitter FIFO reset.
constexpr uint8_t SCR_TXEN
transmission control (0: enable, 1: disable)
constexpr uint8_t FCR_TFEN
Transmitter FIFO enable.
constexpr uint8_t FSR_RFOE
Receiver FIFO Overflow Error (0: no OE, 1: OE)
constexpr uint8_t WKREG_FSR
FIFO Status Register - c0/c1 1011.
constexpr uint8_t FCR_RFEN
Receiver FIFO enable.
constexpr uint8_t FSR_RFFE
Receiver FIFO Frame Error (0: no FE, 1: FE)
constexpr uint8_t LCR_PAR_ODD
Parity odd.
constexpr uint8_t FSR_RFDAT
Receiver FIFO count (0: empty, 1: not empty)
constexpr uint8_t WKREG_TFCNT
Transmitter FIFO Count - c0/c1 1001.
constexpr uint8_t FSR_TFFULL
Transmitter FIFO full (0: not full, 1: full)
constexpr uint8_t WKREG_LCR
Line Configuration Register - c0/c1 0101.
constexpr uint8_t WKREG_SCR
Serial Control Register - c0/c1 0100.
constexpr uint8_t FSR_RFLB
Receiver FIFO Line Break (0: no LB, 1: LB)
constexpr uint8_t LCR_PAR_EVEN
Parity even.
constexpr uint8_t LCR_PAEN
Parity enable (0: no check, 1: check)
constexpr uint8_t WKREG_SPAGE
Global Page register c0/c1 0011.
constexpr uint8_t WKREG_BRH
Baud rate configuration register: high byte - c0/c1 0100.
constexpr uint8_t WKREG_BRL
Baud rate configuration register: low byte - c0/c1 0101.
constexpr uint8_t WKREG_BRD
Baud rate configuration register decimal part - c0/c1 0110.
bool uart_receive_test_(char *message)
Test the read_array() method.
void uart_send_test_(char *message)
Test the write_array() method.
constexpr uint8_t WKREG_GPDIR
Global GPIO direction register - 10 0001.
constexpr uint8_t WKREG_GPDAT
Global GPIO data register - 11 0001.
@ UART_CONFIG_PARITY_EVEN
constexpr size_t XFER_MAX_SIZE
XFER_MAX_SIZE defines the maximum number of bytes allowed during one transfer.
constexpr size_t RING_BUFFER_SIZE
size of the ring buffer set to size of the FIFO
const char * reg_to_str(int reg, bool page1)
const char * p2s(uart::UARTParityOptions parity)
Converts the parity enum value to a C string.
constexpr size_t FIFO_SIZE
size of the internal WeiKai FIFO
std::string i2s(uint8_t val)
convert an int to binary representation as C++ std::string
void print_buffer(const uint8_t *data, size_t length)
Display a buffer in hexadecimal format (32 hex values / line) for debug.
uint32_t elapsed_ms(uint32_t &last_time)
measure the time elapsed between two calls
Providing packet encoding functions for exchanging data with a remote host.
const uint32_t COMPONENT_STATE_MASK
const uint32_t COMPONENT_STATE_LOOP
void IRAM_ATTR HOT yield()
uint32_t IRAM_ATTR HOT micros()
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
WeiKai component family - classes declaration.