ESPHome 2026.1.0-dev
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, "UART Bus:");
124 ESP_LOGCONFIG(TAG, " Type: %s", UART_TYPE[is_software]);
125 if (!is_software) {
126 ESP_LOGCONFIG(TAG, " Port number: %d", this->hardware_idx_);
127 }
128 LOG_PIN(" TX Pin: ", tx_pin_);
129 LOG_PIN(" RX Pin: ", rx_pin_);
130 if (this->rx_pin_ != nullptr) {
131 ESP_LOGCONFIG(TAG, " RX Buffer Size: %u", this->rx_buffer_size_);
132 }
133 ESP_LOGCONFIG(TAG,
134 " Baud Rate: %u baud\n"
135 " Data Bits: %u\n"
136 " Parity: %s\n"
137 " Stop bits: %u",
138 this->baud_rate_, this->data_bits_, LOG_STR_ARG(parity_to_str(this->parity_)), this->stop_bits_);
139 this->check_logger_conflict();
140}
141
142void LibreTinyUARTComponent::write_array(const uint8_t *data, size_t len) {
143 this->serial_->write(data, len);
144#ifdef USE_UART_DEBUGGER
145 for (size_t i = 0; i < len; i++) {
146 this->debug_callback_.call(UART_DIRECTION_TX, data[i]);
147 }
148#endif
149}
150
152 if (!this->check_read_timeout_())
153 return false;
154 *data = this->serial_->peek();
155 return true;
156}
157
158bool LibreTinyUARTComponent::read_array(uint8_t *data, size_t len) {
159 if (!this->check_read_timeout_(len))
160 return false;
161 this->serial_->readBytes(data, len);
162#ifdef USE_UART_DEBUGGER
163 for (size_t i = 0; i < len; i++) {
164 this->debug_callback_.call(UART_DIRECTION_RX, data[i]);
165 }
166#endif
167 return true;
168}
169
170int LibreTinyUARTComponent::available() { return this->serial_->available(); }
172 ESP_LOGVV(TAG, " Flushing");
173 this->serial_->flush();
174}
175
177#ifdef USE_LOGGER
178 if (this->hardware_idx_ == -1 || logger::global_logger->get_baud_rate() == 0) {
179 return;
180 }
181
183 ESP_LOGW(TAG, " You're using the same serial port for logging and the UART component. Please "
184 "disable logging over the serial port by setting logger->baud_rate to 0.");
185 }
186#endif
187}
188
189} // namespace esphome::uart
190#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:20
@ FLAG_NONE
Definition gpio.h:17
@ FLAG_PULLUP
Definition gpio.h:21
@ FLAG_PULLDOWN
Definition gpio.h:22
Logger * global_logger
Definition logger.cpp:297
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:533