mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 10:12:52 +00:00
63 lines
1.7 KiB
C++
63 lines
1.7 KiB
C++
#include "uart_component.h"
|
|
#include "esphome/core/application.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace esphome::uart {
|
|
|
|
ESPHOME_LOG_TAG(TAG, "uart");
|
|
|
|
// Keeps the pacing product in 32 bits up to about 10 Mbaud.
|
|
static constexpr uint32_t MAX_PACE_SPAN_MS = 4000;
|
|
|
|
bool UARTComponent::check_read_timeout_(size_t len) {
|
|
if (this->available() >= len)
|
|
return true;
|
|
|
|
uint32_t start_time = millis();
|
|
while (this->available() < len) {
|
|
if (millis() - start_time > 100) {
|
|
ESP_LOGE(TAG, "Reading from UART timed out at byte %zu!", this->available());
|
|
return false;
|
|
}
|
|
yield();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
size_t UARTComponent::paced_write_room(uint32_t last_write_ms) {
|
|
size_t room = this->available_for_write();
|
|
if (room != SIZE_MAX) {
|
|
return room;
|
|
}
|
|
// A pass woken early writes little.
|
|
uint32_t span =
|
|
std::min({App.get_loop_component_start_time() - last_write_ms, App.get_loop_interval(), MAX_PACE_SPAN_MS});
|
|
// 10 bits per byte on the line.
|
|
uint32_t paced = this->baud_rate_ / 10 * span / 1000;
|
|
return std::max<size_t>(1, paced);
|
|
}
|
|
|
|
void UARTComponent::set_rx_full_threshold_ms(uint8_t time) {
|
|
uint8_t bytelength = this->data_bits_ + this->stop_bits_ + 1;
|
|
if (this->parity_ != UARTParityOptions::UART_CONFIG_PARITY_NONE)
|
|
bytelength += 1;
|
|
int32_t val = clamp<int32_t>((this->baud_rate_ / (bytelength * 1000 / time)) - 1, 1, 120);
|
|
this->set_rx_full_threshold(val);
|
|
}
|
|
|
|
#ifdef USE_ESP8266
|
|
void UARTComponent::write_array_progmem(const uint8_t *data, size_t len) {
|
|
uint8_t buf[32];
|
|
while (len > 0) {
|
|
const size_t chunk = std::min(len, sizeof(buf));
|
|
progmem_memcpy(buf, data, chunk);
|
|
this->write_array(buf, chunk);
|
|
data += chunk;
|
|
len -= chunk;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} // namespace esphome::uart
|