@@ -6,7 +6,7 @@
|
||||
#define CC1101_1_GDO0 4
|
||||
#define CC1101_1_FREQ_MHZ 315.0f
|
||||
|
||||
// CC1101 #2 (433 MHz band — jam center 433.46 MHz, midpoint of 433–433.92 MHz)
|
||||
// CC1101 #2 (433.92 MHz band)
|
||||
#define CC1101_2_CS 8
|
||||
#define CC1101_2_GDO0 5
|
||||
#define CC1101_2_FREQ_MHZ 433.92f
|
||||
@@ -35,27 +35,19 @@
|
||||
#define JAM_BITRATE_KBPS 250.0f // baseband / channel filter context for RadioLib begin()
|
||||
#define JAM_FREQ_DEV_KHZ 380.0f // default passed to begin(); per-radio deviation applied after init
|
||||
#define JAM_RX_BW_KHZ 812.0f // wide RX BW for begin()
|
||||
// GDO0 toggle rate during jam.
|
||||
// 500 kHz (2 µs period = 480 ESP32-S3 cycles) leaves ~60% headroom over ISR overhead (~200 cycles),
|
||||
// preventing the interrupt storm / WDT boot-loop that 1 MHz caused (240 cycles < ISR overhead).
|
||||
// OOK on R1: ±500 kHz main lobe around 315 MHz + strong sidebands covering 314–316 MHz.
|
||||
// 2-FSK 380 kHz dev on R2: tone pair 433.08/433.84 MHz + 250 kHz sideband spread → 432.8–434.1 MHz,
|
||||
// fully covering the 433–433.92 MHz band.
|
||||
#define JAM_LFSR_KEY_HZ 500000
|
||||
// GDO0 toggle rate during jam (1 MHz timer tick). Higher → wider AM/FM splatter on both carriers; 100 kHz typical.
|
||||
#define JAM_LFSR_KEY_HZ 100000
|
||||
|
||||
// Fixed dual-carrier jamming: each radio holds one frequency at full TX power (TI CC1101 freq + deviation).
|
||||
// Many NA ~315 MHz RKE remotes are ASK/OOK (see TI CC1101 datasheet MDMCFG2.MOD_FORMAT). Jam path uses OOK on
|
||||
// R1 so LFSR on GDO0 keys the PA (broad AM sidebands). Set JAM_R1_USE_OOK 0 for 2-FSK only at JAM_DEV_KHZ_R1_WIDE.
|
||||
// Fobs may sit on 314.8–315.2 MHz — measure with an SDR and retune JAM_LOCK_FREQ_1_MHZ if needed.
|
||||
// R1: 315.0 MHz center — OOK+LFSR main lobe covers 314–316 MHz (full 2 MHz span of NA fob band).
|
||||
// R2: 433.46 MHz center — midpoint of 433–433.92 MHz; with 380 kHz dev + 1 MHz LFSR sidebands
|
||||
// the noise covers 432.1–434.8 MHz, blanketing the entire 433–433.92 MHz EU/world fob band.
|
||||
#define JAM_LOCK_FREQ_1_MHZ 315.0f
|
||||
#define JAM_LOCK_FREQ_2_MHZ 433.46f
|
||||
#define JAM_LOCK_FREQ_2_MHZ 433.92f
|
||||
#define JAM_DEV_KHZ_R2_WIDE 380.0f
|
||||
#define JAM_DEV_KHZ_R1_NARROW 25.0f // probe / RadioLib begin() only
|
||||
#define JAM_DEV_KHZ_R1_WIDE 380.0f // max CC1101 2-FSK deviation on R1 when OOK fails or JAM_R1_USE_OOK=0
|
||||
#define JAM_R1_USE_OOK 1 // 1 = R1 jam ASK/OOK (direct LFSR main lobe = 314–316 MHz); 0 = 2-FSK
|
||||
#define JAM_DEV_KHZ_R1_WIDE 200.0f // FSK jam spread when JAM_R1_USE_OOK is 0 (or OOK setup fails)
|
||||
#define JAM_R1_USE_OOK 1 // 1 = R1 jam ASK/OOK (typical NA); 0 = wide 2-FSK on R1
|
||||
|
||||
// Precision jam: narrow 2-FSK on both + slower LFSR (energy in a smaller RF slice).
|
||||
#define JAM_PRECISION_DEV_R1_KHZ 28.0f
|
||||
@@ -72,11 +64,7 @@
|
||||
#define JAM_FLOOD_DEV_R1_KHZ 140.0f
|
||||
#define JAM_FLOOD_DEV_R2_KHZ 200.0f
|
||||
|
||||
// Special/Flood jam timing: CC1101 at 250 kbps takes 2.59ms to send a 61-byte packet (preamble+sync+data).
|
||||
// 3ms restart gap allows each packet to complete naturally before startTransmit() is called again.
|
||||
// Duty cycle: ~85%. 10ms (original cypher-pulse) only achieves 26% — too many gaps for rolling-code fobs.
|
||||
#define JAM_SPECIAL_DELAY_MS 3
|
||||
#define JAM_FLOOD_DELAY_MS 3
|
||||
// Special jam: 60-byte random payloads with 10ms delay (cypher-pulse exact clone).
|
||||
|
||||
// SmartRF-style dump: config space only (TI SWRS061); PATABLE/ strobes not included.
|
||||
#define CC1101_CFG_REG_LAST 0x2E
|
||||
|
||||
55
src/main.cpp
55
src/main.cpp
@@ -1065,49 +1065,39 @@ static void stopJamming() {
|
||||
}
|
||||
|
||||
// Packet-flood jam: PRNG frames on both radios (shared SPI — sequential).
|
||||
//
|
||||
// Uses startTransmit() (non-blocking) so the CC1101 finishes each packet autonomously
|
||||
// and returns to IDLE on its own. The 3ms guard (JAM_SPECIAL_DELAY_MS) is just over
|
||||
// the 2.59ms on-air time for a 61-byte packet at 250 kbps, so we restart cleanly
|
||||
// without ever cutting a packet short. Duty cycle: ~85% vs. the previous 26%.
|
||||
//
|
||||
// RadioLib's transmit() wraps startTransmit()+finishTransmit(); finishTransmit() has
|
||||
// a timeout bug at 250 kbps (timeout = 0ms) causing it to immediately return
|
||||
// RADIOLIB_ERR_TX_TIMEOUT while the CC1101 is still transmitting. Using startTransmit()
|
||||
// directly avoids that entirely — we just let the CC1101 run and restart after 3ms.
|
||||
static void jamFloodTick() {
|
||||
if (!s_floodJamActive || !jammingEnabled) return;
|
||||
static uint8_t pkt[JAM_FLOOD_PKT_BYTES];
|
||||
static uint32_t lastMs = 0;
|
||||
|
||||
const uint32_t now = millis();
|
||||
const uint32_t delay = (jamMode == JamMode::SPECIAL)
|
||||
? (uint32_t)JAM_SPECIAL_DELAY_MS
|
||||
: (uint32_t)JAM_FLOOD_DELAY_MS;
|
||||
|
||||
if ((uint32_t)(now - lastMs) < delay) return;
|
||||
lastMs = now; // timestamp BEFORE SPI — gives tightest pacing
|
||||
|
||||
static uint32_t lastMs;
|
||||
|
||||
if (jamMode == JamMode::SPECIAL) {
|
||||
// Exact cypher-pulse clone: 60-byte payload, 10ms wait, blocking transmit.
|
||||
if ((uint32_t)(millis() - lastMs) < 10u) return;
|
||||
|
||||
if (radio1Status == 2) {
|
||||
esp_fill_random(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
(void)radio1.startTransmit(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
esp_fill_random(pkt, 60);
|
||||
(void)radio1.transmit(pkt, 60);
|
||||
}
|
||||
if (radio2Status == 2) {
|
||||
esp_fill_random(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
(void)radio2.startTransmit(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
esp_fill_random(pkt, 60);
|
||||
(void)radio2.transmit(pkt, 60);
|
||||
}
|
||||
} else {
|
||||
// FLOOD mode: same non-blocking approach, same packet size.
|
||||
// Flood: full transmit() — startTransmit() without finishTransmit() was aborting
|
||||
// each packet on the next tick (standby() at start of TX), so almost no on-air energy.
|
||||
if ((uint32_t)(millis() - lastMs) < 2u) return;
|
||||
|
||||
if (radio1Status == 2) {
|
||||
esp_fill_random(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
(void)radio1.startTransmit(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
esp_fill_random(pkt, sizeof(pkt));
|
||||
(void)radio1.transmit(pkt, sizeof(pkt));
|
||||
}
|
||||
if (radio2Status == 2) {
|
||||
esp_fill_random(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
(void)radio2.startTransmit(pkt, JAM_FLOOD_PKT_BYTES);
|
||||
esp_fill_random(pkt, sizeof(pkt));
|
||||
(void)radio2.transmit(pkt, sizeof(pkt));
|
||||
}
|
||||
}
|
||||
|
||||
lastMs = millis(); // record time AFTER transmit completes
|
||||
}
|
||||
|
||||
static int hexNibble(char c) {
|
||||
@@ -2260,8 +2250,7 @@ static void handleRoot() {
|
||||
}
|
||||
server.setContentLength(sizeof(kHtml) - 1);
|
||||
server.send(200, "text/html; charset=utf-8", "");
|
||||
// Use length-aware overload — avoids constructing a 15 KB String on a fragmented heap.
|
||||
server.sendContent(kHtml, sizeof(kHtml) - 1);
|
||||
server.sendContent(kHtml);
|
||||
}
|
||||
|
||||
static void handleLog() {
|
||||
@@ -2613,8 +2602,8 @@ void setup() {
|
||||
jamPower = kPowerTable[jamPowerIdx];
|
||||
preferences.putInt("jamPowerIdx", (int)jamPowerIdx);
|
||||
capHistoryLoad();
|
||||
// Boot policy: Direct mode — OOK + 1 MHz LFSR, ~100% duty cycle, covers 314–316 MHz and 432–434 MHz.
|
||||
jamMode = JamMode::DIRECT;
|
||||
// Boot policy: always start in Special jam (60 B PRNG / 10 ms); persists to NVS for startJamming().
|
||||
jamMode = JamMode::SPECIAL;
|
||||
preferences.putUChar("jamMode", (uint8_t)jamMode);
|
||||
logLine("[NVS] jam at boot: always ON | jamPower=" + String(jamPower) + " dBm | jam_mode=" +
|
||||
String(jamModeToCstr(jamMode)) + " (default on power-up)");
|
||||
|
||||
Reference in New Issue
Block a user