-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathuartex.h
More file actions
173 lines (164 loc) · 6.63 KB
/
Copy pathuartex.h
File metadata and controls
173 lines (164 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#pragma once
#include <memory>
#include "esphome/core/automation.h"
#include "esphome/components/uart/uart.h"
#include "esphome/components/text_sensor/text_sensor.h"
#include "uartex_device.h"
#include "parser.h"
#include "version.h"
namespace esphome {
namespace uartex {
enum ERROR {
ERROR_NONE,
ERROR_SIZE,
ERROR_HEADER,
ERROR_FOOTER,
ERROR_CHECKSUM,
ERROR_RX_TIMEOUT,
ERROR_TX_TIMEOUT
};
enum CHECKSUM {
CHECKSUM_NONE,
CHECKSUM_CUSTOM,
CHECKSUM_XOR,
CHECKSUM_ADD,
CHECKSUM_XOR_NO_HEADER,
CHECKSUM_ADD_NO_HEADER,
CHECKSUM_XOR_ADD
};
enum PRIORITY {
PRIORITY_DATA,
PRIORITY_LOOP
};
struct tx_data_t
{
UARTExDevice* device{nullptr};
const cmd_t* cmd{nullptr};
// Optional owner for ad-hoc commands built at runtime (write_command, the
// templated write action). Keeps the cmd_t alive from enqueue until the
// command is sent so `cmd` never dangles or gets overwritten in place.
std::shared_ptr<cmd_t> owned{};
};
struct header_t
{
std::vector<uint8_t> data;
std::vector<uint8_t> mask;
};
struct rx_data_length_t
{
uint8_t offset{0};
uint8_t length{1};
ENDIAN endian{ENDIAN_BIG};
int8_t adjust{0};
};
class UARTExComponent : public uart::UARTDevice, public Component
{
public:
UARTExComponent() = default;
void set_rx_header(header_t header);
void set_rx_footer(std::vector<uint8_t> footer);
void set_tx_header(std::vector<uint8_t> header);
void set_tx_footer(std::vector<uint8_t> footer);
void set_rx_checksum(CHECKSUM checksum);
void set_rx_checksum(std::function<uint8_t(const uint8_t *data, const uint16_t len)> &&f);
void set_tx_checksum(CHECKSUM checksum);
void set_tx_checksum(std::function<uint8_t(const uint8_t *data, const uint16_t len)> &&f);
void set_rx_checksum_2(CHECKSUM checksum);
void set_tx_checksum_2(CHECKSUM checksum);
void set_rx_checksum_2(std::function<std::vector<uint8_t>(const uint8_t *data, const uint16_t len)> &&f);
void set_tx_checksum_2(std::function<std::vector<uint8_t>(const uint8_t *data, const uint16_t len)> &&f);
void set_rx_priority(PRIORITY priority);
void set_version(text_sensor::TextSensor *version) { this->version_ = version; }
void set_error(text_sensor::TextSensor *error) { this->error_ = error; }
void set_log(text_sensor::TextSensor *log) { this->log_ = log; }
void set_log_ascii(bool ascii) { this->log_ascii_ = ascii; }
void add_on_write_callback(std::function<void(const uint8_t *data, const uint16_t len)> &&callback) { this->write_callback_.add(std::move(callback)); }
void add_on_read_callback(std::function<void(const uint8_t *data, const uint16_t len)> &&callback) { this->read_callback_.add(std::move(callback)); }
void add_on_error_callback(std::function<void(const ERROR)> &&callback) { this->error_callback_.add(std::move(callback)); }
std::vector<uint8_t> get_rx_checksum(const std::vector<uint8_t> &data, const std::vector<uint8_t> &header);
std::vector<uint8_t> get_tx_checksum(const std::vector<uint8_t> &data);
void dump_config() override;
void setup() override;
void loop() override;
float get_setup_priority() const override { return setup_priority::BUS - 1.0f; }
void write_data(const uint8_t data);
void write_data(const std::vector<uint8_t> &data);
void write_flush();
void register_device(UARTExDevice *device);
void set_tx_delay(uint16_t tx_delay);
void set_tx_timeout(uint16_t timeout);
void set_tx_retry_cnt(uint16_t tx_retry_cnt);
void set_tx_command_queue_size(uint16_t size);
void set_rx_length(uint16_t rx_length);
void set_rx_data_length(uint8_t offset, uint8_t length, ENDIAN endian, int8_t adjust);
void set_rx_timeout(uint16_t timeout);
void set_tx_ctrl_pin(InternalGPIOPin *pin);
void enqueue_tx_data(const tx_data_t data, bool low_priority = false);
void write_command(cmd_t cmd);
protected:
bool is_tx_cmd_pending();
void tx_cmd_result(bool result);
void clear_tx_data();
const cmd_t* current_tx_cmd();
void write_tx_cmd();
ERROR validate_data();
bool verify_data();
bool publish_error(ERROR error_code);
void publish_rx_log(const std::vector<unsigned char>& data);
void publish_tx_log(const std::vector<unsigned char>& data);
void publish_log(std::string msg);
bool read_from_uart();
bool parse_bytes();
void publish_to_devices();
bool verify_ack();
void publish_data();
void write_to_uart();
bool retry_tx_data();
void write_tx_data();
void dequeue_tx_data_from_devices();
uint16_t get_checksum(CHECKSUM checksum, const std::vector<uint8_t> &header, const std::vector<uint8_t> &data);
protected:
std::vector<UARTExDevice *> devices_{};
uint16_t conf_rx_timeout_{10};
uint16_t conf_tx_delay_{50};
uint16_t conf_tx_timeout_{50};
uint16_t conf_tx_retry_cnt_{3};
uint16_t conf_tx_command_queue_size_{10};
uint16_t conf_rx_length_{0};
optional<rx_data_length_t> conf_rx_data_length_{};
optional<header_t> rx_header_{};
optional<std::vector<uint8_t>> rx_footer_{};
optional<std::vector<uint8_t>> tx_header_{};
optional<std::vector<uint8_t>> tx_footer_{};
PRIORITY rx_priority_{PRIORITY_DATA};
CHECKSUM rx_checksum_{CHECKSUM_NONE};
CHECKSUM tx_checksum_{CHECKSUM_NONE};
optional<std::function<uint8_t(const uint8_t *data, const uint16_t len)>> rx_checksum_f_{};
optional<std::function<uint8_t(const uint8_t *data, const uint16_t len)>> tx_checksum_f_{};
CHECKSUM rx_checksum_2_{CHECKSUM_NONE};
CHECKSUM tx_checksum_2_{CHECKSUM_NONE};
optional<std::function<std::vector<uint8_t>(const uint8_t *data, const uint16_t len)>> rx_checksum_f_2_{};
optional<std::function<std::vector<uint8_t>(const uint8_t *data, const uint16_t len)>> tx_checksum_f_2_{};
CallbackManager<void(const uint8_t *data, const uint16_t len)> write_callback_{};
CallbackManager<void(const uint8_t *data, const uint16_t len)> read_callback_{};
ERROR error_code_{ERROR_NONE};
CallbackManager<void(const ERROR)> error_callback_{};
std::queue<tx_data_t> tx_queue_{};
std::queue<tx_data_t> tx_queue_low_priority_{};
tx_data_t current_tx_data_{nullptr, nullptr};
bool rx_processing_{false};
unsigned long rx_timer_{0};
unsigned long rx_time_{0};
unsigned long tx_time_{0};
uint16_t tx_retry_cnt_{0};
InternalGPIOPin *tx_ctrl_pin_{nullptr};
Parser rx_parser_{};
text_sensor::TextSensor* version_{nullptr};
text_sensor::TextSensor* error_{nullptr};
text_sensor::TextSensor* log_{nullptr};
bool log_ascii_{false};
std::string last_log_{""};
uint32_t log_count_{0};
};
} // namespace uartex
} // namespace esphome