diff --git a/src/main.cpp b/src/main.cpp index a8282de..273b420 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -175,9 +175,12 @@ static volatile bool capBufFull = false; // set by ISR when buffer fills static uint32_t capRecBits = 0; // bits stored after recording static float capFreq = 315.0f; // frequency at capture time static uint8_t capRadioNum = 1; // 1 or 2 +static bool capIsOOK = true; // modulation: true=OOK, false=2-FSK static gpio_num_t capGdoPin = (gpio_num_t)CC1101_1_GDO0; static hw_timer_t* capTimer = nullptr; -static volatile uint32_t capTransitions = 0; // edge count — used to detect live signal +static volatile uint32_t capTransitions = 0; // edge count — used for bitrate estimation +static volatile uint32_t capLongRuns = 0; // counts stable runs (>15 samples) to filter out thermal noise +static uint32_t capCurrentRun = 0; // current stable run length static bool capSigNotified = false; // fire OLED notification only once per session static bool capPrevJamming = false; // jammingEnabled state saved before capture pauses it @@ -186,10 +189,16 @@ static void IRAM_ATTR capRecordISR() { const uint32_t i = capIdx; if (i >= (uint32_t)(CAP_BUF_BYTES * 8)) { capBufFull = true; return; } const uint8_t bit = (uint8_t)((REG_READ(GPIO_IN_REG) >> capGdoPin) & 1u); - // Count transitions — cheap edge detection without extra storage + // Count transitions and long stable runs (software squelch) if (i > 0) { const uint8_t prev = (capBuf[(i-1) >> 3] >> ((i-1) & 7)) & 1u; - if (bit != prev) capTransitions++; + if (bit == prev) { + capCurrentRun++; + } else { + capTransitions++; + if (capCurrentRun > 15) capLongRuns++; + capCurrentRun = 0; + } } if (bit) capBuf[i >> 3] |= (1u << (i & 7)); else capBuf[i >> 3] &= ~(1u << (i & 7)); @@ -214,22 +223,26 @@ static void capTimerStop() { } } -static void startCapture(float freq, uint8_t radioNum) { +static void startCapture(float freq, uint8_t radioNum, bool isOOK) { capPrevJamming = jammingEnabled; // save before stopJamming() clears it stopJamming(); capFreq = freq; capRadioNum = radioNum; + capIsOOK = isOOK; capGdoPin = (radioNum == 1) ? (gpio_num_t)CC1101_1_GDO0 : (gpio_num_t)CC1101_2_GDO0; capIdx = 0; capBufFull = false; capRecBits = 0; capTransitions = 0; + capLongRuns = 0; + capCurrentRun = 0; capSigNotified = false; memset(capBuf, 0, sizeof(capBuf)); CC1101& radio = (radioNum == 1) ? radio1 : radio2; radio.standby(); + radio.setOOK(isOOK); radio.setFrequency(freq); radio.setFrequencyDeviation(JAM_FREQ_DEV_KHZ); radio.receiveDirect(); // GDO0 becomes demodulated-data output from CC1101 @@ -261,6 +274,7 @@ static void startReplay(uint8_t radioNum) { CC1101& radio = (radioNum == 1) ? radio1 : radio2; radio.standby(); + radio.setOOK(capIsOOK); radio.setFrequency(capFreq); radio.setFrequencyDeviation(JAM_FREQ_DEV_KHZ); radio.transmitDirectAsync(); // GDO0 becomes data input to CC1101 @@ -296,6 +310,7 @@ static void stopCapture() { gpio_set_direction(capGdoPin, GPIO_MODE_OUTPUT); gpio_set_level(capGdoPin, 0); if (capPrevJamming) { + capPrevJamming = false; jammingEnabled = true; startJamming(); } @@ -739,8 +754,10 @@ static void oledTick() { // Consume encoder — manual page change resets the auto-cycle timer if (encDelta != 0) { + noInterrupts(); const int8_t d = encDelta; encDelta = 0; + interrupts(); oledPage = (uint8_t)((oledPage + 3 + (d > 0 ? 1 : -1)) % 3); oledPageMs = now; // reset auto-advance so page stays visible } @@ -1024,6 +1041,13 @@ pre{margin:0;padding:8px;background:#020504;border:1px solid #122814;height:28vh +
+ + +