ESPHome 2025.5.0
Loading...
Searching...
No Matches
uart_component_esp32_arduino.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32_FRAMEWORK_ARDUINO
6#include "esphome/core/log.h"
7
8#ifdef USE_LOGGER
10#endif
11
12namespace esphome {
13namespace uart {
14static const char *const TAG = "uart.arduino_esp32";
15
16static const uint32_t UART_PARITY_EVEN = 0 << 0;
17static const uint32_t UART_PARITY_ODD = 1 << 0;
18static const uint32_t UART_PARITY_ENABLE = 1 << 1;
19static const uint32_t UART_NB_BIT_5 = 0 << 2;
20static const uint32_t UART_NB_BIT_6 = 1 << 2;
21static const uint32_t UART_NB_BIT_7 = 2 << 2;
22static const uint32_t UART_NB_BIT_8 = 3 << 2;
23static const uint32_t UART_NB_STOP_BIT_1 = 1 << 4;
24static const uint32_t UART_NB_STOP_BIT_2 = 3 << 4;
25static const uint32_t UART_TICK_APB_CLOCK = 1 << 27;
26
28 uint32_t config = 0;
29
30 /*
31 * All bits numbers below come from
32 * framework-arduinoespressif32/cores/esp32/esp32-hal-uart.h
33 * And more specifically conf0 union in uart_dev_t.
34 *
35 * Below is bit used from conf0 union.
36 * <name>:<bits position> <values>
37 * parity:0 0:even 1:odd
38 * parity_en:1 Set this bit to enable uart parity check.
39 * bit_num:2-4 0:5bits 1:6bits 2:7bits 3:8bits
40 * stop_bit_num:4-6 stop bit. 1:1bit 2:1.5bits 3:2bits
41 * tick_ref_always_on:27 select the clock.1:apb clock:ref_tick
42 */
43
44 if (this->parity_ == UART_CONFIG_PARITY_EVEN) {
45 config |= UART_PARITY_EVEN | UART_PARITY_ENABLE;
46 } else if (this->parity_ == UART_CONFIG_PARITY_ODD) {
47 config |= UART_PARITY_ODD | UART_PARITY_ENABLE;
48 }
49
50 switch (this->data_bits_) {
51 case 5:
52 config |= UART_NB_BIT_5;
53 break;
54 case 6:
55 config |= UART_NB_BIT_6;
56 break;
57 case 7:
58 config |= UART_NB_BIT_7;
59 break;
60 case 8:
61 config |= UART_NB_BIT_8;
62 break;
63 }
64
65 if (this->stop_bits_ == 1) {
66 config |= UART_NB_STOP_BIT_1;
67 } else {
68 config |= UART_NB_STOP_BIT_2;
69 }
70
71 config |= UART_TICK_APB_CLOCK;
72
73 return config;
74}
75
77 ESP_LOGCONFIG(TAG, "Setting up UART...");
78 // Use Arduino HardwareSerial UARTs if all used pins match the ones
79 // preconfigured by the platform. For example if RX disabled but TX pin
80 // is 1 we still want to use Serial.
81 bool is_default_tx, is_default_rx;
82#ifdef CONFIG_IDF_TARGET_ESP32C3
83 is_default_tx = tx_pin_ == nullptr || tx_pin_->get_pin() == 21;
84 is_default_rx = rx_pin_ == nullptr || rx_pin_->get_pin() == 20;
85#else
86 is_default_tx = tx_pin_ == nullptr || tx_pin_->get_pin() == 1;
87 is_default_rx = rx_pin_ == nullptr || rx_pin_->get_pin() == 3;
88#endif
89 static uint8_t next_uart_num = 0;
90 if (is_default_tx && is_default_rx && next_uart_num == 0) {
91#if ARDUINO_USB_CDC_ON_BOOT
92 this->hw_serial_ = &Serial0;
93#else
94 this->hw_serial_ = &Serial;
95#endif
96 next_uart_num++;
97 } else {
98#ifdef USE_LOGGER
99 bool logger_uses_hardware_uart = true;
100
101#ifdef USE_LOGGER_USB_CDC
103 // this is not a hardware UART, ignore it
104 logger_uses_hardware_uart = false;
105 }
106#endif // USE_LOGGER_USB_CDC
107
108#ifdef USE_LOGGER_USB_SERIAL_JTAG
110 // this is not a hardware UART, ignore it
111 logger_uses_hardware_uart = false;
112 }
113#endif // USE_LOGGER_USB_SERIAL_JTAG
114
115 if (logger_uses_hardware_uart && logger::global_logger->get_baud_rate() > 0 &&
116 logger::global_logger->get_uart() == next_uart_num) {
117 next_uart_num++;
118 }
119#endif // USE_LOGGER
120
121 if (next_uart_num >= SOC_UART_NUM) {
122 ESP_LOGW(TAG, "Maximum number of UART components created already.");
123 this->mark_failed();
124 return;
125 }
126
127 this->number_ = next_uart_num;
128 this->hw_serial_ = new HardwareSerial(next_uart_num++); // NOLINT(cppcoreguidelines-owning-memory)
129 }
130
131 this->load_settings(false);
132}
133
135 int8_t tx = this->tx_pin_ != nullptr ? this->tx_pin_->get_pin() : -1;
136 int8_t rx = this->rx_pin_ != nullptr ? this->rx_pin_->get_pin() : -1;
137 bool invert = false;
138 if (tx_pin_ != nullptr && tx_pin_->is_inverted())
139 invert = true;
140 if (rx_pin_ != nullptr && rx_pin_->is_inverted())
141 invert = true;
142 this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
143 this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx, invert);
144 if (dump_config) {
145 ESP_LOGCONFIG(TAG, "UART %u was reloaded.", this->number_);
146 this->dump_config();
147 }
148}
149
151 ESP_LOGCONFIG(TAG, "UART Bus %d:", this->number_);
152 LOG_PIN(" TX Pin: ", tx_pin_);
153 LOG_PIN(" RX Pin: ", rx_pin_);
154 if (this->rx_pin_ != nullptr) {
155 ESP_LOGCONFIG(TAG, " RX Buffer Size: %u", this->rx_buffer_size_);
156 }
157 ESP_LOGCONFIG(TAG, " Baud Rate: %u baud", this->baud_rate_);
158 ESP_LOGCONFIG(TAG, " Data Bits: %u", this->data_bits_);
159 ESP_LOGCONFIG(TAG, " Parity: %s", LOG_STR_ARG(parity_to_str(this->parity_)));
160 ESP_LOGCONFIG(TAG, " Stop bits: %u", this->stop_bits_);
161 this->check_logger_conflict();
162}
163
164void ESP32ArduinoUARTComponent::write_array(const uint8_t *data, size_t len) {
165 this->hw_serial_->write(data, len);
166#ifdef USE_UART_DEBUGGER
167 for (size_t i = 0; i < len; i++) {
168 this->debug_callback_.call(UART_DIRECTION_TX, data[i]);
169 }
170#endif
171}
172
174 if (!this->check_read_timeout_())
175 return false;
176 *data = this->hw_serial_->peek();
177 return true;
178}
179
180bool ESP32ArduinoUARTComponent::read_array(uint8_t *data, size_t len) {
181 if (!this->check_read_timeout_(len))
182 return false;
183 this->hw_serial_->readBytes(data, len);
184#ifdef USE_UART_DEBUGGER
185 for (size_t i = 0; i < len; i++) {
186 this->debug_callback_.call(UART_DIRECTION_RX, data[i]);
187 }
188#endif
189 return true;
190}
191
192int ESP32ArduinoUARTComponent::available() { return this->hw_serial_->available(); }
194 ESP_LOGVV(TAG, " Flushing...");
195 this->hw_serial_->flush();
196}
197
199#ifdef USE_LOGGER
200 if (this->hw_serial_ == nullptr || logger::global_logger->get_baud_rate() == 0) {
201 return;
202 }
203
205 ESP_LOGW(TAG, " You're using the same serial port for logging and the UART component. Please "
206 "disable logging over the serial port by setting logger->baud_rate to 0.");
207 }
208#endif
209}
210
211} // namespace uart
212} // namespace esphome
213#endif // USE_ESP32_FRAMEWORK_ARDUINO
virtual void mark_failed()
Mark this component as failed.
virtual uint8_t get_pin() const =0
virtual bool is_inverted() const =0
void write_array(const uint8_t *data, size_t len) override
bool read_array(uint8_t *data, size_t len) override
bool check_read_timeout_(size_t len=1)
CallbackManager< void(UARTDirection, uint8_t)> debug_callback_
@ UART_SELECTION_USB_SERIAL_JTAG
Definition logger.h:79
@ UART_SELECTION_USB_CDC
Definition logger.h:76
Logger * global_logger
Definition logger.cpp:251
const char *const TAG
Definition spi.cpp:8
const LogString * parity_to_str(UARTParityOptions parity)
Definition uart.cpp:33
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:301