Initial commit

This commit is contained in:
2026-01-20 01:39:06 +01:00
commit 6f308ad590
34 changed files with 2068 additions and 0 deletions

102
src/lora_transport.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include "lora_transport.h"
#include <LoRa.h>
#include <SPI.h>
static uint16_t crc16_ccitt(const uint8_t *data, size_t len) {
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; ++i) {
crc ^= static_cast<uint16_t>(data[i]) << 8;
for (uint8_t b = 0; b < 8; ++b) {
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc <<= 1;
}
}
}
return crc;
}
void lora_init() {
SPI.begin(PIN_LORA_SCK, PIN_LORA_MISO, PIN_LORA_MOSI, PIN_LORA_NSS);
LoRa.setPins(PIN_LORA_NSS, PIN_LORA_RST, PIN_LORA_DIO0);
LoRa.begin(LORA_FREQUENCY);
LoRa.setSpreadingFactor(LORA_SPREADING_FACTOR);
LoRa.setSignalBandwidth(LORA_BANDWIDTH);
LoRa.setCodingRate4(LORA_CODING_RATE);
LoRa.enableCrc();
LoRa.setSyncWord(LORA_SYNC_WORD);
}
bool lora_send(const LoraPacket &pkt) {
uint8_t buffer[5 + LORA_MAX_PAYLOAD + 2];
size_t idx = 0;
buffer[idx++] = pkt.protocol_version;
buffer[idx++] = static_cast<uint8_t>(pkt.role);
buffer[idx++] = static_cast<uint8_t>(pkt.device_id_short >> 8);
buffer[idx++] = static_cast<uint8_t>(pkt.device_id_short & 0xFF);
buffer[idx++] = static_cast<uint8_t>(pkt.payload_type);
if (pkt.payload_len > LORA_MAX_PAYLOAD) {
return false;
}
memcpy(&buffer[idx], pkt.payload, pkt.payload_len);
idx += pkt.payload_len;
uint16_t crc = crc16_ccitt(buffer, idx);
buffer[idx++] = static_cast<uint8_t>(crc >> 8);
buffer[idx++] = static_cast<uint8_t>(crc & 0xFF);
LoRa.beginPacket();
LoRa.write(buffer, idx);
LoRa.endPacket();
return true;
}
bool lora_receive(LoraPacket &pkt, uint32_t timeout_ms) {
uint32_t start = millis();
while (true) {
int packet_size = LoRa.parsePacket();
if (packet_size > 0) {
if (packet_size < 7) {
while (LoRa.available()) {
LoRa.read();
}
return false;
}
uint8_t buffer[5 + LORA_MAX_PAYLOAD + 2];
size_t len = 0;
while (LoRa.available() && len < sizeof(buffer)) {
buffer[len++] = LoRa.read();
}
if (len < 7) {
return false;
}
uint16_t crc_calc = crc16_ccitt(buffer, len - 2);
uint16_t crc_rx = static_cast<uint16_t>(buffer[len - 2] << 8) | buffer[len - 1];
if (crc_calc != crc_rx) {
return false;
}
pkt.protocol_version = buffer[0];
pkt.role = static_cast<DeviceRole>(buffer[1]);
pkt.device_id_short = static_cast<uint16_t>(buffer[2] << 8) | buffer[3];
pkt.payload_type = static_cast<PayloadType>(buffer[4]);
pkt.payload_len = len - 7;
if (pkt.payload_len > LORA_MAX_PAYLOAD) {
return false;
}
memcpy(pkt.payload, &buffer[5], pkt.payload_len);
return true;
}
if (timeout_ms == 0 || millis() - start >= timeout_ms) {
return false;
}
delay(5);
}
}