You've already forked meshtastic-device-ui
mirror of
https://github.com/m5stack/meshtastic-device-ui.git
synced 2026-05-20 11:51:03 -07:00
d234bd98c7
* fix standalone reboot * add LinuxSerialClient * trunk fmt * debug log levels
160 lines
4.2 KiB
C++
160 lines
4.2 KiB
C++
|
|
#include "comms/UARTClient.h"
|
|
#include "Arduino.h"
|
|
#include "util/ILog.h"
|
|
|
|
#ifndef SERIAL_BAUD
|
|
#define SERIAL_BAUD 38400
|
|
#endif
|
|
|
|
#define CONNECTION_TIMEOUT 60 // seconds
|
|
#define RX_BUFFER 1024
|
|
#define TIMEOUT 250 // ms
|
|
|
|
#define MAX_PACKET_SIZE 284
|
|
|
|
extern const uint8_t MT_MAGIC_0;
|
|
|
|
UARTClient::UARTClient(const char *name) : SerialClient(name), isActive(false), _serial(nullptr) {}
|
|
|
|
/**
|
|
* @brief init serial interface
|
|
* Defaults:
|
|
* ESP32: RX0=3, TX0=1, RX1=9, TX1=10, RX2=16, TX2=17
|
|
* ESP32S2: RX0=44, TX0=43, RX1=18, TX1=17
|
|
* ESP32C3: RX0=20, TX0=21, RX1=18, TX1=19
|
|
* ESP32S3: RX0=44, TX0=43, RX1=15, TX1=16, RX2=19, TX2=20
|
|
*/
|
|
void UARTClient::init(void)
|
|
{
|
|
#if SOC_UART_NUM > 2 && defined(USE_SERIAL2)
|
|
ILOG_INFO("UARTClient::init SERIAL2 baud=%d", SERIAL_BAUD);
|
|
_serial = &Serial2;
|
|
#elif SOC_UART_NUM > 1 && defined(USE_SERIAL1)
|
|
ILOG_INFO("UARTClient::init SERIAL1 baud=%d", SERIAL_BAUD);
|
|
_serial = &Serial1;
|
|
#elif defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
|
|
_serial = &Serial0;
|
|
#elif !defined(ARCH_PORTDUINO)
|
|
ILOG_INFO("UARTClient::init SERIAL1 baud=%d", SERIAL_BAUD);
|
|
_serial = &Serial;
|
|
#else
|
|
_serial = nullptr;
|
|
#endif
|
|
|
|
#if defined(ARCH_ESP32)
|
|
_serial->setTimeout(TIMEOUT);
|
|
_serial->setRxBufferSize(RX_BUFFER);
|
|
_serial->begin(SERIAL_BAUD);
|
|
#else
|
|
// not supported
|
|
#endif
|
|
#ifdef SERIAL_RX
|
|
_serial->setPins(SERIAL_RX, SERIAL_TX);
|
|
ILOG_INFO("UARTClient::setPins rx=%d, tx=%d with %d baud", SERIAL_RX, SERIAL_TX, SERIAL_BAUD);
|
|
#endif
|
|
time(&lastReceived);
|
|
SerialClient::init();
|
|
}
|
|
|
|
bool UARTClient::connect(void)
|
|
{
|
|
if (clientStatus != eConnected) {
|
|
ILOG_DEBUG("serial client connecting...");
|
|
setConnectionStatus(eConnecting, "Connecting...");
|
|
time_t timeout = millis();
|
|
while (!*_serial) {
|
|
if ((millis() - timeout) > 5) {
|
|
setConnectionStatus(eError, "Connection failed!");
|
|
ILOG_WARN("serial client connection failed!");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// skip some available bytes until we see magic header
|
|
int skipped = 0;
|
|
while (_serial->available()) {
|
|
if (_serial->peek() != MT_MAGIC_0) {
|
|
_serial->read();
|
|
skipped++;
|
|
delay(1);
|
|
}
|
|
isActive = true;
|
|
}
|
|
|
|
if (isActive) {
|
|
setConnectionStatus(eConnected, "Connected!");
|
|
ILOG_INFO("serial client connected! (skipped %d bytes)", skipped);
|
|
} else {
|
|
// pretend to be connected and start sending data
|
|
clientStatus = eConnected;
|
|
}
|
|
}
|
|
return clientStatus == eConnected;
|
|
}
|
|
|
|
bool UARTClient::disconnect(void)
|
|
{
|
|
ILOG_DEBUG("serial client disconnecting...");
|
|
isActive = false;
|
|
setConnectionStatus(eDisconnected, "Disconnected");
|
|
return SerialClient::disconnect();
|
|
}
|
|
|
|
bool UARTClient::isConnected(void)
|
|
{
|
|
time_t now;
|
|
time(&now);
|
|
if (now - lastReceived > CONNECTION_TIMEOUT && isActive) {
|
|
isActive = false;
|
|
setConnectionStatus(eDisconnected, "Disconnected");
|
|
}
|
|
return *_serial && (clientStatus == eConnected || isActive);
|
|
}
|
|
|
|
meshtastic_FromRadio UARTClient::receive(void)
|
|
{
|
|
return SerialClient::receive();
|
|
}
|
|
|
|
UARTClient::~UARTClient()
|
|
{
|
|
if (_serial) {
|
|
_serial->end();
|
|
}
|
|
};
|
|
|
|
// --- protected part ---
|
|
|
|
// raw write to serial UART interface
|
|
bool UARTClient::send(const uint8_t *buf, size_t len)
|
|
{
|
|
ILOG_TRACE("sending %d bytes to radio", len);
|
|
size_t wrote = _serial->write(buf, len);
|
|
if (wrote != len) {
|
|
ILOG_ERROR("only %d bytes were sent this time", wrote);
|
|
}
|
|
return wrote == len;
|
|
}
|
|
|
|
// raw read from serial UART interface
|
|
size_t UARTClient::receive(uint8_t *buf, size_t space_left)
|
|
{
|
|
size_t bytes_read = 0;
|
|
while (_serial->available() && bytes_read < MAX_PACKET_SIZE) {
|
|
uint8_t byte = _serial->read();
|
|
*buf++ = byte;
|
|
if (++bytes_read >= space_left) {
|
|
// no error, but serial thread is too slow (-> reduce sleep_time)
|
|
ILOG_WARN("Serial overflow!");
|
|
break;
|
|
}
|
|
}
|
|
if (bytes_read > 0) {
|
|
ILOG_TRACE("received %d bytes from serial", bytes_read);
|
|
time(&lastReceived);
|
|
isActive = true;
|
|
}
|
|
return bytes_read;
|
|
}
|