mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-20 17:22:12 +00:00
Raw LoRa packets to and from a host over the USB/console serial port, plus upstream's SetHardware extensions (identity, crypto, radio config, stats). - app/KissModem.cpp/h: upstream text, ZephCore changes fenced: an LBT refusal returns to CSMA until the wait-clear bound; a TX times out only once the radio has concluded (as Dispatcher::loop); SetRadio outside the ZC_RADIO_* ranges is refused; msUntilNextTx() for the event loop. - src/main_kiss_modem.cpp: event-driven composition root; runs the radio maintenance the Dispatcher would. Identity in /lfs/repeater/_main.id. - adapters/transport/ZephyrUartStream: Arduino Stream over IRQ RX/TX rings. - boards/common/kiss_modem.conf: role, BT off, console driver off. - LoRaRadio::getCurrentRSSI(), Print::availableForWrite(). - UI mesh-action stubs for every non-companion role. Tested on 2x XIAO ESP32-C3 + Wio-SX1262 at 869.423 MHz SF7/62.5/CR5. Built for xiao_esp32c3, rak4631, lora_e5_mini; host tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
117 lines
3.0 KiB
C++
117 lines
3.0 KiB
C++
/*
|
|
* SPDX-License-Identifier: MIT
|
|
* The slice of Arduino's Print / Stream API that code ported verbatim from
|
|
* upstream MeshCore uses, so it compiles unchanged.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
class Print {
|
|
public:
|
|
virtual ~Print() {}
|
|
|
|
virtual size_t write(uint8_t c) = 0;
|
|
virtual size_t write(const uint8_t *buffer, size_t size)
|
|
{
|
|
size_t n = 0;
|
|
while (n < size && write(buffer[n])) {
|
|
n++;
|
|
}
|
|
return n;
|
|
}
|
|
size_t write(const char *str) { return str ? write((const uint8_t *)str, strlen(str)) : 0; }
|
|
virtual int availableForWrite() { return 0; }
|
|
|
|
size_t print(char c) { return write((uint8_t)c); }
|
|
size_t print(const char *str) { return write(str); }
|
|
size_t println(const char *str) { return write(str) + write("\r\n"); }
|
|
|
|
/* Numbers, as Arduino prints them (ConfigSerializer). int32_t is long on
|
|
* some targets and int on others, so both widths are here. */
|
|
size_t print(long n, int base = 10)
|
|
{
|
|
char buf[24];
|
|
int len = (base == 16) ? snprintf(buf, sizeof(buf), "%lx", (unsigned long)n)
|
|
: snprintf(buf, sizeof(buf), "%ld", n);
|
|
return write((const uint8_t *)buf, (size_t)len);
|
|
}
|
|
size_t print(unsigned long n, int base = 10)
|
|
{
|
|
char buf[24];
|
|
int len = snprintf(buf, sizeof(buf), (base == 16) ? "%lx" : "%lu", n);
|
|
return write((const uint8_t *)buf, (size_t)len);
|
|
}
|
|
size_t print(int n, int base = 10) { return print((long)n, base); }
|
|
size_t print(unsigned int n, int base = 10) { return print((unsigned long)n, base); }
|
|
|
|
/* Arduino's Print::printFloat, digit for digit, so a value is written as
|
|
* upstream would write it, without relying on libc float formatting. */
|
|
size_t print(double number, int digits = 2)
|
|
{
|
|
if (number != number) {
|
|
return print("nan");
|
|
}
|
|
if (number > 4294967040.0) {
|
|
return print("ovf");
|
|
}
|
|
if (number < -4294967040.0) {
|
|
return print("-ovf");
|
|
}
|
|
size_t n = 0;
|
|
|
|
if (number < 0.0) {
|
|
n += print('-');
|
|
number = -number;
|
|
}
|
|
double rounding = 0.5;
|
|
|
|
for (int i = 0; i < digits; ++i) {
|
|
rounding /= 10.0;
|
|
}
|
|
number += rounding;
|
|
unsigned long int_part = (unsigned long)number;
|
|
double remainder = number - (double)int_part;
|
|
|
|
n += print(int_part);
|
|
if (digits > 0) {
|
|
n += print('.');
|
|
}
|
|
while (digits-- > 0) {
|
|
remainder *= 10.0;
|
|
unsigned int to_print = (unsigned int)remainder;
|
|
|
|
n += print(to_print);
|
|
remainder -= to_print;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
/* Longer output is truncated; the ported callers print short lines. */
|
|
size_t printf(const char *format, ...) __attribute__((format(printf, 2, 3)))
|
|
{
|
|
char buf[160];
|
|
va_list args;
|
|
va_start(args, format);
|
|
int n = vsnprintf(buf, sizeof(buf), format, args);
|
|
va_end(args);
|
|
if (n < 0) {
|
|
return 0;
|
|
}
|
|
return write((const uint8_t *)buf, (size_t)n < sizeof(buf) ? (size_t)n : sizeof(buf) - 1);
|
|
}
|
|
};
|
|
|
|
class Stream : public Print {
|
|
public:
|
|
virtual int available() = 0;
|
|
virtual int read() = 0;
|
|
virtual int peek() = 0;
|
|
virtual void flush() {}
|
|
};
|