10#include "driver/gpio.h"
11#include "soc/gpio_num.h"
12#include "soc/uart_pins.h"
20static const char *
const TAG =
"uart.idf";
23 uart_parity_t parity = UART_PARITY_DISABLE;
25 parity = UART_PARITY_EVEN;
27 parity = UART_PARITY_ODD;
30 uart_word_length_t data_bits;
33 data_bits = UART_DATA_5_BITS;
36 data_bits = UART_DATA_6_BITS;
39 data_bits = UART_DATA_7_BITS;
42 data_bits = UART_DATA_8_BITS;
45 data_bits = UART_DATA_BITS_MAX;
49 uart_config_t uart_config{};
51 uart_config.data_bits = data_bits;
52 uart_config.parity = parity;
53 uart_config.stop_bits = this->
stop_bits_ == 1 ? UART_STOP_BITS_1 : UART_STOP_BITS_2;
54 uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
55 uart_config.source_clk = UART_SCLK_DEFAULT;
56 uart_config.rx_flow_ctrl_thresh = 122;
62 static uint8_t next_uart_num = 0;
65 bool logger_uses_hardware_uart =
true;
67#ifdef USE_LOGGER_USB_CDC
70 logger_uses_hardware_uart =
false;
74#ifdef USE_LOGGER_USB_SERIAL_JTAG
77 logger_uses_hardware_uart =
false;
87 if (next_uart_num >= SOC_UART_NUM) {
88 ESP_LOGW(TAG,
"Maximum number of UART components created already");
92 this->
uart_num_ =
static_cast<uart_port_t
>(next_uart_num++);
93 this->
lock_ = xSemaphoreCreateMutex();
95#if (SOC_UART_LP_NUM >= 1)
96 size_t fifo_len = ((this->
uart_num_ < SOC_UART_HP_NUM) ? SOC_UART_FIFO_LEN : SOC_LP_UART_FIFO_LEN);
98 size_t fifo_len = SOC_UART_FIFO_LEN;
101 ESP_LOGW(TAG,
"rx_buffer_size is too small, must be greater than %zu", fifo_len);
105 xSemaphoreTake(this->
lock_, portMAX_DELAY);
109 xSemaphoreGive(this->
lock_);
115 if (uart_is_driver_installed(this->
uart_num_)) {
116#ifdef USE_UART_WAKE_LOOP_ON_RX
122 err = uart_driver_delete(this->
uart_num_);
124 ESP_LOGW(TAG,
"uart_driver_delete failed: %s", esp_err_to_name(err));
129 err = uart_driver_install(this->
uart_num_,
138 ESP_LOGW(TAG,
"uart_driver_install failed: %s", esp_err_to_name(err));
151 if (tx == U0TXD_GPIO_NUM || tx == U0RXD_GPIO_NUM) {
152 gpio_reset_pin(
static_cast<gpio_num_t
>(tx));
154 if (rx == U0TXD_GPIO_NUM || rx == U0RXD_GPIO_NUM) {
155 gpio_reset_pin(
static_cast<gpio_num_t
>(rx));
169 setup_pin_if_needed(this->
rx_pin_);
171 setup_pin_if_needed(this->
tx_pin_);
176 invert |= UART_SIGNAL_TXD_INV;
179 invert |= UART_SIGNAL_RXD_INV;
182 err = uart_set_line_inverse(this->
uart_num_, invert);
184 ESP_LOGW(TAG,
"uart_set_line_inverse failed: %s", esp_err_to_name(err));
189 err = uart_set_pin(this->
uart_num_, tx, rx, flow_control, UART_PIN_NO_CHANGE);
191 ESP_LOGW(TAG,
"uart_set_pin failed: %s", esp_err_to_name(err));
198 ESP_LOGW(TAG,
"uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
205 ESP_LOGW(TAG,
"uart_set_rx_timeout failed: %s", esp_err_to_name(err));
213 ESP_LOGW(TAG,
"uart_set_mode failed: %s", esp_err_to_name(err));
219 err = uart_param_config(this->
uart_num_, &uart_config);
221 ESP_LOGW(TAG,
"uart_param_config failed: %s", esp_err_to_name(err));
226#ifdef USE_UART_WAKE_LOOP_ON_RX
232 ESP_LOGCONFIG(TAG,
"Reloaded UART %u", this->
uart_num_);
238 ESP_LOGCONFIG(TAG,
"UART Bus %u:", this->
uart_num_);
239 LOG_PIN(
" TX Pin: ", this->
tx_pin_);
240 LOG_PIN(
" RX Pin: ", this->
rx_pin_);
242 if (this->
rx_pin_ !=
nullptr) {
244 " RX Buffer Size: %u\n"
245 " RX Full Threshold: %u\n"
250 " Baud Rate: %" PRIu32
" baud\n"
254#ifdef USE_UART_WAKE_LOOP_ON_RX
255 "\n Wake on data RX: ENABLED"
264 esp_err_t err = uart_set_rx_full_threshold(this->
uart_num_, rx_full_threshold);
266 ESP_LOGW(TAG,
"uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
275 esp_err_t err = uart_set_rx_timeout(this->
uart_num_, rx_timeout);
277 ESP_LOGW(TAG,
"uart_set_rx_timeout failed: %s", esp_err_to_name(err));
285 xSemaphoreTake(this->
lock_, portMAX_DELAY);
286 int32_t write_len = uart_write_bytes(this->
uart_num_, data,
len);
287 xSemaphoreGive(this->
lock_);
288 if (write_len != (int32_t)
len) {
289 ESP_LOGW(TAG,
"uart_write_bytes failed: %d != %zu", write_len,
len);
292#ifdef USE_UART_DEBUGGER
293 for (
size_t i = 0; i <
len; i++) {
302 xSemaphoreTake(this->
lock_, portMAX_DELAY);
306 int len = uart_read_bytes(this->
uart_num_, data, 1, 20 / portTICK_PERIOD_MS);
314 xSemaphoreGive(this->
lock_);
319 size_t length_to_read =
len;
320 int32_t read_len = 0;
323 xSemaphoreTake(this->
lock_, portMAX_DELAY);
330 if (length_to_read > 0)
331 read_len = uart_read_bytes(this->
uart_num_, data, length_to_read, 20 / portTICK_PERIOD_MS);
332 xSemaphoreGive(this->
lock_);
333#ifdef USE_UART_DEBUGGER
334 for (
size_t i = 0; i <
len; i++) {
338 return read_len == (int32_t) length_to_read;
345 xSemaphoreTake(this->
lock_, portMAX_DELAY);
346 err = uart_get_buffered_data_len(this->
uart_num_, &available);
347 xSemaphoreGive(this->
lock_);
350 ESP_LOGW(TAG,
"uart_get_buffered_data_len failed: %s", esp_err_to_name(err));
360 ESP_LOGVV(TAG,
" Flushing");
361 xSemaphoreTake(this->
lock_, portMAX_DELAY);
362 uart_wait_tx_done(this->
uart_num_, portMAX_DELAY);
363 xSemaphoreGive(this->
lock_);
368#ifdef USE_UART_WAKE_LOOP_ON_RX
375 tskIDLE_PRIORITY + 1,
379 if (result != pdPASS) {
380 ESP_LOGE(TAG,
"Failed to create RX event task");
384 ESP_LOGV(TAG,
"RX event task started");
391 ESP_LOGV(TAG,
"RX event task running");
396 if (xQueueReceive(self->uart_event_queue_, &event, portMAX_DELAY) == pdTRUE) {
397 switch (event.type) {
400 ESP_LOGVV(TAG,
"Data event: %d bytes", event.size);
405 case UART_BUFFER_FULL:
406 ESP_LOGW(TAG,
"FIFO overflow or ring buffer full - clearing");
407 uart_flush_input(self->uart_num_);
413 ESP_LOGVV(TAG,
"Event type: %d", event.type);
BedjetMode mode
BedJet operating mode.
void wake_loop_threadsafe()
Wake the main event loop from a FreeRTOS task Thread-safe, can be called from task context to immedia...
virtual void mark_failed()
Mark this component as failed.
virtual uint8_t get_pin() const =0
virtual bool is_inverted() const =0
void dump_config() override
void set_rx_timeout(size_t rx_timeout) override
uart_config_t get_config_()
void check_logger_conflict() override
TaskHandle_t rx_event_task_handle_
static void rx_event_task_func(void *param)
void start_rx_event_task_()
bool peek_byte(uint8_t *data) override
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
QueueHandle_t uart_event_queue_
void load_settings() override
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
const LogString * parity_to_str(UARTParityOptions parity)
@ UART_CONFIG_PARITY_EVEN
Application App
Global storage of Application pointer - only one Application can exist.