#include "openknx_idf/tpuart_uart_interface.h" #include "esp_log.h" #include namespace gateway::openknx { namespace { constexpr const char* kTag = "openknx_tpuart"; } // namespace TpuartUartInterface::TpuartUartInterface(uart_port_t uart_port, int tx_pin, int rx_pin, size_t rx_buffer_size, size_t tx_buffer_size) : uart_port_(uart_port), tx_pin_(tx_pin), rx_pin_(rx_pin), rx_buffer_size_(rx_buffer_size), tx_buffer_size_(tx_buffer_size) {} TpuartUartInterface::~TpuartUartInterface() { end(); } void TpuartUartInterface::begin(int baud) { if (_running) { end(); } uart_config_t config{}; config.baud_rate = baud; config.data_bits = UART_DATA_8_BITS; config.parity = UART_PARITY_EVEN; config.stop_bits = UART_STOP_BITS_1; config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; config.source_clk = UART_SCLK_DEFAULT; esp_err_t err = uart_param_config(uart_port_, &config); if (err != ESP_OK) { ESP_LOGE(kTag, "failed to configure UART%d: %s", uart_port_, esp_err_to_name(err)); return; } err = uart_set_pin(uart_port_, tx_pin_ < 0 ? UART_PIN_NO_CHANGE : tx_pin_, rx_pin_ < 0 ? UART_PIN_NO_CHANGE : rx_pin_, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); if (err != ESP_OK) { ESP_LOGE(kTag, "failed to route UART%d pins: %s", uart_port_, esp_err_to_name(err)); return; } err = uart_driver_install(uart_port_, rx_buffer_size_, tx_buffer_size_, 0, nullptr, 0); if (err != ESP_OK) { ESP_LOGE(kTag, "failed to install UART%d driver: %s", uart_port_, esp_err_to_name(err)); return; } uart_set_rx_full_threshold(uart_port_, 1); _running = true; } void TpuartUartInterface::end() { if (!_running) { return; } _running = false; uart_driver_delete(uart_port_); } bool TpuartUartInterface::available() { if (!_running) { return false; } size_t len = 0; return uart_get_buffered_data_len(uart_port_, &len) == ESP_OK && len > 0; } bool TpuartUartInterface::availableForWrite() { if (!_running) { return false; } size_t len = 0; return uart_get_tx_buffer_free_size(uart_port_, &len) == ESP_OK && len > 0; } bool TpuartUartInterface::write(char value) { if (!_running) { return false; } return uart_write_bytes(uart_port_, &value, 1) == 1; } int TpuartUartInterface::read() { if (!_running) { return -1; } uint8_t value = 0; return uart_read_bytes(uart_port_, &value, 1, 0) == 1 ? value : -1; } bool TpuartUartInterface::overflow() { return overflow_.exchange(false); } void TpuartUartInterface::flush() { if (_running) { uart_flush(uart_port_); } } bool TpuartUartInterface::hasCallback() { return false; } void TpuartUartInterface::registerCallback(std::function callback) { callback_ = std::move(callback); } } // namespace gateway::openknx