9#include "driver/gpio.h"
10#include "hal/uart_ll.h"
11#include "esp_private/gpio.h"
12#include "soc/gpio_num.h"
13#include "soc/soc_caps.h"
14#include "soc/uart_pins.h"
16#ifdef USE_UART_WAKE_LOOP_ON_RX
38static constexpr bool is_default_uart0_pin(int8_t pin_num) {
39 return pin_num == U0TXD_GPIO_NUM || pin_num == U0RXD_GPIO_NUM;
43static_assert(SOC_MOD_CLK_INVALID <= UINT8_MAX,
"uart_sclk_t no longer fits in uint8_t clock_source_");
45static const LogString *clock_source_to_str(uart_sclk_t clock_source) {
46 switch (clock_source) {
47#if SOC_UART_SUPPORT_APB_CLK
49 return LOG_STR(
"APB");
51#if SOC_UART_SUPPORT_XTAL_CLK
53 return LOG_STR(
"XTAL");
55#if SOC_UART_SUPPORT_RTC_CLK
57 return LOG_STR(
"RTC");
59#if SOC_UART_SUPPORT_REF_TICK
60 case UART_SCLK_REF_TICK:
61 return LOG_STR(
"REF_TICK");
64 return clock_source == UART_SCLK_DEFAULT ? LOG_STR(
"DEFAULT") : LOG_STR(
"UNKNOWN");
69 uart_parity_t parity = UART_PARITY_DISABLE;
71 parity = UART_PARITY_EVEN;
73 parity = UART_PARITY_ODD;
76 uart_word_length_t data_bits;
79 data_bits = UART_DATA_5_BITS;
82 data_bits = UART_DATA_6_BITS;
85 data_bits = UART_DATA_7_BITS;
88 data_bits = UART_DATA_8_BITS;
91 data_bits = UART_DATA_BITS_MAX;
95 uart_config_t uart_config{};
97 uart_config.data_bits = data_bits;
98 uart_config.parity = parity;
99 uart_config.stop_bits = this->
stop_bits_ == 1 ? UART_STOP_BITS_1 : UART_STOP_BITS_2;
100 uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
101 uart_config.source_clk =
static_cast<uart_sclk_t
>(this->
clock_source_);
102 uart_config.rx_flow_ctrl_thresh = 122;
108 static uint8_t next_uart_num = 0;
111 bool logger_uses_hardware_uart =
true;
113#ifdef USE_LOGGER_USB_CDC
116 logger_uses_hardware_uart =
false;
120#ifdef USE_LOGGER_USB_SERIAL_JTAG
123 logger_uses_hardware_uart =
false;
133 if (next_uart_num >= SOC_UART_NUM) {
134 ESP_LOGW(TAG,
"Maximum number of UART components created already");
138 this->
uart_num_ =
static_cast<uart_port_t
>(next_uart_num++);
140#if (SOC_UART_LP_NUM >= 1)
141 size_t fifo_len = ((this->
uart_num_ < SOC_UART_HP_NUM) ? SOC_UART_FIFO_LEN : SOC_LP_UART_FIFO_LEN);
143 size_t fifo_len = SOC_UART_FIFO_LEN;
146 ESP_LOGW(TAG,
"rx_buffer_size is too small, must be greater than %zu", fifo_len);
156 if (uart_is_driver_installed(this->
uart_num_)) {
157 err = uart_driver_delete(this->
uart_num_);
159 ESP_LOGW(TAG,
"uart_driver_delete failed: %s", esp_err_to_name(err));
164 err = uart_driver_install(this->
uart_num_,
173 ESP_LOGW(TAG,
"uart_driver_install failed: %s", esp_err_to_name(err));
185 err = uart_param_config(this->
uart_num_, &uart_config);
187 ESP_LOGW(TAG,
"uart_param_config failed: %s", esp_err_to_name(err));
199 if (is_default_uart0_pin(tx)) {
200 gpio_func_sel(
static_cast<gpio_num_t
>(tx), PIN_FUNC_GPIO);
202 if (is_default_uart0_pin(rx)) {
203 gpio_func_sel(
static_cast<gpio_num_t
>(rx), PIN_FUNC_GPIO);
216 setup_pin_if_needed(this->
rx_pin_);
218 setup_pin_if_needed(this->
tx_pin_);
225 ESP_LOGW(TAG,
"uart_set_line_inverse failed: %s", esp_err_to_name(err));
230 err = uart_set_pin(this->
uart_num_, tx, rx, flow_control, UART_PIN_NO_CHANGE);
232 ESP_LOGW(TAG,
"uart_set_pin failed: %s", esp_err_to_name(err));
246#ifdef USE_UART_WAKE_LOOP_ON_RX
254 ESP_LOGCONFIG(TAG,
"Reloaded UART %u", this->
uart_num_);
262 invert |= UART_SIGNAL_TXD_INV;
265 invert |= UART_SIGNAL_RXD_INV;
268 invert |= UART_SIGNAL_RTS_INV;
277 ESP_LOGW(TAG,
"uart_set_line_inverse failed: %s", esp_err_to_name(err));
283 ESP_LOGW(TAG,
"uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
289 ESP_LOGW(TAG,
"uart_set_rx_timeout failed: %s", esp_err_to_name(err));
297 ESP_LOGW(TAG,
"uart_set_mode failed: %s", esp_err_to_name(err));
314 return ESP_ERR_INVALID_STATE;
317 if (!uart_is_driver_installed(this->
uart_num_)) {
319 return this->
is_failed() ? ESP_FAIL : ESP_OK;
323 esp_err_t err = uart_param_config(this->
uart_num_, &uart_config);
328 ESP_LOGE(TAG,
"uart_param_config (live) failed: %s; no previous framing to restore", esp_err_to_name(err));
332 ESP_LOGW(TAG,
"uart_param_config (live) failed: %s; restoring %" PRIu32
" baud", esp_err_to_name(err),
336 esp_err_t restore_err = uart_param_config(this->
uart_num_, &uart_config);
337 if (restore_err != ESP_OK) {
338 ESP_LOGE(TAG,
"UART left unconfigured after failed live reconfigure: %s", esp_err_to_name(restore_err));
353 ESP_LOGCONFIG(TAG,
"UART Bus %u:", this->
uart_num_);
354 LOG_PIN(
" TX Pin: ", this->
tx_pin_);
355 LOG_PIN(
" RX Pin: ", this->
rx_pin_);
357 if (this->
rx_pin_ !=
nullptr) {
359 " RX Buffer Size: %u\n"
360 " RX Full Threshold: %u\n"
371 " Baud Rate: %" PRIu32
" baud\n"
376#ifdef USE_UART_WAKE_LOOP_ON_RX
377 "\n Wake on data RX: ENABLED"
381 LOG_STR_ARG(clock_source_to_str(
static_cast<uart_sclk_t
>(this->
clock_source_))));
387 esp_err_t err = uart_set_rx_full_threshold(this->
uart_num_, rx_full_threshold);
389 ESP_LOGW(TAG,
"uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
398 esp_err_t err = uart_set_rx_timeout(this->
uart_num_, rx_timeout);
400 ESP_LOGW(TAG,
"uart_set_rx_timeout failed: %s", esp_err_to_name(err));
411 return uart_ll_get_txfifo_len(UART_LL_GET_HW(this->
uart_num_));
415 uart_get_tx_buffer_free_size(this->
uart_num_, &free);
420 int32_t write_len = uart_write_bytes(this->
uart_num_, data,
len);
421 if (write_len != (int32_t)
len) {
422 ESP_LOGW(TAG,
"uart_write_bytes failed: %" PRId32
" != %zu", write_len,
len);
425#ifdef USE_UART_DEBUGGER
426 for (
size_t i = 0; i <
len; i++) {
438 int len = uart_read_bytes(this->
uart_num_, data, 1, 20 / portTICK_PERIOD_MS);
453 size_t length_to_read =
len;
454 int32_t read_len = 0;
462 if (length_to_read > 0)
463 read_len = uart_read_bytes(this->
uart_num_, data + (
len - length_to_read), length_to_read, 20 / portTICK_PERIOD_MS);
464#ifdef USE_UART_DEBUGGER
465 for (
size_t i = 0; i <
len; i++) {
469 return read_len == (int32_t) length_to_read;
476 err = uart_get_buffered_data_len(this->
uart_num_, &available);
479 ESP_LOGW(TAG,
"uart_get_buffered_data_len failed: %s", esp_err_to_name(err));
489 ESP_LOGVV(TAG,
" Flushing");
491 esp_err_t err = uart_wait_tx_done(this->
uart_num_, ticks);
494 if (err == ESP_ERR_TIMEOUT)
501#ifdef USE_UART_WAKE_LOOP_ON_RX
505 BaseType_t *task_woken) {
506 if (uart_select_notif == UART_SELECT_READ_NOTIF) {
515 uart_wait_tx_done(this->
uart_num_, pdMS_TO_TICKS(100));
517 esp_err_t err = uart_driver_delete(this->
uart_num_);
519 ESP_LOGW(TAG,
"uart_driver_delete failed: %s", esp_err_to_name(err));
BedjetMode mode
BedJet operating mode.
static void IRAM_ATTR ESPHOME_ALWAYS_INLINE wake_loop_isrsafe()
Wake from ISR (ESP8266). No task_woken arg — no FreeRTOS. Caller must be IRAM_ATTR.
void mark_failed()
Mark this component as failed.
size_t available_for_write() override
void dump_config() override
void set_rx_timeout(size_t rx_timeout) override
esp_err_t apply_line_settings_()
void set_framing_(const Framing &framing)
uart_config_t get_config_()
void check_logger_conflict() override
void set_pins_hold_(bool hold)
bool peek_byte(uint8_t *data) override
size_t available() override
uint8_t clock_source_
uart_sclk_t stored in a byte; the IDF values are all small.
void load_settings()
Load the UART settings.
uint32_t line_inversion_mask_()
void write_array(const uint8_t *data, size_t len) override
void set_rx_full_threshold(size_t rx_full_threshold) override
bool read_array(uint8_t *data, size_t len) override
UARTFlushResult flush() override
void on_shutdown() override
uint32_t flush_timeout_ms_
0 means wait indefinitely (portMAX_DELAY).
static void uart_rx_isr_callback(uart_port_t uart_num, uart_select_notif_t uart_select_notif, BaseType_t *task_woken)
esp_err_t apply_settings_live()
Apply the current framing (baud rate, parity, data/stop bits) to the installed driver in place,...
Framing last_good_framing_
UARTParityOptions parity_
bool check_read_timeout_(size_t len=1)
InternalGPIOPin * tx_pin_
uint32_t get_baud_rate() const
InternalGPIOPin * flow_control_pin_
CallbackManager< void(UARTDirection, uint8_t)> debug_callback_
size_t rx_full_threshold_
InternalGPIOPin * rx_pin_
@ UART_SELECTION_USB_SERIAL_JTAG
ESPHOME_LOG_TAG(TAG, "uart.binary_sensor")
const LogString * parity_to_str(UARTParityOptions parity)
@ UART_CONFIG_PARITY_EVEN
UARTFlushResult
Result of a flush() call.
@ UART_FLUSH_RESULT_SUCCESS
Confirmed: all bytes left the TX FIFO.
@ UART_FLUSH_RESULT_FAILED
Confirmed: driver or hardware error.
@ UART_FLUSH_RESULT_TIMEOUT
Confirmed: timed out before TX completed.