ESPHome 2026.1.4
Loading...
Searching...
No Matches
uart_component_libretiny.cpp
Go to the documentation of this file.
1#ifdef USE_LIBRETINY
2
6#include "esphome/core/log.h"
8
9#ifdef USE_LOGGER
11#endif
12
13#if LT_ARD_HAS_SOFTSERIAL
14#include <SoftwareSerial.h>
15#endif
16
17namespace esphome::uart {
18
19static const char *const TAG = "uart.lt";
20
21static const char *UART_TYPE[] = {
22 "hardware",
23 "software",
24};
25
27 uint16_t config = 0;
28
29 switch (this->parity_) {
31 config |= SERIAL_PARITY_NONE;
32 break;
34 config |= SERIAL_PARITY_EVEN;
35 break;
37 config |= SERIAL_PARITY_ODD;
38 break;
39 }
40
41 config |= (this->data_bits_ - 4) << 8;
42 config |= 0x10 + (this->stop_bits_ - 1) * 0x20;
43
44 return config;
45}
46
48 int8_t tx_pin = tx_pin_ == nullptr ? -1 : tx_pin_->get_pin();
49 int8_t rx_pin = rx_pin_ == nullptr ? -1 : rx_pin_->get_pin();
50 bool tx_inverted = tx_pin_ != nullptr && tx_pin_->is_inverted();
51 bool rx_inverted = rx_pin_ != nullptr && rx_pin_->is_inverted();
52
53 auto shouldFallbackToSoftwareSerial = [&]() -> bool {
54 auto hasFlags = [](InternalGPIOPin *pin, const gpio::Flags mask) -> bool {
55 return pin && (pin->get_flags() & mask) != gpio::Flags::FLAG_NONE;
56 };
59#if LT_ARD_HAS_SOFTSERIAL
60 ESP_LOGI(TAG, "Pins has flags set. Using Software Serial");
61 return true;
62#else
63 ESP_LOGW(TAG, "Pin flags are set but not supported for hardware serial. Ignoring");
64#endif
65 }
66 return false;
67 };
68
69 if (false)
70 return;
71#if LT_HW_UART0
72 else if ((tx_pin == -1 || tx_pin == PIN_SERIAL0_TX) && (rx_pin == -1 || rx_pin == PIN_SERIAL0_RX) &&
73 !shouldFallbackToSoftwareSerial()) {
74 this->serial_ = &Serial0;
75 this->hardware_idx_ = 0;
76 }
77#endif
78#if LT_HW_UART1
79 else if ((tx_pin == -1 || tx_pin == PIN_SERIAL1_TX) && (rx_pin == -1 || rx_pin == PIN_SERIAL1_RX) &&
80 !shouldFallbackToSoftwareSerial()) {
81 this->serial_ = &Serial1;
82 this->hardware_idx_ = 1;
83 }
84#endif
85#if LT_HW_UART2
86 else if ((tx_pin == -1 || tx_pin == PIN_SERIAL2_TX) && (rx_pin == -1 || rx_pin == PIN_SERIAL2_RX) &&
87 !shouldFallbackToSoftwareSerial()) {
88 this->serial_ = &Serial2;
89 this->hardware_idx_ = 2;
90 }
91#endif
92 else {
93#if LT_ARD_HAS_SOFTSERIAL
94 if (this->rx_pin_) {
95 this->rx_pin_->setup();
96 }
97 if (this->tx_pin_ && this->rx_pin_ != this->tx_pin_) {
98 this->tx_pin_->setup();
99 }
100 this->serial_ = new SoftwareSerial(rx_pin, tx_pin, rx_inverted || tx_inverted);
101#else
102 this->serial_ = &Serial;
103 ESP_LOGE(TAG, " SoftwareSerial is not implemented for this chip. Only hardware pins are supported:");
104#if LT_HW_UART0
105 ESP_LOGE(TAG, " TX=%u, RX=%u", PIN_SERIAL0_TX, PIN_SERIAL0_RX);
106#endif
107#if LT_HW_UART1
108 ESP_LOGE(TAG, " TX=%u, RX=%u", PIN_SERIAL1_TX, PIN_SERIAL1_RX);
109#endif
110#if LT_HW_UART2
111 ESP_LOGE(TAG, " TX=%u, RX=%u", PIN_SERIAL2_TX, PIN_SERIAL2_RX);
112#endif
113 this->mark_failed();
114 return;
115#endif
116 }
117
118 this->serial_->begin(this->baud_rate_, get_config());
119}
120
122 bool is_software = this->hardware_idx_ == -1;
123 ESP_LOGCONFIG(TAG,
124 "UART Bus:\n"
125 " Type: %s",
126 UART_TYPE[is_software]);
127 if (!is_software) {
128 ESP_LOGCONFIG(TAG, " Port number: %d", this->hardware_idx_);
129 }
130 LOG_PIN(" TX Pin: ", tx_pin_);
131 LOG_PIN(" RX Pin: ", rx_pin_);
132 if (this->rx_pin_ != nullptr) {
133 ESP_LOGCONFIG(TAG, " RX Buffer Size: %u", this->rx_buffer_size_);
134 }
135 ESP_LOGCONFIG(TAG,
136 " Baud Rate: %u baud\n"
137 " Data Bits: %u\n"
138 " Parity: %s\n"
139 " Stop bits: %u",
140 this->baud_rate_, this->data_bits_, LOG_STR_ARG(parity_to_str(this->parity_)), this->stop_bits_);
141 this->check_logger_conflict();
142}
143
144void LibreTinyUARTComponent::write_array(const uint8_t *data, size_t len) {
145 this->serial_->write(data, len);
146#ifdef USE_UART_DEBUGGER
147 for (size_t i = 0; i < len; i++) {
148 this->debug_callback_.call(UART_DIRECTION_TX, data[i]);
149 }
150#endif
151}
152
154 if (!this->check_read_timeout_())
155 return false;
156 *data = this->serial_->peek();
157 return true;
158}
159
160bool LibreTinyUARTComponent::read_array(uint8_t *data, size_t len) {
161 if (!this->check_read_timeout_(len))
162 return false;
163 this->serial_->readBytes(data, len);
164#ifdef USE_UART_DEBUGGER
165 for (size_t i = 0; i < len; i++) {
166 this->debug_callback_.call(UART_DIRECTION_RX, data[i]);
167 }
168#endif
169 return true;
170}
171
172int LibreTinyUARTComponent::available() { return this->serial_->available(); }
174 ESP_LOGVV(TAG, " Flushing");
175 this->serial_->flush();
176}
177
179#ifdef USE_LOGGER
180 if (this->hardware_idx_ == -1 || logger::global_logger->get_baud_rate() == 0) {
181 return;
182 }
183
185 ESP_LOGW(TAG, " You're using the same serial port for logging and the UART component. Please "
186 "disable logging over the serial port by setting logger->baud_rate to 0.");
187 }
188#endif
189}
190
191} // namespace esphome::uart
192#endif // USE_LIBRETINY
virtual void mark_failed()
Mark this component as failed.
virtual void setup()=0
virtual gpio::Flags get_flags() const =0
Retrieve GPIO pin flags.
virtual uint8_t get_pin() const =0
virtual bool is_inverted() const =0
bool read_array(uint8_t *data, size_t len) override
void write_array(const uint8_t *data, size_t len) override
bool check_read_timeout_(size_t len=1)
CallbackManager< void(UARTDirection, uint8_t)> debug_callback_
@ FLAG_OPEN_DRAIN
Definition gpio.h:29
@ FLAG_NONE
Definition gpio.h:26
@ FLAG_PULLUP
Definition gpio.h:30
@ FLAG_PULLDOWN
Definition gpio.h:31
Logger * global_logger
const char *const TAG
Definition spi.cpp:7
const LogString * parity_to_str(UARTParityOptions parity)
Definition uart.cpp:32
std::string size_t len
Definition helpers.h:595