summaryrefslogtreecommitdiff
path: root/src/rf
diff options
context:
space:
mode:
Diffstat (limited to 'src/rf')
-rw-r--r--src/rf/cc1101.cpp205
-rw-r--r--src/rf/cc1101.h9
-rw-r--r--src/rf/nrf24.cpp249
-rw-r--r--src/rf/nrf24.h13
4 files changed, 476 insertions, 0 deletions
diff --git a/src/rf/cc1101.cpp b/src/rf/cc1101.cpp
new file mode 100644
index 0000000..603a0d7
--- /dev/null
+++ b/src/rf/cc1101.cpp
@@ -0,0 +1,205 @@
+#include <Arduino.h>
+#include "../libs/ELECHOUSE_CC1101_SRC_DRV.h"
+#include "cc1101.h"
+#include "../config.h"
+#include "SPI.h"
+
+// ===== CONFIG =====
+#define RAW_BUF_MAX 512
+
+// ===== STATE =====
+static bool cc1101Inited = false;
+
+// ===== CAPTURE STATE =====
+volatile unsigned long captureBuffer[RAW_BUF_MAX];
+volatile int pulseIndex = 0;
+volatile unsigned long lastEdgeTime = 0;
+volatile bool capturing = false;
+
+// ===== RF SETTINGS =====
+float currentFreq = 433.92;
+float dataRate = 3.79372;
+float deviation = 0.0;
+float rxBW = 325.0;
+int powerLevel = 10;
+
+// ===== ISR =====
+void IRAM_ATTR pulseISR()
+{
+ unsigned long now = micros();
+
+ if (!capturing) return;
+ if (pulseIndex >= RAW_BUF_MAX) return;
+
+ unsigned long duration = now - lastEdgeTime;
+
+ if (duration < 150) return;
+
+ captureBuffer[pulseIndex++] = duration;
+ lastEdgeTime = now;
+}
+
+// ===== OOK SETUP =====
+void setupOOKMode()
+{
+ ELECHOUSE_cc1101.SetRx();
+ ELECHOUSE_cc1101.setMHZ(currentFreq);
+
+ ELECHOUSE_cc1101.setModulation(2); // ASK/OOK
+ ELECHOUSE_cc1101.setDRate(dataRate);
+ ELECHOUSE_cc1101.setDeviation(0);
+ ELECHOUSE_cc1101.setRxBW(rxBW);
+ ELECHOUSE_cc1101.setSyncMode(0);
+ ELECHOUSE_cc1101.setPA(powerLevel);
+}
+
+// ===== INIT (LAZY, SAFE) =====
+// ================= CC1101 INIT =================
+bool initCC1101()
+{
+ Serial.println();
+ Serial.println("===== CC1101 INIT =====");
+
+ // ===== SPI =====
+ SPI.begin(
+ cc1101_SCK,
+ cc1101_MISO,
+ cc1101_MOSI,
+ CC1101_CS
+ );
+
+ pinMode(CC1101_CS, OUTPUT);
+ digitalWrite(CC1101_CS, HIGH);
+
+ delay(100);
+
+ // ===== GDO =====
+ ELECHOUSE_cc1101.setGDO(
+ CC1101_GDO0,
+ -1
+ );
+
+ ELECHOUSE_cc1101.setSpiPin(
+ cc1101_SCK,
+ cc1101_MISO,
+ cc1101_MOSI,
+ CC1101_CS
+ );
+
+ // ===== DETECT =====
+ Serial.println("Checking chip...");
+
+ if (!ELECHOUSE_cc1101.getCC1101())
+ {
+ Serial.println("❌ CC1101 NOT FOUND");
+ return false;
+ }
+
+ Serial.println("✅ CC1101 FOUND");
+
+ // ===== IMPORTANT =====
+ // DO NOT CALL Init()
+ // it freezes on some ESP32-S3 setups
+
+ // ===== MANUAL CONFIG =====
+ ELECHOUSE_cc1101.setMHZ(currentFreq);
+
+ // 2 = ASK/OOK
+ ELECHOUSE_cc1101.setModulation(2);
+
+ ELECHOUSE_cc1101.setDRate(dataRate);
+
+ ELECHOUSE_cc1101.setRxBW(rxBW);
+
+ ELECHOUSE_cc1101.setDeviation(0);
+
+ // disable sync requirement
+ ELECHOUSE_cc1101.setSyncMode(0);
+
+ ELECHOUSE_cc1101.setPA(powerLevel);
+
+ // async serial mode
+ ELECHOUSE_cc1101.setCCMode(0);
+
+ // enter RX
+ ELECHOUSE_cc1101.SetRx();
+
+ pinMode(CC1101_GDO0, INPUT);
+
+ Serial.println("✅ RX MODE READY");
+
+ cc1101Inited = true;
+ return true;
+}
+// ===== CAPTURE CONTROL =====
+void startCapture()
+{
+ pulseIndex = 0;
+ capturing = true;
+ lastEdgeTime = micros();
+
+ attachInterrupt(
+ digitalPinToInterrupt(CC1101_GDO0),
+ pulseISR,
+ CHANGE
+ );
+
+ Serial.println("Looking for RF... ");
+}
+
+bool isCC1101Ready() {
+ return cc1101Inited;
+}
+
+void stopCapture()
+{
+ capturing = false;
+
+ detachInterrupt(digitalPinToInterrupt(CC1101_GDO0));
+
+ Serial.println("Capture stopped");
+}
+
+// ===== DEBUG PRINT =====
+void printCapture()
+{
+ Serial.println("Captured pulses:");
+
+ for (int i = 0; i < pulseIndex; i++)
+ {
+ Serial.println(captureBuffer[i]);
+ }
+}
+
+
+// ================= REPLAY =================
+void replaySignal()
+{
+ Serial.println();
+ Serial.println("Replaying signal...");
+
+ stopCapture();
+
+ ELECHOUSE_cc1101.SetTx();
+
+ pinMode(CC1101_GDO0, OUTPUT);
+
+ for (int i = 0; i < pulseIndex; i++)
+ {
+ digitalWrite(
+ CC1101_GDO0,
+ (i % 2 == 0) ? HIGH : LOW
+ );
+
+ delayMicroseconds(captureBuffer[i]);
+ }
+
+ digitalWrite(CC1101_GDO0, LOW);
+
+ ELECHOUSE_cc1101.SetRx();
+
+ pinMode(CC1101_GDO0, INPUT);
+
+ Serial.println("Replay complete");
+}
+
diff --git a/src/rf/cc1101.h b/src/rf/cc1101.h
new file mode 100644
index 0000000..a403edb
--- /dev/null
+++ b/src/rf/cc1101.h
@@ -0,0 +1,9 @@
+#pragma once
+
+bool initCC1101();
+bool isCC1101Ready();
+
+void startCapture();
+void stopCapture();
+void printCapture();
+void replaySignal();
diff --git a/src/rf/nrf24.cpp b/src/rf/nrf24.cpp
new file mode 100644
index 0000000..0479985
--- /dev/null
+++ b/src/rf/nrf24.cpp
@@ -0,0 +1,249 @@
+#include <Arduino.h>
+#include <RF24.h>
+#include "nrf24.h"
+#include "../ui/display.h"
+#include "../buttons.h"
+#define JAM_DURATION 500
+
+extern SPIClass *RADIO_SPI;
+extern RF24 radio1;
+extern RF24 radio2;
+
+// ============ CHANNELS =============
+const byte bleChannels[] = {2, 26, 80};
+const byte bluetoothChannels[] = {
+ 32, 34, 46, 48, 50, 52,
+ 0, 1, 2, 4, 6, 8,
+ 22, 24, 26, 28, 30,
+ 74, 76, 78, 80
+};
+const byte wifiChannels[] = {
+ 12, 17, 22, 27, 32,
+ 37, 42, 47, 52, 57,
+ 62, 67, 72
+};
+const byte usbWireless_channels[] = {40, 50, 60};
+const byte videoTransmitter_channels[] = {70, 75, 80};
+const byte zigbee_channels[] = {11, 15, 20, 25};
+const byte rc_channels[] = {1, 3, 5, 7};
+
+void initNRF(RF24 &radio)
+{
+ if (!radio.begin(RADIO_SPI)) {
+ Serial.println("NRF not found");
+ return;
+ }
+
+ radio.setAutoAck(false);
+ radio.stopListening();
+ radio.setRetries(0, 0);
+ radio.setPALevel(RF24_PA_MAX, true);
+ radio.setDataRate(RF24_2MBPS);
+ radio.openWritingPipe(0xE7E7E7E7E7LL);
+ radio.setCRCLength(RF24_CRC_DISABLED);
+ Serial.println("NRF Initialized");
+
+}
+
+
+
+//void startBleJammer() {
+// initNRF(radio1);
+// initNRF(radio2);
+//
+// Serial.println("NRF JAMMER STARTED");
+//
+// const char payload[] = "xxxxxxxxxxxxxxxx";
+//
+// u8g2.clearBuffer();
+// u8g2.drawStr(0, 10, "Jamming:");
+// u8g2.setCursor(60, 10);
+// u8g2.print("Bluetooth");
+// u8g2.sendBuffer();
+//
+// while(true) {
+//
+// // Channels (you can change this set)
+// const byte channels[] = {2, 26, 80};
+//
+//
+// for (int i = 0; i < sizeof(channels); i++) {
+// radio1.setChannel(channels[i]);
+// radio1.write(&payload, sizeof(payload));
+// //radio2.setChannel(channels[i]);
+// //radio2.write(&payload, sizeof(payload));
+// }
+//
+// if (btnBack())
+// {
+// Serial.println("Jammer stopped");
+// return;
+// }
+// }
+//
+//}
+//
+//void startBluetoothJammer()
+//{
+// initNRF(radio1);
+// initNRF(radio2);
+//
+// Serial.println("NRF JAMMER STARTED");
+//
+// const char payload[] = "xxxxxxxxxxxxxxxx";
+//
+// u8g2.clearBuffer();
+// u8g2.drawStr(0, 10, "Jamming:");
+// u8g2.setCursor(60, 10);
+// u8g2.print("Bluetooth");
+// u8g2.sendBuffer();
+//
+// while(true) {
+//
+// // Channels (you can change this set)
+// const byte channels[] = {32, 34, 46, 48, 50, 52, 0, 1, 2, 4, 6, 8, 22, 24, 26, 28, 30, 74, 76, 78, 80};
+//
+//
+// for (int i = 0; i < sizeof(channels); i++) {
+// radio1.setChannel(channels[i]);
+// radio1.write(&payload, sizeof(payload));
+// //radio2.setChannel(channels[i]);
+// //radio2.write(&payload, sizeof(payload));
+// }
+//
+// if (btnBack())
+// {
+// Serial.println("Jammer stopped");
+// return;
+// }
+// }
+//}
+
+void startJammer(const char* name, const byte* channels, size_t channelCount)
+{
+ initNRF(radio1);
+ initNRF(radio2);
+
+ Serial.println("NRF JAMMER STARTED");
+
+ const char payload[] = "xxxxxxxxxxxxxxxx";
+
+ u8g2.clearBuffer();
+ u8g2.setFont(u8g2_font_6x10_tr);
+ u8g2.drawStr(0, 15, "NRF24 Jammer");
+ u8g2.drawStr(0, 35, name);
+ u8g2.drawStr(0, 55, "BACK = Exit");
+ u8g2.sendBuffer();
+
+ while (true)
+ {
+ for (size_t i = 0; i < channelCount; i++)
+ {
+ //radio1.setChannel(channels[i]);
+ //radio1.write(&payload, sizeof(payload));
+
+ // Optional second NRF
+ // radio2.setChannel(channels[i]);
+ // radio2.write(&payload, sizeof(payload));
+
+
+ radio1.setChannel(channels[i]);
+ radio2.setChannel(channels[(i + 1) % channelCount]);
+
+ radio1.writeFast(&payload, sizeof(payload));
+ radio2.writeFast(&payload, sizeof(payload));
+ }
+
+ if (btnBack())
+ {
+ Serial.println("Jammer stopped");
+ radio1.powerDown();
+ radio2.powerDown();
+ return;
+ }
+ }
+
+ //while (true) {
+ //for (size_t i = 0; i < channelCount; i++)
+ //{
+ // radio1.setChannel(channels[i]);
+ // radio2.setChannel(channels[(i + 1) % channelCount]);
+
+ // radio1.writeFast(&payload, sizeof(payload));
+ // radio2.writeFast(&payload, sizeof(payload));
+
+ // radio1.txStandBy(1);
+ // radio2.txStandBy(1);
+
+ // delayMicroseconds(200);
+ //}
+
+
+ //if (btnBack())
+ //{
+ // Serial.println("Jammer stopped");
+
+ // radio1.powerDown();
+ // radio2.powerDown();
+
+ // return;
+ //}
+//}
+}
+
+void NRFToolsMenu(int index) {
+ switch (index) {
+ case 0:
+ // startBleJammer();
+ // BLE
+ startJammer(
+ "BLE",
+ bleChannels,
+ sizeof(bleChannels) / sizeof(bleChannels[0])
+ );
+
+ break;
+ case 1:
+ // startBluetoothJammer();
+ // Bluetooth
+ startJammer(
+ "Bluetooth",
+ bluetoothChannels,
+ sizeof(bluetoothChannels) / sizeof(bluetoothChannels[0])
+ );
+ break;
+
+ case 2:
+ startJammer(
+ "WiFi",
+ wifiChannels,
+ sizeof(wifiChannels) / sizeof(wifiChannels[0])
+ );
+ break;
+ case 3:
+ startJammer(
+ "USB Wireless",
+ usbWireless_channels,
+ sizeof(usbWireless_channels) / sizeof(usbWireless_channels[0])
+ );
+ break;
+ case 4:
+ startJammer(
+ "Video TX",
+ videoTransmitter_channels,
+ sizeof(videoTransmitter_channels) / sizeof(videoTransmitter_channels[0])
+ );
+ break;
+ case 5:
+ break;
+ startJammer(
+ "RC",
+ rc_channels,
+ sizeof(rc_channels) / sizeof(rc_channels[0])
+ );
+ break;
+ case 6:
+
+ break;
+}
+ }
diff --git a/src/rf/nrf24.h b/src/rf/nrf24.h
new file mode 100644
index 0000000..308bbc4
--- /dev/null
+++ b/src/rf/nrf24.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <RF24.h>
+
+// Initialization
+void initNRF(RF24 &radio);
+
+void startBluetoothJammer();
+void startBleJammer();
+
+void startJammer(const char* name, const byte* channels, size_t channelCount);
+
+void NRFToolsMenu(int index);