diff options
Diffstat (limited to 'src/rf')
| -rw-r--r-- | src/rf/cc1101.cpp | 205 | ||||
| -rw-r--r-- | src/rf/cc1101.h | 9 | ||||
| -rw-r--r-- | src/rf/nrf24.cpp | 249 | ||||
| -rw-r--r-- | src/rf/nrf24.h | 13 |
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); |
