From 0a40daf4fad5c1593c6e1696ac0cab992c799e2e Mon Sep 17 00:00:00 2001 From: krolyxon Date: Mon, 4 May 2026 22:48:07 +0530 Subject: [PATCH] initial commit --- .gitignore | 5 + assets/initial_workflow_diagram.png | Bin 0 -> 203827 bytes firmware/ELECHOUSE_CC1101_SRC_DRV.cpp | 1309 +++++++++++++++++++++++++ firmware/ELECHOUSE_CC1101_SRC_DRV.h | 194 ++++ firmware/badusb.cpp | 56 ++ firmware/badusb.h | 5 + firmware/blescanner.cpp | 211 ++++ firmware/blescanner.h | 5 + firmware/buttons.cpp | 20 + firmware/buttons.h | 8 + firmware/cc1101.cpp | 150 +++ firmware/cc1101.h | 9 + firmware/config.h | 48 + firmware/data/ESP32-BLE-Mouse.zip | Bin 0 -> 7810 bytes firmware/device_check.cpp | 242 +++++ firmware/device_check.h | 3 + firmware/display.cpp | 16 + firmware/display.h | 7 + firmware/firmware.ino | 128 +++ firmware/menu.cpp | 278 ++++++ firmware/menu.h | 10 + firmware/nrf24.cpp | 99 ++ firmware/nrf24.h | 14 + firmware/stubs.cpp | 13 + firmware/sysinfo.cpp | 87 ++ firmware/sysinfo.h | 3 + firmware/wifi_analyzer.cpp | 147 +++ firmware/wifi_analyzer.h | 4 + firmware/wifi_scan.cpp | 152 +++ firmware/wifi_scan.h | 5 + 30 files changed, 3228 insertions(+) create mode 100644 .gitignore create mode 100644 assets/initial_workflow_diagram.png create mode 100644 firmware/ELECHOUSE_CC1101_SRC_DRV.cpp create mode 100644 firmware/ELECHOUSE_CC1101_SRC_DRV.h create mode 100644 firmware/badusb.cpp create mode 100644 firmware/badusb.h create mode 100644 firmware/blescanner.cpp create mode 100644 firmware/blescanner.h create mode 100644 firmware/buttons.cpp create mode 100644 firmware/buttons.h create mode 100644 firmware/cc1101.cpp create mode 100644 firmware/cc1101.h create mode 100644 firmware/config.h create mode 100644 firmware/data/ESP32-BLE-Mouse.zip create mode 100644 firmware/device_check.cpp create mode 100644 firmware/device_check.h create mode 100644 firmware/display.cpp create mode 100644 firmware/display.h create mode 100644 firmware/firmware.ino create mode 100644 firmware/menu.cpp create mode 100644 firmware/menu.h create mode 100644 firmware/nrf24.cpp create mode 100644 firmware/nrf24.h create mode 100644 firmware/stubs.cpp create mode 100644 firmware/sysinfo.cpp create mode 100644 firmware/sysinfo.h create mode 100644 firmware/wifi_analyzer.cpp create mode 100644 firmware/wifi_analyzer.h create mode 100644 firmware/wifi_scan.cpp create mode 100644 firmware/wifi_scan.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..401d1aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +schmatics +documentation + +# Clangd cache +.cache diff --git a/assets/initial_workflow_diagram.png b/assets/initial_workflow_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..782b9b437f9e711456085e8704243c3ac212297b GIT binary patch literal 203827 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 b+Nu@o?b;07fjaBq%8FA8s>d^q8vXr0(4FrI literal 0 HcmV?d00001 diff --git a/firmware/ELECHOUSE_CC1101_SRC_DRV.cpp b/firmware/ELECHOUSE_CC1101_SRC_DRV.cpp new file mode 100644 index 0000000..5568989 --- /dev/null +++ b/firmware/ELECHOUSE_CC1101_SRC_DRV.cpp @@ -0,0 +1,1309 @@ +/* + ELECHOUSE_CC1101.cpp - CC1101 module library + Copyright (c) 2010 Michael. + Author: Michael, + Version: November 12, 2010 + + This library is designed to use CC1101/CC1100 module on Arduino platform. + CC1101/CC1100 module is an useful wireless module.Using the functions of the + library, you can easily send and receive data by the CC1101/CC1100 module. + Just have fun! + For the details, please refer to the datasheet of CC1100/CC1101. +---------------------------------------------------------------------------------------------------------------- +cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE). +---------------------------------------------------------------------------------------------------------------- +*/ +#include +#include "ELECHOUSE_CC1101_SRC_DRV.h" +#include + +/****************************************************************/ +#define WRITE_BURST 0x40 //write burst +#define READ_SINGLE 0x80 //read single +#define READ_BURST 0xC0 //read burst +#define BYTES_IN_RXFIFO 0x7F //byte number in RXfifo +#define max_modul 6 + +SPIClass CCSPI(HSPI); + +byte modulation = 2; +byte frend0; +byte chan = 0; +int pa = 12; +byte last_pa; +byte SCK_PIN; +byte MISO_PIN; +byte MOSI_PIN; +byte SS_PIN; +byte GDO0; +byte GDO2; +byte SCK_PIN_M[max_modul]; +byte MISO_PIN_M[max_modul]; +byte MOSI_PIN_M[max_modul]; +byte SS_PIN_M[max_modul]; +byte GDO0_M[max_modul]; +byte GDO2_M[max_modul]; +byte gdo_set=0; +bool spi = 0; +bool ccmode = 0; +float MHz = 433.92; +byte m4RxBw = 0; +byte m4DaRa; +byte m2DCOFF; +byte m2MODFM; +byte m2MANCH; +byte m2SYNCM; +byte m1FEC; +byte m1PRE; +byte m1CHSP; +byte pc1PQT; +byte pc1CRC_AF; +byte pc1APP_ST; +byte pc1ADRCHK; +byte pc0WDATA; +byte pc0PktForm; +byte pc0CRC_EN; +byte pc0LenConf; +byte trxstate = 0; +byte clb1[2]= {24,28}; +byte clb2[2]= {31,38}; +byte clb3[2]= {65,76}; +byte clb4[2]= {77,79}; + +/****************************************************************/ +uint8_t PA_TABLE[8] {0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00}; +// -30 -20 -15 -10 0 5 7 10 +uint8_t PA_TABLE_315[8] {0x12,0x0D,0x1C,0x34,0x51,0x85,0xCB,0xC2,}; //300 - 348 +uint8_t PA_TABLE_433[8] {0x12,0x0E,0x1D,0x34,0x60,0x84,0xC8,0xC0,}; //387 - 464 +// -30 -20 -15 -10 -6 0 5 7 10 12 +uint8_t PA_TABLE_868[10] {0x03,0x17,0x1D,0x26,0x37,0x50,0x86,0xCD,0xC5,0xC0,}; //779 - 899.99 +// -30 -20 -15 -10 -6 0 5 7 10 11 +uint8_t PA_TABLE_915[10] {0x03,0x0E,0x1E,0x27,0x38,0x8E,0x84,0xCC,0xC3,0xC0,}; //900 - 928 +/**************************************************************** +*FUNCTION NAME:SpiStart +*FUNCTION :spi communication start +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiStart(void) +{ + // initialize the SPI pins + pinMode(SCK_PIN, OUTPUT); + pinMode(MOSI_PIN, OUTPUT); + pinMode(MISO_PIN, INPUT); + pinMode(SS_PIN, OUTPUT); + + // enable SPI + #ifdef ESP32 + CCSPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN); + #else + CCSPI.begin(); + #endif +} +/**************************************************************** +*FUNCTION NAME:SpiEnd +*FUNCTION :spi communication disable +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiEnd(void) +{ + // disable SPI + CCSPI.endTransaction(); + CCSPI.end(); +} +/**************************************************************** +*FUNCTION NAME: GDO_Set() +*FUNCTION : set GDO0,GDO2 pin for serial pinmode. +*INPUT : none +*OUTPUT : none +****************************************************************/ +void ELECHOUSE_CC1101::GDO_Set (void) +{ + pinMode(GDO0, OUTPUT); + pinMode(GDO2, INPUT); +} +/**************************************************************** +*FUNCTION NAME: GDO_Set() +*FUNCTION : set GDO0 for internal transmission mode. +*INPUT : none +*OUTPUT : none +****************************************************************/ +void ELECHOUSE_CC1101::GDO0_Set (void) +{ + pinMode(GDO0, INPUT); +} +/**************************************************************** +*FUNCTION NAME:Reset +*FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100// +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Reset (void) +{ + digitalWrite(SS_PIN, LOW); + delay(1); + digitalWrite(SS_PIN, HIGH); + delay(1); + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(CC1101_SRES); + while(digitalRead(MISO_PIN)); + digitalWrite(SS_PIN, HIGH); +} +/**************************************************************** +*FUNCTION NAME:Init +*FUNCTION :CC1101 initialization +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Init(void) +{ + setSpi(); + SpiStart(); //spi initialization + digitalWrite(SS_PIN, HIGH); + digitalWrite(SCK_PIN, HIGH); + digitalWrite(MOSI_PIN, LOW); + Reset(); //CC1101 reset + RegConfigSettings(); //CC1101 register config + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiWriteReg +*FUNCTION :CC1101 write data to register +*INPUT :addr: register address; value: register value +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiWriteReg(byte addr, byte value) +{ + SpiStart(); + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(addr); + CCSPI.transfer(value); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiWriteBurstReg +*FUNCTION :CC1101 write burst data to register +*INPUT :addr: register address; buffer:register value array; num:number to write +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiWriteBurstReg(byte addr, byte *buffer, byte num) +{ + byte i, temp; + SpiStart(); + temp = addr | WRITE_BURST; + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(temp); + for (i = 0; i < num; i++) + { + CCSPI.transfer(buffer[i]); + } + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiStrobe +*FUNCTION :CC1101 Strobe +*INPUT :strobe: command; //refer define in CC1101.h// +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiStrobe(byte strobe) +{ + SpiStart(); + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(strobe); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiReadReg +*FUNCTION :CC1101 read data from register +*INPUT :addr: register address +*OUTPUT :register value +****************************************************************/ +byte ELECHOUSE_CC1101::SpiReadReg(byte addr) +{ + byte temp, value; + SpiStart(); + temp = addr| READ_SINGLE; + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(temp); + value=CCSPI.transfer(0); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); + return value; +} + +/**************************************************************** +*FUNCTION NAME:SpiReadBurstReg +*FUNCTION :CC1101 read burst data from register +*INPUT :addr: register address; buffer:array to store register value; num: number to read +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiReadBurstReg(byte addr, byte *buffer, byte num) +{ + byte i,temp; + SpiStart(); + temp = addr | READ_BURST; + digitalWrite(SS_PIN, LOW); + while(digitalRead(MISO_PIN)); + CCSPI.transfer(temp); + for(i=0;i4){m=4;} +modulation = m; +Split_MDMCFG2(); +switch (m) +{ +case 0: m2MODFM=0x00; frend0=0x10; break; // 2-FSK +case 1: m2MODFM=0x10; frend0=0x10; break; // GFSK +case 2: m2MODFM=0x30; frend0=0x11; break; // ASK +case 3: m2MODFM=0x40; frend0=0x10; break; // 4-FSK +case 4: m2MODFM=0x70; frend0=0x10; break; // MSK +} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +SpiWriteReg(CC1101_FREND0, frend0); +setPA(pa); +} +/**************************************************************** +*FUNCTION NAME:PA Power +*FUNCTION :set CC1101 PA Power +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPA(int p) +{ +int a; +pa = p; + +if (MHz >= 300 && MHz <= 348){ +if (pa <= -30){a = PA_TABLE_315[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_315[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_315[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_315[3];} +else if (pa > -10 && pa <= 0){a = PA_TABLE_315[4];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_315[5];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_315[6];} +else if (pa > 7){a = PA_TABLE_315[7];} +last_pa = 1; +} +else if (MHz >= 378 && MHz <= 464){ +if (pa <= -30){a = PA_TABLE_433[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_433[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_433[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_433[3];} +else if (pa > -10 && pa <= 0){a = PA_TABLE_433[4];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_433[5];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_433[6];} +else if (pa > 7){a = PA_TABLE_433[7];} +last_pa = 2; +} +else if (MHz >= 779 && MHz <= 899.99){ +if (pa <= -30){a = PA_TABLE_868[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_868[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_868[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_868[3];} +else if (pa > -10 && pa <= -6){a = PA_TABLE_868[4];} +else if (pa > -6 && pa <= 0){a = PA_TABLE_868[5];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_868[6];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_868[7];} +else if (pa > 7 && pa <= 10){a = PA_TABLE_868[8];} +else if (pa > 10){a = PA_TABLE_868[9];} +last_pa = 3; +} +else if (MHz >= 900 && MHz <= 928){ +if (pa <= -30){a = PA_TABLE_915[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_915[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_915[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_915[3];} +else if (pa > -10 && pa <= -6){a = PA_TABLE_915[4];} +else if (pa > -6 && pa <= 0){a = PA_TABLE_915[5];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_915[6];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_915[7];} +else if (pa > 7 && pa <= 10){a = PA_TABLE_915[8];} +else if (pa > 10){a = PA_TABLE_915[9];} +last_pa = 4; +} +if (modulation == 2){ +PA_TABLE[0] = 0; +PA_TABLE[1] = a; +}else{ +PA_TABLE[0] = a; +PA_TABLE[1] = 0; +} +SpiWriteBurstReg(CC1101_PATABLE,PA_TABLE,8); +} +/**************************************************************** +*FUNCTION NAME:Frequency Calculator +*FUNCTION :Calculate the basic frequency. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setMHZ(float mhz){ +byte freq2 = 0; +byte freq1 = 0; +byte freq0 = 0; + +MHz = mhz; + +for (bool i = 0; i==0;){ +if (mhz >= 26){ +mhz-=26; +freq2+=1; +} +else if (mhz >= 0.1015625){ +mhz-=0.1015625; +freq1+=1; +} +else if (mhz >= 0.00039675){ +mhz-=0.00039675; +freq0+=1; +} +else{i=1;} +} +if (freq0 > 255){freq1+=1;freq0-=256;} + +SpiWriteReg(CC1101_FREQ2, freq2); +SpiWriteReg(CC1101_FREQ1, freq1); +SpiWriteReg(CC1101_FREQ0, freq0); + +Calibrate(); +} +/**************************************************************** +*FUNCTION NAME:Calibrate +*FUNCTION :Calibrate frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Calibrate(void){ + +if (MHz >= 300 && MHz <= 348){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 300, 348, clb1[0], clb1[1])); +if (MHz < 322.88){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 1){setPA(pa);} +} +} +else if (MHz >= 378 && MHz <= 464){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 378, 464, clb2[0], clb2[1])); +if (MHz < 430.5){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 2){setPA(pa);} +} +} +else if (MHz >= 779 && MHz <= 899.99){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 779, 899, clb3[0], clb3[1])); +if (MHz < 861){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 3){setPA(pa);} +} +} +else if (MHz >= 900 && MHz <= 928){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 900, 928, clb4[0], clb4[1])); +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 4){setPA(pa);} +} +} +/**************************************************************** +*FUNCTION NAME:Calibration offset +*FUNCTION :Set calibration offset +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setClb(byte b, byte s, byte e){ +if (b == 1){ +clb1[0]=s; +clb1[1]=e; +} +else if (b == 2){ +clb2[0]=s; +clb2[1]=e; +} +else if (b == 3){ +clb3[0]=s; +clb3[1]=e; +} +else if (b == 4){ +clb4[0]=s; +clb4[1]=e; +} +} +/**************************************************************** +*FUNCTION NAME:getCC1101 +*FUNCTION :Test Spi connection and return 1 when true. +*INPUT :none +*OUTPUT :none +****************************************************************/ +bool ELECHOUSE_CC1101::getCC1101(void){ +setSpi(); +if (SpiReadStatus(0x31)>0){ +return 1; +}else{ +return 0; +} +} +/**************************************************************** +*FUNCTION NAME:getMode +*FUNCTION :Return the Mode. Sidle = 0, TX = 1, Rx = 2. +*INPUT :none +*OUTPUT :none +****************************************************************/ +byte ELECHOUSE_CC1101::getMode(void){ +return trxstate; +} +/**************************************************************** +*FUNCTION NAME:Set Sync_Word +*FUNCTION :Sync Word +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSyncWord(byte sh, byte sl){ +SpiWriteReg(CC1101_SYNC1, sh); +SpiWriteReg(CC1101_SYNC0, sl); +} +/**************************************************************** +*FUNCTION NAME:Set ADDR +*FUNCTION :Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF). +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAddr(byte v){ +SpiWriteReg(CC1101_ADDR, v); +} +/**************************************************************** +*FUNCTION NAME:Set PQT +*FUNCTION :Preamble quality estimator threshold +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPQT(byte v){ +Split_PKTCTRL1(); +pc1PQT = 0; +if (v>7){v=7;} +pc1PQT = v*32; +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set CRC_AUTOFLUSH +*FUNCTION :Enable automatic flush of RX FIFO when CRC is not OK +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setCRC_AF(bool v){ +Split_PKTCTRL1(); +pc1CRC_AF = 0; +if (v==1){pc1CRC_AF=8;} +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set APPEND_STATUS +*FUNCTION :When enabled, two status bytes will be appended to the payload of the packet +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAppendStatus(bool v){ +Split_PKTCTRL1(); +pc1APP_ST = 0; +if (v==1){pc1APP_ST=4;} +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set ADR_CHK +*FUNCTION :Controls address check configuration of received packages +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAdrChk(byte v){ +Split_PKTCTRL1(); +pc1ADRCHK = 0; +if (v>3){v=3;} +pc1ADRCHK = v; +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set WHITE_DATA +*FUNCTION :Turn data whitening on / off. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setWhiteData(bool v){ +Split_PKTCTRL0(); +pc0WDATA = 0; +if (v == 1){pc0WDATA=64;} +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set PKT_FORMAT +*FUNCTION :Format of RX and TX data +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPktFormat(byte v){ +Split_PKTCTRL0(); +pc0PktForm = 0; +if (v>3){v=3;} +pc0PktForm = v*16; +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set CRC +*FUNCTION :CRC calculation in TX and CRC check in RX +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setCrc(bool v){ +Split_PKTCTRL0(); +pc0CRC_EN = 0; +if (v==1){pc0CRC_EN=4;} +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set LENGTH_CONFIG +*FUNCTION :Configure the packet length +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setLengthConfig(byte v){ +Split_PKTCTRL0(); +pc0LenConf = 0; +if (v>3){v=3;} +pc0LenConf = v; +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set PACKET_LENGTH +*FUNCTION :Indicates the packet length +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPacketLength(byte v){ +SpiWriteReg(CC1101_PKTLEN, v); +} +/**************************************************************** +*FUNCTION NAME:Set DCFILT_OFF +*FUNCTION :Disable digital DC blocking filter before demodulator +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDcFilterOff(bool v){ +Split_MDMCFG2(); +m2DCOFF = 0; +if (v==1){m2DCOFF=128;} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set MANCHESTER +*FUNCTION :Enables Manchester encoding/decoding +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setManchester(bool v){ +Split_MDMCFG2(); +m2MANCH = 0; +if (v==1){m2MANCH=8;} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set SYNC_MODE +*FUNCTION :Combined sync-word qualifier mode +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSyncMode(byte v){ +Split_MDMCFG2(); +m2SYNCM = 0; +if (v>7){v=7;} +m2SYNCM=v; +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set FEC +*FUNCTION :Enable Forward Error Correction (FEC) +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setFEC(bool v){ +Split_MDMCFG1(); +m1FEC=0; +if (v==1){m1FEC=128;} +SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP); +} +/**************************************************************** +*FUNCTION NAME:Set PRE +*FUNCTION :Sets the minimum number of preamble bytes to be transmitted. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPRE(byte v){ +Split_MDMCFG1(); +m1PRE=0; +if (v>7){v=7;} +m1PRE = v*16; +SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP); +} +/**************************************************************** +*FUNCTION NAME:Set Channel +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setChannel(byte ch){ +chan = ch; +SpiWriteReg(CC1101_CHANNR, chan); +} +/**************************************************************** +*FUNCTION NAME:Set Channel spacing +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setChsp(float f){ +Split_MDMCFG1(); +byte MDMCFG0 = 0; +m1CHSP = 0; +if (f > 405.456543){f = 405.456543;} +if (f < 25.390625){f = 25.390625;} +for (int i = 0; i<5; i++){ +if (f <= 50.682068){ +f -= 25.390625; +f /= 0.0991825; +MDMCFG0 = f; +float s1 = (f - MDMCFG0) *10; +if (s1 >= 5){MDMCFG0++;} +i = 5; +}else{ +m1CHSP++; +f/=2; +} +} +SpiWriteReg(19,m1CHSP+m1FEC+m1PRE); +SpiWriteReg(20,MDMCFG0); +} +/**************************************************************** +*FUNCTION NAME:Set Receive bandwidth +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setRxBW(float f){ +Split_MDMCFG4(); +int s1 = 3; +int s2 = 3; +for (int i = 0; i<3; i++){ +if (f > 101.5625){f/=2; s1--;} +else{i=3;} +} +for (int i = 0; i<3; i++){ +if (f > 58.1){f/=1.25; s2--;} +else{i=3;} +} +s1 *= 64; +s2 *= 16; +m4RxBw = s1 + s2; +SpiWriteReg(16,m4RxBw+m4DaRa); +} +/**************************************************************** +*FUNCTION NAME:Set Data Rate +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDRate(float d){ +Split_MDMCFG4(); +float c = d; +byte MDMCFG3 = 0; +if (c > 1621.83){c = 1621.83;} +if (c < 0.0247955){c = 0.0247955;} +m4DaRa = 0; +for (int i = 0; i<20; i++){ +if (c <= 0.0494942){ +c = c - 0.0247955; +c = c / 0.00009685; +MDMCFG3 = c; +float s1 = (c - MDMCFG3) *10; +if (s1 >= 5){MDMCFG3++;} +i = 20; +}else{ +m4DaRa++; +c = c/2; +} +} +SpiWriteReg(16, m4RxBw+m4DaRa); +SpiWriteReg(17, MDMCFG3); +} +/**************************************************************** +*FUNCTION NAME:Set Devitation +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDeviation(float d){ +float f = 1.586914; +float v = 0.19836425; +int c = 0; +if (d > 380.859375){d = 380.859375;} +if (d < 1.586914){d = 1.586914;} +for (int i = 0; i<255; i++){ +f+=v; +if (c==7){v*=2;c=-1;i+=8;} +if (f>=d){c=i;i=255;} +c++; +} +SpiWriteReg(21,c); +} +/**************************************************************** +*FUNCTION NAME:Split PKTCTRL0 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_PKTCTRL1(void){ +int calc = SpiReadStatus(7); +pc1PQT = 0; +pc1CRC_AF = 0; +pc1APP_ST = 0; +pc1ADRCHK = 0; +for (bool i = 0; i==0;){ +if (calc >= 32){calc-=32; pc1PQT+=32;} +else if (calc >= 8){calc-=8; pc1CRC_AF+=8;} +else if (calc >= 4){calc-=4; pc1APP_ST+=4;} +else {pc1ADRCHK = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split PKTCTRL0 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_PKTCTRL0(void){ +int calc = SpiReadStatus(8); +pc0WDATA = 0; +pc0PktForm = 0; +pc0CRC_EN = 0; +pc0LenConf = 0; +for (bool i = 0; i==0;){ +if (calc >= 64){calc-=64; pc0WDATA+=64;} +else if (calc >= 16){calc-=16; pc0PktForm+=16;} +else if (calc >= 4){calc-=4; pc0CRC_EN+=4;} +else {pc0LenConf = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG1 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG1(void){ +int calc = SpiReadStatus(19); +m1FEC = 0; +m1PRE = 0; +m1CHSP = 0; +int s2 = 0; +for (bool i = 0; i==0;){ +if (calc >= 128){calc-=128; m1FEC+=128;} +else if (calc >= 16){calc-=16; m1PRE+=16;} +else {m1CHSP = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG2 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG2(void){ +int calc = SpiReadStatus(18); +m2DCOFF = 0; +m2MODFM = 0; +m2MANCH = 0; +m2SYNCM = 0; +for (bool i = 0; i==0;){ +if (calc >= 128){calc-=128; m2DCOFF+=128;} +else if (calc >= 16){calc-=16; m2MODFM+=16;} +else if (calc >= 8){calc-=8; m2MANCH+=8;} +else{m2SYNCM = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG4 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG4(void){ +int calc = SpiReadStatus(16); +m4RxBw = 0; +m4DaRa = 0; +for (bool i = 0; i==0;){ +if (calc >= 64){calc-=64; m4RxBw+=64;} +else if (calc >= 16){calc -= 16; m4RxBw+=16;} +else{m4DaRa = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:RegConfigSettings +*FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100// +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::RegConfigSettings(void) +{ + SpiWriteReg(CC1101_FSCTRL1, 0x06); + + setCCMode(ccmode); + setMHZ(MHz); + + SpiWriteReg(CC1101_MDMCFG1, 0x02); + SpiWriteReg(CC1101_MDMCFG0, 0xF8); + SpiWriteReg(CC1101_CHANNR, chan); + SpiWriteReg(CC1101_DEVIATN, 0x47); + SpiWriteReg(CC1101_FREND1, 0x56); + SpiWriteReg(CC1101_MCSM0 , 0x18); + SpiWriteReg(CC1101_FOCCFG, 0x16); + SpiWriteReg(CC1101_BSCFG, 0x1C); + SpiWriteReg(CC1101_AGCCTRL2, 0xC7); + SpiWriteReg(CC1101_AGCCTRL1, 0x00); + SpiWriteReg(CC1101_AGCCTRL0, 0xB2); + SpiWriteReg(CC1101_FSCAL3, 0xE9); + SpiWriteReg(CC1101_FSCAL2, 0x2A); + SpiWriteReg(CC1101_FSCAL1, 0x00); + SpiWriteReg(CC1101_FSCAL0, 0x1F); + SpiWriteReg(CC1101_FSTEST, 0x59); + SpiWriteReg(CC1101_TEST2, 0x81); + SpiWriteReg(CC1101_TEST1, 0x35); + SpiWriteReg(CC1101_TEST0, 0x09); + SpiWriteReg(CC1101_PKTCTRL1, 0x04); + SpiWriteReg(CC1101_ADDR, 0x00); + SpiWriteReg(CC1101_PKTLEN, 0x00); +} +/**************************************************************** +*FUNCTION NAME:SetTx +*FUNCTION :set CC1101 send data +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetTx(void) +{ + SpiStrobe(CC1101_SIDLE); + SpiStrobe(CC1101_STX); //start send + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:SetRx +*FUNCTION :set CC1101 to receive state +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetRx(void) +{ + SpiStrobe(CC1101_SIDLE); + SpiStrobe(CC1101_SRX); //start receive + trxstate=2; +} +/**************************************************************** +*FUNCTION NAME:SetTx +*FUNCTION :set CC1101 send data and change frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetTx(float mhz) +{ + SpiStrobe(CC1101_SIDLE); + setMHZ(mhz); + SpiStrobe(CC1101_STX); //start send + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:SetRx +*FUNCTION :set CC1101 to receive state and change frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetRx(float mhz) +{ + SpiStrobe(CC1101_SIDLE); + setMHZ(mhz); + SpiStrobe(CC1101_SRX); //start receive + trxstate=2; +} +/**************************************************************** +*FUNCTION NAME:RSSI Level +*FUNCTION :Calculating the RSSI Level +*INPUT :none +*OUTPUT :none +****************************************************************/ +int ELECHOUSE_CC1101::getRssi(void) +{ +int rssi; +rssi=SpiReadStatus(CC1101_RSSI); +if (rssi >= 128){rssi = (rssi-256)/2-74;} +else{rssi = (rssi/2)-74;} +return rssi; +} +/**************************************************************** +*FUNCTION NAME:LQI Level +*FUNCTION :get Lqi state +*INPUT :none +*OUTPUT :none +****************************************************************/ +byte ELECHOUSE_CC1101::getLqi(void) +{ +byte lqi; +lqi=SpiReadStatus(CC1101_LQI); +return lqi; +} +/**************************************************************** +*FUNCTION NAME:SetSres +*FUNCTION :Reset CC1101 +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSres(void) +{ + SpiStrobe(CC1101_SRES); + trxstate=0; +} +/**************************************************************** +*FUNCTION NAME:setSidle +*FUNCTION :set Rx / TX Off +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSidle(void) +{ + SpiStrobe(CC1101_SIDLE); + trxstate=0; +} +/**************************************************************** +*FUNCTION NAME:goSleep +*FUNCTION :set cc1101 Sleep on +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::goSleep(void){ + trxstate=0; + SpiStrobe(0x36);//Exit RX / TX, turn off frequency synthesizer and exit + SpiStrobe(0x39);//Enter power down mode when CSn goes high. +} +/**************************************************************** +*FUNCTION NAME:Char direct SendData +*FUNCTION :use CC1101 send data +*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61 +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SendData(char *txchar) +{ +int len = strlen(txchar); +byte chartobyte[len]; +for (int i = 0; i sync transmitted + while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet + SpiStrobe(CC1101_SFTX); //flush TXfifo + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:Char direct SendData +*FUNCTION :use CC1101 send data without GDO +*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61 +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SendData(char *txchar,int t) +{ +int len = strlen(txchar); +byte chartobyte[len]; +for (int i = 0; i + Version: November 12, 2010 + + This library is designed to use CC1101/CC1100 module on Arduino platform. + CC1101/CC1100 module is an useful wireless module.Using the functions of the + library, you can easily send and receive data by the CC1101/CC1100 module. + Just have fun! + For the details, please refer to the datasheet of CC1100/CC1101. +---------------------------------------------------------------------------------------------------------------- +cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE). +---------------------------------------------------------------------------------------------------------------- +*/ +#ifndef ELECHOUSE_CC1101_SRC_DRV_h +#define ELECHOUSE_CC1101_SRC_DRV_h + +#include + +//***************************************CC1101 define**************************************************// +// CC1101 CONFIG REGSITER +#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration +#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration +#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration +#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds +#define CC1101_SYNC1 0x04 // Sync word, high INT8U +#define CC1101_SYNC0 0x05 // Sync word, low INT8U +#define CC1101_PKTLEN 0x06 // Packet length +#define CC1101_PKTCTRL1 0x07 // Packet automation control +#define CC1101_PKTCTRL0 0x08 // Packet automation control +#define CC1101_ADDR 0x09 // Device address +#define CC1101_CHANNR 0x0A // Channel number +#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control +#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control +#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U +#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U +#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U +#define CC1101_MDMCFG4 0x10 // Modem configuration +#define CC1101_MDMCFG3 0x11 // Modem configuration +#define CC1101_MDMCFG2 0x12 // Modem configuration +#define CC1101_MDMCFG1 0x13 // Modem configuration +#define CC1101_MDMCFG0 0x14 // Modem configuration +#define CC1101_DEVIATN 0x15 // Modem deviation setting +#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration +#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration +#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration +#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration +#define CC1101_BSCFG 0x1A // Bit Synchronization configuration +#define CC1101_AGCCTRL2 0x1B // AGC control +#define CC1101_AGCCTRL1 0x1C // AGC control +#define CC1101_AGCCTRL0 0x1D // AGC control +#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout +#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout +#define CC1101_WORCTRL 0x20 // Wake On Radio control +#define CC1101_FREND1 0x21 // Front end RX configuration +#define CC1101_FREND0 0x22 // Front end TX configuration +#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration +#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration +#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration +#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration +#define CC1101_RCCTRL1 0x27 // RC oscillator configuration +#define CC1101_RCCTRL0 0x28 // RC oscillator configuration +#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control +#define CC1101_PTEST 0x2A // Production test +#define CC1101_AGCTEST 0x2B // AGC test +#define CC1101_TEST2 0x2C // Various test settings +#define CC1101_TEST1 0x2D // Various test settings +#define CC1101_TEST0 0x2E // Various test settings + +//CC1101 Strobe commands +#define CC1101_SRES 0x30 // Reset chip. +#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). + // If in RX/TX: Go to a wait state where only the synthesizer is + // running (for quick RX / TX turnaround). +#define CC1101_SXOFF 0x32 // Turn off crystal oscillator. +#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off + // (enables quick start). +#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and + // MCSM0.FS_AUTOCAL=1. +#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if + // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled: + // Only go to TX if channel is clear. +#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit + // Wake-On-Radio mode if applicable. +#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer +#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio) +#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high. +#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer. +#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer. +#define CC1101_SWORRST 0x3C // Reset real time clock. +#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two + // INT8Us for simpler software. +//CC1101 STATUS REGSITER +#define CC1101_PARTNUM 0x30 +#define CC1101_VERSION 0x31 +#define CC1101_FREQEST 0x32 +#define CC1101_LQI 0x33 +#define CC1101_RSSI 0x34 +#define CC1101_MARCSTATE 0x35 +#define CC1101_WORTIME1 0x36 +#define CC1101_WORTIME0 0x37 +#define CC1101_PKTSTATUS 0x38 +#define CC1101_VCO_VC_DAC 0x39 +#define CC1101_TXBYTES 0x3A +#define CC1101_RXBYTES 0x3B + +//CC1101 PATABLE,TXFIFO,RXFIFO +#define CC1101_PATABLE 0x3E +#define CC1101_TXFIFO 0x3F +#define CC1101_RXFIFO 0x3F + +//************************************* class **************************************************// +class ELECHOUSE_CC1101 +{ +private: + void SpiStart(void); + void SpiEnd(void); + void GDO_Set (void); + void GDO0_Set (void); + void Reset (void); + void setSpi(void); + void RegConfigSettings(void); + void Calibrate(void); + void Split_PKTCTRL0(void); + void Split_PKTCTRL1(void); + void Split_MDMCFG1(void); + void Split_MDMCFG2(void); + void Split_MDMCFG4(void); +public: + void Init(void); + byte SpiReadStatus(byte addr); + void setSpiPin(byte sck, byte miso, byte mosi, byte ss); + void addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul); + void setGDO(byte gdo0, byte gdo2); + void setGDO0(byte gdo0); + void addGDO(byte gdo0, byte gdo2, byte modul); + void addGDO0(byte gdo0, byte modul); + void setModul(byte modul); + void setCCMode(bool s); + void setModulation(byte m); + void setPA(int p); + void setMHZ(float mhz); + void setChannel(byte chnl); + void setChsp(float f); + void setRxBW(float f); + void setDRate(float d); + void setDeviation(float d); + void SetTx(void); + void SetRx(void); + void SetTx(float mhz); + void SetRx(float mhz); + int getRssi(void); + byte getLqi(void); + void setSres(void); + void setSidle(void); + void goSleep(void); + void SendData(byte *txBuffer, byte size); + void SendData(char *txchar); + void SendData(byte *txBuffer, byte size, int t); + void SendData(char *txchar, int t); + byte CheckReceiveFlag(void); + byte ReceiveData(byte *rxBuffer); + bool CheckCRC(void); + void SpiStrobe(byte strobe); + void SpiWriteReg(byte addr, byte value); + void SpiWriteBurstReg(byte addr, byte *buffer, byte num); + byte SpiReadReg(byte addr); + void SpiReadBurstReg(byte addr, byte *buffer, byte num); + void setClb(byte b, byte s, byte e); + bool getCC1101(void); + byte getMode(void); + void setSyncWord(byte sh, byte sl); + void setAddr(byte v); + void setWhiteData(bool v); + void setPktFormat(byte v); + void setCrc(bool v); + void setLengthConfig(byte v); + void setPacketLength(byte v); + void setDcFilterOff(bool v); + void setManchester(bool v); + void setSyncMode(byte v); + void setFEC(bool v); + void setPRE(byte v); + void setPQT(byte v); + void setCRC_AF(bool v); + void setAppendStatus(bool v); + void setAdrChk(byte v); + bool CheckRxFifo(int t); +}; + +extern ELECHOUSE_CC1101 ELECHOUSE_cc1101; + +#endif \ No newline at end of file diff --git a/firmware/badusb.cpp b/firmware/badusb.cpp new file mode 100644 index 0000000..18c501a --- /dev/null +++ b/firmware/badusb.cpp @@ -0,0 +1,56 @@ +#include +#include + +extern USBHIDKeyboard Keyboard; + +void runBadUSBDemo() +{ + delay(2000); + Keyboard.println(""); + Keyboard.println("#-FEATURES:"); + Keyboard.println("1- WIFI ATTACKS"); + Keyboard.println("2- BLE ATTACKS"); + Keyboard.println("3- BAD USB"); + Keyboard.println("4- NFC"); + Keyboard.println("5- INFRARED"); + Keyboard.println("6- SUB-GHZ"); + Keyboard.println("7- GPIO"); + Keyboard.println("8- APPS"); + Keyboard.println("9- SETTINGS"); + Keyboard.println("10- FILES"); + +} + +void runBadUSBOpenCMD() +{ + delay(2000); + Keyboard.println(""); + Keyboard.println("#-FEATURES:"); + Keyboard.println("1- WIFI ATTACKS"); + Keyboard.println("2- BLE ATTACKS"); + Keyboard.println("3- BAD USB"); + Keyboard.println("4- NFC"); + Keyboard.println("5- INFRARED"); + Keyboard.println("6- SUB-GHZ"); + Keyboard.println("7- GPIO"); + Keyboard.println("8- APPS"); + Keyboard.println("9- SETTINGS"); + Keyboard.println("10- FILES"); +} + +void runBadUSBRickroll() +{ + delay(2000); + Keyboard.println(""); + Keyboard.println("#-FEATURES:"); + Keyboard.println("1- WIFI ATTACKS"); + Keyboard.println("2- BLE ATTACKS"); + Keyboard.println("3- BAD USB"); + Keyboard.println("4- NFC"); + Keyboard.println("5- INFRARED"); + Keyboard.println("6- SUB-GHZ"); + Keyboard.println("7- GPIO"); + Keyboard.println("8- APPS"); + Keyboard.println("9- SETTINGS"); + Keyboard.println("10- FILES"); +} diff --git a/firmware/badusb.h b/firmware/badusb.h new file mode 100644 index 0000000..a5a0dd5 --- /dev/null +++ b/firmware/badusb.h @@ -0,0 +1,5 @@ +#pragma once + +void runBadUSBDemo(); +void runBadUSBOpenCMD(); +void runBadUSBRickroll(); diff --git a/firmware/blescanner.cpp b/firmware/blescanner.cpp new file mode 100644 index 0000000..6cca404 --- /dev/null +++ b/firmware/blescanner.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include + +#include "display.h" +#include "buttons.h" +#include "config.h" + +// ===== DEVICE STRUCT ===== +struct BLEDeviceInfo { + String name; + String address; + int rssi; + String manufacturer; + String deviceType; +}; + +static std::vector devices; +static BLEScan *pBLEScan; +static int selectedIndex = 0; + +// ===== CALLBACK ===== +class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { + void onResult(BLEAdvertisedDevice advertisedDevice) override { + BLEDeviceInfo dev; + + String tempName = advertisedDevice.getName(); + + if (tempName.length() == 0 && advertisedDevice.haveServiceData()) { + tempName = advertisedDevice.getServiceData().c_str(); + } + + if (tempName.length() == 0) { + String addr = advertisedDevice.getAddress().toString().c_str(); + tempName = "BLE_" + addr.substring(addr.length() - 5); + } + + dev.name = tempName; + dev.address = advertisedDevice.getAddress().toString().c_str(); + dev.rssi = advertisedDevice.getRSSI(); + + if (advertisedDevice.haveManufacturerData()) { + String mData = advertisedDevice.getManufacturerData().c_str(); + + if (mData.length() >= 2) { + char buffer[10]; + sprintf(buffer, "0x%02X%02X", + (uint8_t)mData[1], + (uint8_t)mData[0]); + dev.manufacturer = String(buffer); + } else { + dev.manufacturer = "unknown"; + } + } else { + dev.manufacturer = "unknown"; + } + + if (advertisedDevice.haveServiceUUID()) { + dev.deviceType = + advertisedDevice.getServiceUUID().toString().c_str(); + } else { + dev.deviceType = "unknown"; + } + + devices.push_back(dev); + } +}; + +// ===== DRAW MENU ===== +void ble_drawMenu() +{ + u8g2.clearBuffer(); + + if (devices.empty()) + { + u8g2.setFont(u8g2_font_6x12_tr); + u8g2.drawStr(0, 30, "No devices"); + u8g2.drawStr(0, 45, "Press BACK"); + } + else + { + u8g2.setFont(u8g2_font_5x8_tr); + + char counter[20]; + sprintf(counter, "%d/%d", selectedIndex + 1, (int)devices.size()); + u8g2.drawStr(0, 8, counter); + + u8g2.setFont(u8g2_font_6x10_tr); + + for (int i = 0; i < 3; i++) + { + int idx = selectedIndex + i; + if (idx >= devices.size()) break; + + int y = 22 + i * 14; + + if (i == 0) + { + u8g2.drawBox(0, y - 10, 128, 12); + u8g2.setDrawColor(0); + } + + String text = devices[idx].name; + if (text.length() > 12) + text = text.substring(0, 12) + ".."; + + text += " (" + String(devices[idx].rssi) + ")"; + + u8g2.drawStr(2, y, text.c_str()); + + if (i == 0) + u8g2.setDrawColor(1); + } + } + + u8g2.sendBuffer(); +} + +// ===== DEVICE DETAILS ===== +void ble_drawDetails(const BLEDeviceInfo &dev) +{ + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_5x8_tr); + + u8g2.drawStr(0, 10, dev.name.c_str()); + u8g2.drawStr(0, 20, dev.address.c_str()); + + char rssiStr[20]; + sprintf(rssiStr, "RSSI: %d", dev.rssi); + u8g2.drawStr(0, 30, rssiStr); + + u8g2.drawStr(0, 40, dev.manufacturer.c_str()); + + u8g2.sendBuffer(); +} + +// ===== SCAN ===== +void ble_scan() +{ + devices.clear(); + + u8g2.clearBuffer(); + u8g2.drawStr(10, 30, "Scanning..."); + u8g2.sendBuffer(); + + BLEDevice::init(""); + + pBLEScan = BLEDevice::getScan(); + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false); + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); + + pBLEScan->start(5, false); + + // remove duplicates + std::vector unique; + for (auto &d : devices) + { + bool exists = false; + for (auto &u : unique) + { + if (u.address == d.address) + { + exists = true; + break; + } + } + if (!exists) unique.push_back(d); + } + + devices = unique; +} + +// ===== MAIN LOOP ===== +void ble_loop() +{ + static uint32_t lastPress = 0; + + if (millis() - lastPress < 200) + return; + + if (btnDown() && selectedIndex < (int)devices.size() - 1) + { + selectedIndex++; + ble_drawMenu(); + lastPress = millis(); + } + else if (btnUp() && selectedIndex > 0) + { + selectedIndex--; + ble_drawMenu(); + lastPress = millis(); + } + else if (btnSelect() && !devices.empty()) + { + ble_drawDetails(devices[selectedIndex]); + delay(3000); + ble_drawMenu(); + lastPress = millis(); + } + else if (btnBack()) + { + ble_scan(); + selectedIndex = 0; + ble_drawMenu(); + lastPress = millis(); + } +} diff --git a/firmware/blescanner.h b/firmware/blescanner.h new file mode 100644 index 0000000..a642de2 --- /dev/null +++ b/firmware/blescanner.h @@ -0,0 +1,5 @@ +#pragma once + +void ble_scan(); +void ble_loop(); +void ble_drawMenu(); diff --git a/firmware/buttons.cpp b/firmware/buttons.cpp new file mode 100644 index 0000000..d28c4cc --- /dev/null +++ b/firmware/buttons.cpp @@ -0,0 +1,20 @@ +#include "buttons.h" +#include + +#define BTN_UP 4 +#define BTN_DOWN 5 +#define BTN_SELECT 6 +#define BTN_BACK 7 + +void buttonsInit() +{ + pinMode(BTN_UP, INPUT_PULLUP); + pinMode(BTN_DOWN, INPUT_PULLUP); + pinMode(BTN_SELECT, INPUT_PULLUP); + pinMode(BTN_BACK, INPUT_PULLUP); +} + +bool btnUp() { return !digitalRead(BTN_UP); } +bool btnDown() { return !digitalRead(BTN_DOWN); } +bool btnSelect() { return !digitalRead(BTN_SELECT); } +bool btnBack() { return !digitalRead(BTN_BACK); } diff --git a/firmware/buttons.h b/firmware/buttons.h new file mode 100644 index 0000000..077f35f --- /dev/null +++ b/firmware/buttons.h @@ -0,0 +1,8 @@ +#pragma once + +void buttonsInit(); + +bool btnUp(); +bool btnDown(); +bool btnSelect(); +bool btnBack(); diff --git a/firmware/cc1101.cpp b/firmware/cc1101.cpp new file mode 100644 index 0000000..dcbbbee --- /dev/null +++ b/firmware/cc1101.cpp @@ -0,0 +1,150 @@ +#include +#include "ELECHOUSE_CC1101_SRC_DRV.h" +#include "cc1101.h" +#include "config.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 < 50) return; + + captureBuffer[pulseIndex++] = duration; + lastEdgeTime = now; +} + +// ===== OOK SETUP ===== +void setupOOKMode() +{ + ELECHOUSE_cc1101.SetRx(); + ELECHOUSE_cc1101.setMHZ(currentFreq); + + ELECHOUSE_cc1101.setModulation(0); // 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) ===== +bool initCC1101() +{ + if (cc1101Inited) + return true; + + Serial.println("Initializing CC1101..."); + + // IMPORTANT: no detachInterrupt here (causes crash if not installed) + + ELECHOUSE_cc1101.setSpiPin( + cc1101_SCK, + cc1101_MISO, + cc1101_MOSI, + CC1101_CS + ); + + ELECHOUSE_cc1101.setGDO(CC1101_GDO0, CC1101_GDO2); + + if (!ELECHOUSE_cc1101.getCC1101()) + { + Serial.println("❌ CC1101 NOT FOUND"); + return false; + } + + delay(10); // let SPI settle + + ELECHOUSE_cc1101.Init(); // THIS WAS YOUR FREEZE POINT + setupOOKMode(); + + pinMode(CC1101_GDO0, INPUT); + + Serial.println("✅ CC1101 READY"); + + cc1101Inited = true; + return true; +} + +// ===== CAPTURE CONTROL ===== +void startCapture() +{ + pulseIndex = 0; + capturing = true; + lastEdgeTime = micros(); + + attachInterrupt( + digitalPinToInterrupt(CC1101_GDO0), + pulseISR, + CHANGE + ); + + Serial.println("Capture started"); +} + +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("Replaying..."); + + 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(); +} diff --git a/firmware/cc1101.h b/firmware/cc1101.h new file mode 100644 index 0000000..a403edb --- /dev/null +++ b/firmware/cc1101.h @@ -0,0 +1,9 @@ +#pragma once + +bool initCC1101(); +bool isCC1101Ready(); + +void startCapture(); +void stopCapture(); +void printCapture(); +void replaySignal(); diff --git a/firmware/config.h b/firmware/config.h new file mode 100644 index 0000000..ce40ebc --- /dev/null +++ b/firmware/config.h @@ -0,0 +1,48 @@ +#pragma once + +// ================= NRF24 ================= +#define CE1_PIN 10 +#define CSN1_PIN 11 + +#define CE2_PIN 12 +#define CSN2_PIN 13 + +#define NRF_SCK 18 +#define NRF_MISO 16 +#define NRF_MOSI 17 + +// ================== OLED =================== +#define OLED_SDA_PIN 8 +#define OLED_SCL_PIN 9 + +/////////////////cc1101 vars////////////// +// CC1101 via FSPI +#define cc1101_SCK 15 +#define cc1101_MISO 3 +#define cc1101_MOSI 46 + +//////////////cc1101(1)////////// +#define CC1101_CS 45 +#define CC1101_GDO0 21 +#define CC1101_GDO2 47 + +/////////////cc1101(2)////////// +#define CC1101_2_CS 40 +#define CC1101_2_GDO0 41 +#define CC1101_2_GDO2 42 + +// SD Card via HSPI +#define SD_SCK 14 +#define SD_MISO 39 +#define SD_MOSI 38 +#define SD_CS 37 + + +// =================== Buttons ==================== +#define BTN_UP 4 +#define BTN_DOWN 5 +#define BTN_SELECT 6 +#define BTN_BACK 7 +#define BTN_LEFT 1 +#define BTN_RIGHT 2 + diff --git a/firmware/data/ESP32-BLE-Mouse.zip b/firmware/data/ESP32-BLE-Mouse.zip new file mode 100644 index 0000000000000000000000000000000000000000..43e49f4b6c6c8cfc778017794865832a687fbfe3 GIT binary patch literal 7810 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 yeqQ(q&BFa>(Ek|mZTa(0 +#include +#include +#include +#include "ELECHOUSE_CC1101_SRC_DRV.h" + +#include "display.h" +#include "buttons.h" +#include "config.h" + +// ===== EXTERNALS ===== +extern RF24 radio1; +extern RF24 radio2; +extern SPIClass *RADIO_SPI; +extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2; + +// ===== RESULTS ===== +struct DeviceStatus { + bool nrf_link = false; + bool nrf1 = false; + bool nrf2 = false; + bool cc1101 = false; + bool oled = true; + bool buttons = false; +}; + +// ===== NRF CHECK ===== +bool checkNRF(RF24 &radio) +{ + // safer: only init if needed + if (!radio.isChipConnected()) { + if (!radio.begin(RADIO_SPI)) + return false; + } + + return radio.isChipConnected(); +} + +// ===== CC1101 CHECK ===== +bool checkCC1101() +{ + ELECHOUSE_cc1101.setSpiPin( + cc1101_SCK, + cc1101_MISO, + cc1101_MOSI, + CC1101_CS + ); + + delay(5); // important stabilization + + return ELECHOUSE_cc1101.getCC1101(); +} + +// ===== BUTTON CHECK ===== +bool checkButtons() +{ + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_6x10_tr); + u8g2.drawStr(0, 20, "Press any button..."); + u8g2.sendBuffer(); + + unsigned long start = millis(); + + while (millis() - start < 2000) + { + if (!digitalRead(BTN_UP) || + !digitalRead(BTN_DOWN) || + !digitalRead(BTN_SELECT) || + !digitalRead(BTN_BACK)) + { + return true; + } + } + + return false; +} + +// ===== DRAW ===== +#define MAX_ITEMS 6 +#define VISIBLE_ROWS 5 + +const char* labels[MAX_ITEMS] = { + "NRF1", + "NRF2", + "LINK", + "CC1101", + "BUTTONS", + "OLED" +}; + +bool values[MAX_ITEMS]; + +int selectedIndex = 0; +int offset = 0; + +void drawStatus(DeviceStatus &s) +{ + values[0] = s.nrf1; + values[1] = s.nrf2; + values[2] = s.nrf_link; + values[3] = s.cc1101; + values[4] = s.buttons; + values[5] = s.oled; + + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_6x10_tr); + + // scrolling logic + if (selectedIndex < offset) + offset = selectedIndex; + + if (selectedIndex >= offset + VISIBLE_ROWS) + offset = selectedIndex - VISIBLE_ROWS + 1; + + for (int i = 0; i < VISIBLE_ROWS; i++) + { + int item = offset + i; + if (item >= MAX_ITEMS) break; + + int y = 12 + i * 10; + + if (item == selectedIndex) + { + u8g2.drawBox(0, y - 9, 128, 10); + u8g2.setDrawColor(0); + } + + u8g2.drawStr(2, y, labels[item]); + + if (values[item]) + u8g2.drawStr(80, y, "OK"); + else + u8g2.drawStr(80, y, "FAIL"); + + if (item == selectedIndex) + u8g2.setDrawColor(1); + } + + u8g2.sendBuffer(); +} + +bool testNRFLink() +{ + const byte address[6] = "00001"; + uint8_t payload = 0xAB; + uint8_t received = 0; + + // --- init radios --- + if (!radio1.begin(RADIO_SPI)) return false; + if (!radio2.begin(RADIO_SPI)) return false; + + radio1.setPALevel(RF24_PA_LOW); + radio2.setPALevel(RF24_PA_LOW); + + radio1.setDataRate(RF24_1MBPS); + radio2.setDataRate(RF24_1MBPS); + + radio1.setChannel(100); + radio2.setChannel(100); + + radio1.setAutoAck(false); + radio2.setAutoAck(false); + + // --- configure pipes --- + radio1.openWritingPipe(address); + radio2.openReadingPipe(0, address); + + radio2.startListening(); + + delay(50); + + // --- send --- + radio1.stopListening(); + bool sent = radio1.write(&payload, sizeof(payload)); + + if (!sent) return false; + + // --- receive --- + unsigned long start = millis(); + + while (millis() - start < 200) + { + if (radio2.available()) + { + radio2.read(&received, sizeof(received)); + return (received == payload); + } + } + + return false; +} + +// ===== MAIN ===== +void device_check_run() +{ + DeviceStatus status; + + Serial.println("Running device diagnostics..."); + + // NRF + // NRF link test + status.nrf_link = testNRFLink(); + status.nrf1 = checkNRF(radio1); + status.nrf2 = checkNRF(radio2); + + // CC1101 + status.cc1101 = checkCC1101(); + + // Buttons + status.buttons = checkButtons(); + + drawStatus(status); + + Serial.println("Diagnostics complete"); + +while (1) +{ +drawStatus(status); + +if (btnUp()) +{ +selectedIndex--; +if (selectedIndex < 0) selectedIndex = MAX_ITEMS - 1; +delay(150); +} + +if (btnDown()) +{ +selectedIndex++; +if (selectedIndex >= MAX_ITEMS) selectedIndex = 0; +delay(150); +} + +if (btnBack()) +{ +delay(150); +break; +} +}} + + + diff --git a/firmware/device_check.h b/firmware/device_check.h new file mode 100644 index 0000000..3d6b250 --- /dev/null +++ b/firmware/device_check.h @@ -0,0 +1,3 @@ +#pragma once + +void device_check_run(); diff --git a/firmware/display.cpp b/firmware/display.cpp new file mode 100644 index 0000000..12c9ac9 --- /dev/null +++ b/firmware/display.cpp @@ -0,0 +1,16 @@ +#include "display.h" +#include +#include "config.h" + + +U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2( + U8G2_R0, + U8X8_PIN_NONE +); + +void displayInit() +{ + Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN); + u8g2.begin(); + u8g2.setFont(u8g2_font_6x12_tr); +} diff --git a/firmware/display.h b/firmware/display.h new file mode 100644 index 0000000..0b48b75 --- /dev/null +++ b/firmware/display.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2; + +void displayInit(); diff --git a/firmware/firmware.ino b/firmware/firmware.ino new file mode 100644 index 0000000..5b71a60 --- /dev/null +++ b/firmware/firmware.ino @@ -0,0 +1,128 @@ +#include +#include +#include + +#include +#include + +#include +#include + +#include "ELECHOUSE_CC1101_SRC_DRV.h" + +#include +#include + +#include +#include +#include +#include + + +#include "display.h" +#include "buttons.h" +#include "menu.h" + +#include "config.h" +#include "cc1101.h" + +// ================= USB HID ================= +USBHIDKeyboard Keyboard; + + +RF24 radio1(CE1_PIN, CSN1_PIN); +RF24 radio2(CE2_PIN, CSN2_PIN); +SPIClass *RADIO_SPI; + + + + +// ================= BLE SCAN ================= +BLEScan *pBLEScan; + + +void startBLEScan() +{ + BLEDevice::init(""); + + pBLEScan = BLEDevice::getScan(); + + pBLEScan->setActiveScan(true); + + pBLEScan->start(5); + + Serial.println("BLE scan complete"); +} + +// ================= SYSTEM INFO ================= +void printSystemUsage() +{ + esp_chip_info_t chip_info; + + esp_chip_info(&chip_info); + + Serial.printf("CPU cores: %d\n", chip_info.cores); + + Serial.printf( + "Free heap: %d bytes\n", + heap_caps_get_free_size(MALLOC_CAP_DEFAULT) + ); + + Serial.printf( + "PSRAM free: %d bytes\n", + heap_caps_get_free_size(MALLOC_CAP_SPIRAM) + ); +} + +void showSplash() +{ + u8g2.clearBuffer(); + + u8g2.setFont(u8g2_font_logisoso20_tr); // big font + u8g2.drawStr(10, 40, "Orion-RF"); + + u8g2.setFont(u8g2_font_5x8_tr); // small subtitle + u8g2.drawStr(25, 58, "Initializing..."); + + u8g2.sendBuffer(); + + delay(1500); // 1.5 sec +} + + +// ================= SETUP ================= +void setup() +{ + Serial.begin(115200); + + displayInit(); + showSplash(); + + buttonsInit(); + menuInit(); + + delay(1500); + + USB.begin(); + Keyboard.begin(); + + // NRF SPI safety + pinMode(CSN1_PIN, OUTPUT); + digitalWrite(CSN1_PIN, HIGH); + + pinMode(CSN2_PIN, OUTPUT); + digitalWrite(CSN2_PIN, HIGH); + + RADIO_SPI = new SPIClass(FSPI); + RADIO_SPI->begin(NRF_SCK, NRF_MISO, NRF_MOSI); + + printSystemUsage(); + + Serial.println("SYSTEM READY"); +} + +// ================= LOOP ================= +void loop() +{ + menuLoop(); +} diff --git a/firmware/menu.cpp b/firmware/menu.cpp new file mode 100644 index 0000000..411df35 --- /dev/null +++ b/firmware/menu.cpp @@ -0,0 +1,278 @@ +#include +#include "menu.h" +#include "display.h" +#include "buttons.h" +#include "badusb.h" +#include "nrf24.h" +#include "cc1101.h" +#include "blescanner.h" +#include "wifi_scan.h" +#include "wifi_analyzer.h" +#include "device_check.h" + +// ================= FEATURE HANDLERS ================= +void runSystemInfoFeature(); +void runRFCaptureFeature(); +void runBLEScanFeature(); + + + +// ================= MENU DATA ================= + +// Root menu +const char *mainMenuItems[] = { + "BadUSB", + "RF Capture", + "NRF Jammer", + "BLE Scan", + "Wifi Scan", + "Wifi Analyzer", + "System Info", + "Device Check", + "Restart" +}; + +Menu mainMenu = {mainMenuItems, sizeof(mainMenuItems) / sizeof(mainMenuItems[0])}; + +// BadUSB submenu +const char *badusbItems[] = { + "Demo", + "Open CMD", + "Rickroll"}; + +Menu badusbMenu = {badusbItems, 3}; + +// ================= MENU STATE ================= + +Menu *currentMenu = &mainMenu; + +int menuIndex = 0; +int menuOffset = 0; + +#define MENU_VISIBLE_ROWS 4 + +bool insideFeature = false; + +// ================= DRAW ================= + +void drawMenu() +{ + u8g2.clearBuffer(); + + // scroll handling + if (menuIndex < menuOffset) + menuOffset = menuIndex; + + if (menuIndex >= menuOffset + MENU_VISIBLE_ROWS) + menuOffset = menuIndex - MENU_VISIBLE_ROWS + 1; + + for (int i = 0; i < MENU_VISIBLE_ROWS; i++) + { + int item = menuOffset + i; + + if (item >= currentMenu->size) + break; + + if (item == menuIndex) + u8g2.drawStr(0, 14 + i * 14, ">"); + + u8g2.drawStr(10, 14 + i * 14, currentMenu->items[item]); + } + + // scroll indicators + if (menuOffset > 0) + u8g2.drawStr(118, 10, "^"); + + if (menuOffset + MENU_VISIBLE_ROWS < currentMenu->size) + u8g2.drawStr(118, 62, "v"); + + u8g2.sendBuffer(); +} + +// ================= FEATURE EXECUTION ================= + +void launchFeature() +{ + insideFeature = true; + + if (currentMenu == &mainMenu) + { + switch (menuIndex) + { + case 0: // BadUSB → enter submenu + currentMenu = &badusbMenu; + menuIndex = 0; + menuOffset = 0; + break; + + case 1: + if (!isCC1101Ready()) { + if (!initCC1101()) { + Serial.println("CC1101 failed"); + return; + } + } + + Serial.println("Ready to capture..."); + + startCapture(); + delay(5000); + stopCapture(); + printCapture(); + break; + case 2: + startNRFJammer(); + break; + + case 3: + ble_scan(); + ble_drawMenu(); + while (1) { + ble_loop(); + if (btnBack()) + break; + } + break; + + case 4: + { + // Start scan once + wifi_scan_start(); + wifi_scan_draw(); + + while (1) { + wifi_scan_loop(); + // EXIT condition handled ONLY here + if (btnBack()) { + delay(150); // debounce + break; + } + } + break; + } + case 5: + { + + wifi_analyzer_start(); + + bool prevBack = false; + while (1) + { + wifi_analyzer_loop(); + bool nowBack = btnBack(); + if (nowBack && !prevBack) + { + delay(150); + break; + } + prevBack = nowBack; + } + break; + } + + case 6: + runSystemInfoFeature(); + break; + case 7: + device_check_run(); + break; + case 8: + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_6x13_tr); + u8g2.drawStr(30, 30, "Restarting..."); + u8g2.sendBuffer(); + delay(1000); + ESP.restart(); + break; + } + } + else if (currentMenu == &badusbMenu) + { + switch (menuIndex) + { + case 0: + runBadUSBDemo(); + break; + + case 1: + Serial.println("Open CMD payload"); + runBadUSBOpenCMD(); + break; + + case 2: + Serial.println("Rickroll payload"); + runBadUSBRickroll(); + break; + } + } + + insideFeature = false; + + drawMenu(); +} + +// ================= INIT ================= + +void menuInit() +{ + currentMenu = &mainMenu; + menuIndex = 0; + menuOffset = 0; + + drawMenu(); +} + +// ================= LOOP ================= + +void menuLoop() +{ + static uint32_t lastPress = 0; + + if (insideFeature) + return; + + if (millis() - lastPress < 150) + return; + + if (btnUp()) + { + menuIndex--; + + if (menuIndex < 0) + menuIndex = currentMenu->size - 1; + + drawMenu(); + lastPress = millis(); + } + + else if (btnDown()) + { + menuIndex++; + + if (menuIndex >= currentMenu->size) + menuIndex = 0; + + drawMenu(); + lastPress = millis(); + } + + else if (btnSelect()) + { + launchFeature(); + lastPress = millis(); + } + + else if (btnBack()) + { + if (currentMenu != &mainMenu) + { + currentMenu = &mainMenu; + menuIndex = 0; + menuOffset = 0; + + drawMenu(); + } + + lastPress = millis(); + } +} diff --git a/firmware/menu.h b/firmware/menu.h new file mode 100644 index 0000000..c51cd24 --- /dev/null +++ b/firmware/menu.h @@ -0,0 +1,10 @@ +#pragma once + +struct Menu +{ + const char **items; + int size; +}; + +void menuInit(); +void menuLoop(); diff --git a/firmware/nrf24.cpp b/firmware/nrf24.cpp new file mode 100644 index 0000000..8c1b4d9 --- /dev/null +++ b/firmware/nrf24.cpp @@ -0,0 +1,99 @@ +#include +#include +#include "buttons.h" +#include "nrf24.h" +#include "display.h" +#define JAM_DURATION 500 + +extern SPIClass *RADIO_SPI; +extern RF24 radio1; +extern RF24 radio2; + +void initNRF(RF24 &radio) +{ + radio.begin(RADIO_SPI); + + radio.setAutoAck(false); + radio.stopListening(); + + radio.setRetries(0, 0); + radio.setDataRate(RF24_2MBPS); +radio.setPALevel(RF24_PA_MAX); + + radio.openWritingPipe(0xE7E7E7E7E7LL); +} + + +void jamChannels(const char* label, int startCh, int endCh) { + byte data1[32], data2[32]; + for (int i = 0; i < 32; i++) { + data1[i] = random(0, 256); + data2[i] = random(0, 256); + } + + for (int ch = startCh; ch <= endCh; ch++) { + // Status screen + u8g2.clearBuffer(); + u8g2.drawStr(0, 10, "Jamming:"); + u8g2.setCursor(60, 10); + u8g2.print(label); + u8g2.setCursor(0, 30); + u8g2.print("Channel: "); + u8g2.print(ch); + u8g2.sendBuffer(); + + unsigned long startTime = millis(); + while (millis() - startTime < JAM_DURATION) { + radio1.setChannel(ch); + radio1.stopListening(); + radio1.write(data1, sizeof(data1)); + delayMicroseconds(100); + + radio2.setChannel(ch); + radio2.stopListening(); + radio2.write(data2, sizeof(data2)); + delayMicroseconds(100); + + } +} +} + + +void nrfJammerSweep() +{ + static uint8_t ch1 = 0; + static uint8_t ch2 = 124; + + uint8_t payload[32] = {0xFF}; + + radio1.setChannel(ch1); + radio1.writeFast(payload, sizeof(payload)); + + radio2.setChannel(ch2); + radio2.writeFast(payload, sizeof(payload)); + + ch1++; + ch2--; + + if (ch1 > 124) ch1 = 0; + if (ch2 > 124) ch2 = 124; +} + +void startNRFJammer() +{ + initNRF(radio1); + initNRF(radio2); + + Serial.println("NRF JAMMER STARTED"); + // nrfJammerSweep(); + jamChannels("Bluetooth", 0, 78); + + + if (btnBack()) + { + Serial.println("Jammer stopped"); + return; + } + + delayMicroseconds(200); +} diff --git a/firmware/nrf24.h b/firmware/nrf24.h new file mode 100644 index 0000000..9d543fc --- /dev/null +++ b/firmware/nrf24.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +// Initialization +void initNRF(RF24 &radio); + +// Jammer modes +void startNRFJammer(); // dual-radio sweep jammer +void stopNRFJammer(); // (optional, for future) + +// Advanced (later) +void nrfJammerSweep(); // internal, but can expose if needed +void nrfSetChannel(uint8_t ch); diff --git a/firmware/stubs.cpp b/firmware/stubs.cpp new file mode 100644 index 0000000..c7782ca --- /dev/null +++ b/firmware/stubs.cpp @@ -0,0 +1,13 @@ +#include + + +void runRFCaptureFeature() +{ + Serial.println("RF Capture not implemented yet"); +} + + +void runBLEScanFeature() +{ + Serial.println("BLE Scan not implemented yet"); +} diff --git a/firmware/sysinfo.cpp b/firmware/sysinfo.cpp new file mode 100644 index 0000000..afd13aa --- /dev/null +++ b/firmware/sysinfo.cpp @@ -0,0 +1,87 @@ +#include +#include "display.h" +#include "buttons.h" +#include +#include + +void runSystemInfoFeature() +{ + esp_chip_info_t chip_info; + + esp_chip_info(&chip_info); + + while (true) + { + //u8g2.clearBuffer(); + + //char buf[32]; + + //sprintf(buf, "Cores: %d", chip_info.cores); + //u8g2.drawStr(0, 14, buf); + + //sprintf(buf, "Heap: %d", + // heap_caps_get_free_size(MALLOC_CAP_DEFAULT)); + //u8g2.drawStr(0, 28, buf); + + + //u8g2.drawStr(0, 60, "BACK to exit"); + + // Get RAM info + size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); + size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT); + int ramUsage = 100 - ((freeHeap * 100) / totalHeap); + + // Get Flash info + //uint32_t flashSize = spi_flash_get_chip_size(); + uint32_t flashSize = ESP.getFlashChipSize(); + uint32_t flashUsed = ESP.getSketchSize(); + int flashUsage = (flashUsed * 100) / flashSize; + + // Temperature (approx) + uint8_t temperature = temperatureRead(); + + // Chip info + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_6x12_tr); + + char buf[32]; + + // Box 1 - RAM + u8g2.drawFrame(0, 0, 128, 12); + sprintf(buf, "RAM: %d%% used", ramUsage); + u8g2.drawStr(4, 9, buf); + + // Box 2 - Flash + u8g2.drawFrame(0, 12, 128, 12); + sprintf(buf, "Flash: %d%% used", flashUsage); + u8g2.drawStr(4, 21, buf); + + // Box 3 - Temp (FULL WIDTH now) + u8g2.drawFrame(0, 24, 128, 12); + sprintf(buf, "Temp: %d C", temperature); + u8g2.drawStr(4, 33, buf); + + // Box 4 - Chip info (FULL WIDTH) + u8g2.drawFrame(0, 36, 128, 12); + sprintf(buf, "Cores: %d Rev: %d", chip_info.cores, chip_info.revision); + u8g2.drawStr(4, 45, buf); + + // Box 5 - PSRAM (KB) + u8g2.drawFrame(0, 48, 128, 12); + sprintf(buf, "PSRAM: %lu KB", heap_caps_get_free_size(MALLOC_CAP_SPIRAM) / 1024); + u8g2.drawStr(4, 57, buf); + + u8g2.sendBuffer(); + + if (btnBack()) + { + delay(200); + return; + } + + delay(100); + } +} diff --git a/firmware/sysinfo.h b/firmware/sysinfo.h new file mode 100644 index 0000000..8a4f176 --- /dev/null +++ b/firmware/sysinfo.h @@ -0,0 +1,3 @@ +#pragma once + +void runSystemInfoFeature(); diff --git a/firmware/wifi_analyzer.cpp b/firmware/wifi_analyzer.cpp new file mode 100644 index 0000000..0264088 --- /dev/null +++ b/firmware/wifi_analyzer.cpp @@ -0,0 +1,147 @@ +#include +#include +#include + +#include "display.h" +#include "buttons.h" + +// ===== CONFIG ===== +#define GRAPH_WIDTH 128 +#define GRAPH_HEIGHT 44 +#define GRAPH_TOP 10 +#define MAX_POINTS 128 +#define SPIKE_THRESHOLD 30 + +// ===== STATE ===== +struct SnifferGraph { + uint8_t graphData[MAX_POINTS]; + uint8_t currentChannel = 1; + volatile uint16_t packetCounter = 0; + unsigned long lastChannelSwitch = 0; + unsigned long lastUpdate = 0; +}; + +static SnifferGraph sniffer; + +// ===== CALLBACK ===== +void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type) +{ + if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL) + { + sniffer.packetCounter++; + } +} + +// ===== INIT ===== +void wifi_analyzer_start() +{ + // display init (safe to call again) + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_5x8_tr); + u8g2.drawStr(0, 10, "Starting analyzer..."); + u8g2.sendBuffer(); + + // reset graph + memset(sniffer.graphData, 0, sizeof(sniffer.graphData)); + sniffer.packetCounter = 0; + sniffer.currentChannel = 1; + + // reset WiFi + WiFi.disconnect(true, true); + esp_wifi_stop(); + delay(200); + esp_wifi_deinit(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&cfg); + esp_wifi_set_storage(WIFI_STORAGE_RAM); + esp_wifi_set_mode(WIFI_MODE_NULL); + esp_wifi_start(); + + esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE); + esp_wifi_set_promiscuous_rx_cb(snifferCallback); + esp_wifi_set_promiscuous(true); +} + +// ===== HELPERS ===== +static void switchChannel() +{ + sniffer.currentChannel++; + if (sniffer.currentChannel > 13) sniffer.currentChannel = 1; + + esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE); +} + +static void updateGraph(uint8_t value) +{ + for (int i = 0; i < MAX_POINTS - 1; i++) + { + sniffer.graphData[i] = sniffer.graphData[i + 1]; + } + + sniffer.graphData[MAX_POINTS - 1] = value; +} + +static void drawGraph(uint16_t pktCount) +{ + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_5x8_tr); + + char line1[16]; + char line2[16]; + + sprintf(line1, "Ch:%d", sniffer.currentChannel); + sprintf(line2, "Pkts:%d", pktCount * 5); + + u8g2.drawStr(0, 8, line1); + u8g2.drawStr(60, 8, line2); + + for (int x = 1; x < GRAPH_WIDTH; x++) + { + int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1]; + int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x]; + + u8g2.drawLine(x - 1, y1, x, y2); + } + + if (pktCount >= SPIKE_THRESHOLD) + { + u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT); + } + + u8g2.sendBuffer(); +} + +// ===== LOOP ===== +void wifi_analyzer_loop() +{ + static uint32_t lastPress = 0; + unsigned long now = millis(); + + // channel hopping + if (now - sniffer.lastChannelSwitch >= 1000) + { + sniffer.lastChannelSwitch = now; + switchChannel(); + } + + // graph update + if (now - sniffer.lastUpdate >= 200) + { + sniffer.lastUpdate = now; + + uint16_t pktCount = sniffer.packetCounter; + + uint8_t scaled = pktCount * 2; + uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT); + + updateGraph(value); + drawGraph(pktCount); + + sniffer.packetCounter = 0; + } + + // optional: small debounce to not hammer CPU + if (millis() - lastPress < 10) + return; +} diff --git a/firmware/wifi_analyzer.h b/firmware/wifi_analyzer.h new file mode 100644 index 0000000..df68284 --- /dev/null +++ b/firmware/wifi_analyzer.h @@ -0,0 +1,4 @@ +#pragma once + +void wifi_analyzer_start(); +void wifi_analyzer_loop(); diff --git a/firmware/wifi_scan.cpp b/firmware/wifi_scan.cpp new file mode 100644 index 0000000..d4657bb --- /dev/null +++ b/firmware/wifi_scan.cpp @@ -0,0 +1,152 @@ +#include +#include +#include "display.h" +#include "buttons.h" + +#define MAX_NETWORKS 30 + +struct WiFiNet { + String ssid; + int rssi; + int channel; + bool encrypted; +}; + +static WiFiNet networks[MAX_NETWORKS]; +static int networkCount = 0; +static int selectedIndex = 0; + +// ===== SCAN ===== +void wifi_scan_start() +{ + u8g2.clearBuffer(); + u8g2.drawStr(10, 30, "Scanning WiFi..."); + u8g2.sendBuffer(); + + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + + delay(100); + + int n = WiFi.scanNetworks(); + + networkCount = min(n, MAX_NETWORKS); + + for (int i = 0; i < networkCount; i++) + { + networks[i].ssid = WiFi.SSID(i); + networks[i].rssi = WiFi.RSSI(i); + networks[i].channel = WiFi.channel(i); + networks[i].encrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN); + } + + selectedIndex = 0; +} + +// ===== DRAW ===== +void wifi_scan_draw() +{ + u8g2.clearBuffer(); + + if (networkCount == 0) + { + u8g2.drawStr(0, 30, "No networks"); + u8g2.drawStr(0, 45, "Press BACK"); + } + else + { + char counter[20]; + sprintf(counter, "%d/%d", selectedIndex + 1, networkCount); + u8g2.setFont(u8g2_font_5x8_tr); + u8g2.drawStr(0, 8, counter); + + u8g2.setFont(u8g2_font_6x10_tr); + + for (int i = 0; i < 3; i++) + { + int idx = selectedIndex + i; + if (idx >= networkCount) break; + + int y = 22 + i * 14; + + if (i == 0) + { + u8g2.drawBox(0, y - 10, 128, 12); + u8g2.setDrawColor(0); + } + + String text = networks[idx].ssid; + if (text.length() > 10) + text = text.substring(0, 10) + ".."; + + text += " (" + String(networks[idx].rssi) + ")"; + + u8g2.drawStr(2, y, text.c_str()); + + if (i == 0) + u8g2.setDrawColor(1); + } + } + + u8g2.sendBuffer(); +} + +// ===== DETAILS ===== +void wifi_drawDetails() +{ + if (networkCount == 0) return; + + WiFiNet &net = networks[selectedIndex]; + + u8g2.clearBuffer(); + u8g2.setFont(u8g2_font_5x8_tr); + + u8g2.drawStr(0, 10, net.ssid.c_str()); + + char rssi[20]; + sprintf(rssi, "RSSI: %d", net.rssi); + u8g2.drawStr(0, 20, rssi); + + char ch[20]; + sprintf(ch, "CH: %d", net.channel); + u8g2.drawStr(0, 30, ch); + + u8g2.drawStr(0, 40, net.encrypted ? "Secured" : "Open"); + + u8g2.sendBuffer(); +} + +// ===== LOOP ===== +void wifi_scan_loop() +{ + static uint32_t lastPress = 0; + + if (millis() - lastPress < 150) + return; + + if (btnDown() && selectedIndex < networkCount - 1) + { + selectedIndex++; + wifi_scan_draw(); + lastPress = millis(); + } + else if (btnUp() && selectedIndex > 0) + { + selectedIndex--; + wifi_scan_draw(); + lastPress = millis(); + } + else if (btnSelect() && networkCount > 0) + { + wifi_drawDetails(); + delay(3000); + wifi_scan_draw(); + lastPress = millis(); + } +// else if (btnBack()) +// { +// wifi_scan_start(); +// wifi_scan_draw(); +// lastPress = millis(); +// } +} diff --git a/firmware/wifi_scan.h b/firmware/wifi_scan.h new file mode 100644 index 0000000..902054e --- /dev/null +++ b/firmware/wifi_scan.h @@ -0,0 +1,5 @@ +#pragma once + +void wifi_scan_start(); +void wifi_scan_loop(); +void wifi_scan_draw();