Files
MeshCore/tools/hil/ProfileChannelTrace.h
T
mikecarper bd30388436 Speed up SX1262 profile switching and verify radio lab behavior
Keep TCXO warm during owned dual-profile retunes, batch modulation setup, and enable guarded fast RX with buffered 8 MHz SPI on XIAO S3 WIO and Indicator LoRa. Preserve lifecycle invalidation, packet guards, rollback, and existing scheduling budgets.

Add reliable sequence-scoped USB lab transport, native regression coverage, bounded channel and preamble diagnostics, and byte-exact measurement records including failed experiments and qualification limits.
2026-09-14 01:22:09 -07:00

46 lines
1.9 KiB
C

#pragma once
// HIL only. Observe existing SPI reads/clears without changing their bytes.
// Optional early IRQ polling is performed by the channel scheduler, not here.
struct ChannelTraceEvent {
uint32_t us, a, b;
uint16_t irq;
uint8_t channel, kind;
};
struct ChannelTrace {
enum : uint8_t { Arm=1, Irq=2, Clear=3, Hop=4, Hold=5, Packet=6, Timeout=7 };
static constexpr unsigned Capacity=4096;
ChannelTraceEvent events[Capacity];
bool active=false, enabled=false;
unsigned size=0, overflow=0;
uint32_t origin=0, sequence=0, pollAt=0, pollCount=0, pollTotalUs=0, pollMaxUs=0;
uint16_t irq=0;
uint32_t rfWord=0, txWord=0, txCommandUs=0;
uint8_t channel=0;
void add(uint8_t kind,uint32_t a=0,uint32_t b=0) {
if(!active) return;
if(size==Capacity) { ++overflow;return; }
events[size++]={uint32_t(micros()-origin),a,b,irq,channel,kind};
}
void arm(uint32_t seq,uint8_t current,uint8_t expected,uint32_t visitAge) {
size=overflow=0;origin=micros();sequence=seq;channel=current;irq=0;
pollAt=origin;pollCount=pollTotalUs=pollMaxUs=0;active=enabled;
add(Arm,expected,visitAge);
}
void observe(const uint8_t* out,size_t len,const uint8_t* in) {
if(!out || !in) return;
// Track actual command bytes even outside a capture, not just SW labels.
if(len==5 && out[0]==0x86)
rfWord=uint32_t(out[1])<<24 | uint32_t(out[2])<<16 | uint32_t(out[3])<<8 | out[4];
if(len==4 && out[0]==0x83) { txCommandUs=micros();txWord=rfWord; }
if(!active) return;
// Pinned SX126x Module: opcode, status dummy, two big-endian IRQ bytes.
if(len==4 && out[0]==0x12) {
const uint16_t value=uint16_t(in[2])<<8 | in[3];
if(value!=irq) { irq=value;add(Irq); }
} else if(len==3 && out[0]==0x02 && irq) {
add(Clear,uint16_t(out[1])<<8 | out[2]);
// Do not predict the clear's success: next actual read establishes it.
}
}
} channelTrace;