ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
uart_transport.cpp
Go to the documentation of this file.
1#include "esphome/core/log.h"
3#include "uart_transport.h"
4
5namespace esphome::uart {
6
7ESPHOME_LOG_TAG(TAG, "uart_transport");
8
9static constexpr uint16_t MAX_PACKET_SIZE = 508;
10static constexpr uint8_t FLAG_BYTE = 0x7E;
11static constexpr uint8_t CONTROL_BYTE = 0x7D;
12
14 PacketTransport::loop();
15
16 while (this->parent_->available()) {
17 uint8_t byte;
18 if (!this->parent_->read_byte(&byte)) {
19 ESP_LOGW(TAG, "Failed to read byte from UART");
20 return;
21 }
22 if (byte == FLAG_BYTE) {
23 if (this->rx_started_ && this->receive_buffer_.size() > 6) {
24 auto len = this->receive_buffer_.size();
25 auto crc = crc16(this->receive_buffer_.data(), len - 2);
26 if (crc != (this->receive_buffer_[len - 2] | (this->receive_buffer_[len - 1] << 8))) {
27 ESP_LOGD(TAG, "CRC mismatch, discarding packet");
28 this->rx_started_ = false;
29 this->receive_buffer_.clear();
30 continue;
31 }
32 this->receive_buffer_.resize(len - 2);
33 this->process_(this->receive_buffer_);
34 this->rx_started_ = false;
35 } else {
36 this->rx_started_ = true;
37 }
38 this->receive_buffer_.clear();
39 this->rx_control_ = false;
40 continue;
41 }
42 if (!this->rx_started_)
43 continue;
44 if (byte == CONTROL_BYTE) {
45 this->rx_control_ = true;
46 continue;
47 }
48 if (this->rx_control_) {
49 byte ^= 0x20;
50 this->rx_control_ = false;
51 }
52 if (this->receive_buffer_.size() == MAX_PACKET_SIZE) {
53 ESP_LOGD(TAG, "Packet too large, discarding");
54 this->rx_started_ = false;
55 this->receive_buffer_.clear();
56 continue;
57 }
58 this->receive_buffer_.push_back(byte);
59 }
60}
61
66void UARTTransport::write_byte_(uint8_t byte) const {
67 if (byte == FLAG_BYTE || byte == CONTROL_BYTE) {
68 this->parent_->write_byte(CONTROL_BYTE);
69 byte ^= 0x20;
70 }
71 this->parent_->write_byte(byte);
72}
73
74void UARTTransport::send_packet(const std::vector<uint8_t> &buf) const {
75 this->parent_->write_byte(FLAG_BYTE);
76 for (uint8_t byte : buf) {
77 this->write_byte_(byte);
78 }
79 auto crc = crc16(buf.data(), buf.size());
80 this->write_byte_(crc & 0xFF);
81 this->write_byte_(crc >> 8);
82 this->parent_->write_byte(FLAG_BYTE);
83}
84
85size_t UARTTransport::get_max_packet_size() { return MAX_PACKET_SIZE; }
86} // namespace esphome::uart
void process_(std::span< const uint8_t > data)
Process a received packet.
void write_byte(uint8_t data)
bool read_byte(uint8_t *data)
virtual size_t available()=0
UARTComponent * parent_
Definition uart.h:134
std::vector< uint8_t > receive_buffer_
size_t get_max_packet_size() override
void send_packet(const std::vector< uint8_t > &buf) const override
void write_byte_(uint8_t byte) const
Write a byte to the UART bus.
ESPHOME_LOG_TAG(TAG, "uart.binary_sensor")
uint16_t crc16(const uint8_t *data, uint16_t len, uint16_t crc, uint16_t reverse_poly, bool refin, bool refout)
Calculate a CRC-16 checksum of data with size len.
Definition helpers.cpp:95
const void size_t len
Definition hal.h:68