Krolyxon
Commit 0a40daf

Branches

Tags

Refs →

orion-rf0a40daf

initial commit

Author
krolyxon
Date
2026-05-04 22:48 +0530
Parents
None
Commit
0a40daf4fad5c1593c6e1696ac0cab992c799e2e

+3228 −0

30 files changed

  1. A .gitignore +5 −0
  2. A assets/initial_workflow_diagram.png
  3. A firmware/ELECHOUSE_CC1101_SRC_DRV.cpp +1309 −0
  4. A firmware/ELECHOUSE_CC1101_SRC_DRV.h +194 −0
  5. A firmware/badusb.cpp +56 −0
  6. A firmware/badusb.h +5 −0
  7. A firmware/blescanner.cpp +211 −0
  8. A firmware/blescanner.h +5 −0
  9. A firmware/buttons.cpp +20 −0
  10. A firmware/buttons.h +8 −0
  11. A firmware/cc1101.cpp +150 −0
  12. A firmware/cc1101.h +9 −0
  13. A firmware/config.h +48 −0
  14. A firmware/data/ESP32-BLE-Mouse.zip
  15. A firmware/device_check.cpp +242 −0
  16. A firmware/device_check.h +3 −0
  17. A firmware/display.cpp +16 −0
  18. A firmware/display.h +7 −0
  19. A firmware/firmware.ino +128 −0
  20. A firmware/menu.cpp +278 −0
  21. A firmware/menu.h +10 −0
  22. A firmware/nrf24.cpp +99 −0
  23. A firmware/nrf24.h +14 −0
  24. A firmware/stubs.cpp +13 −0
  25. A firmware/sysinfo.cpp +87 −0
  26. A firmware/sysinfo.h +3 −0
  27. A firmware/wifi_analyzer.cpp +147 −0
  28. A firmware/wifi_analyzer.h +4 −0
  29. A firmware/wifi_scan.cpp +152 −0
  30. A firmware/wifi_scan.h +5 −0
A .gitignore View
@@ -0,0 +1,5 @@
1+schmatics
2+documentation
3+
4+# Clangd cache
5+.cache
A assets/initial_workflow_diagram.png View

[Binary file]

A firmware/ELECHOUSE_CC1101_SRC_DRV.cpp View
@@ -0,0 +1,1309 @@
1+/*
2+ ELECHOUSE_CC1101.cpp - CC1101 module library
3+ Copyright (c) 2010 Michael.
4+ Author: Michael, <www.elechouse.com>
5+ Version: November 12, 2010
6+
7+ This library is designed to use CC1101/CC1100 module on Arduino platform.
8+ CC1101/CC1100 module is an useful wireless module.Using the functions of the
9+ library, you can easily send and receive data by the CC1101/CC1100 module.
10+ Just have fun!
11+ For the details, please refer to the datasheet of CC1100/CC1101.
12+----------------------------------------------------------------------------------------------------------------
13+cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE).
14+----------------------------------------------------------------------------------------------------------------
15+*/
16+#include <SPI.h>
17+#include "ELECHOUSE_CC1101_SRC_DRV.h"
18+#include <Arduino.h>
19+
20+/****************************************************************/
21+#define WRITE_BURST 0x40 //write burst
22+#define READ_SINGLE 0x80 //read single
23+#define READ_BURST 0xC0 //read burst
24+#define BYTES_IN_RXFIFO 0x7F //byte number in RXfifo
25+#define max_modul 6
26+
27+SPIClass CCSPI(HSPI);
28+
29+byte modulation = 2;
30+byte frend0;
31+byte chan = 0;
32+int pa = 12;
33+byte last_pa;
34+byte SCK_PIN;
35+byte MISO_PIN;
36+byte MOSI_PIN;
37+byte SS_PIN;
38+byte GDO0;
39+byte GDO2;
40+byte SCK_PIN_M[max_modul];
41+byte MISO_PIN_M[max_modul];
42+byte MOSI_PIN_M[max_modul];
43+byte SS_PIN_M[max_modul];
44+byte GDO0_M[max_modul];
45+byte GDO2_M[max_modul];
46+byte gdo_set=0;
47+bool spi = 0;
48+bool ccmode = 0;
49+float MHz = 433.92;
50+byte m4RxBw = 0;
51+byte m4DaRa;
52+byte m2DCOFF;
53+byte m2MODFM;
54+byte m2MANCH;
55+byte m2SYNCM;
56+byte m1FEC;
57+byte m1PRE;
58+byte m1CHSP;
59+byte pc1PQT;
60+byte pc1CRC_AF;
61+byte pc1APP_ST;
62+byte pc1ADRCHK;
63+byte pc0WDATA;
64+byte pc0PktForm;
65+byte pc0CRC_EN;
66+byte pc0LenConf;
67+byte trxstate = 0;
68+byte clb1[2]= {24,28};
69+byte clb2[2]= {31,38};
70+byte clb3[2]= {65,76};
71+byte clb4[2]= {77,79};
72+
73+/****************************************************************/
74+uint8_t PA_TABLE[8] {0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00};
75+// -30 -20 -15 -10 0 5 7 10
76+uint8_t PA_TABLE_315[8] {0x12,0x0D,0x1C,0x34,0x51,0x85,0xCB,0xC2,}; //300 - 348
77+uint8_t PA_TABLE_433[8] {0x12,0x0E,0x1D,0x34,0x60,0x84,0xC8,0xC0,}; //387 - 464
78+// -30 -20 -15 -10 -6 0 5 7 10 12
79+uint8_t PA_TABLE_868[10] {0x03,0x17,0x1D,0x26,0x37,0x50,0x86,0xCD,0xC5,0xC0,}; //779 - 899.99
80+// -30 -20 -15 -10 -6 0 5 7 10 11
81+uint8_t PA_TABLE_915[10] {0x03,0x0E,0x1E,0x27,0x38,0x8E,0x84,0xCC,0xC3,0xC0,}; //900 - 928
82+/****************************************************************
83+*FUNCTION NAME:SpiStart
84+*FUNCTION :spi communication start
85+*INPUT :none
86+*OUTPUT :none
87+****************************************************************/
88+void ELECHOUSE_CC1101::SpiStart(void)
89+{
90+ // initialize the SPI pins
91+ pinMode(SCK_PIN, OUTPUT);
92+ pinMode(MOSI_PIN, OUTPUT);
93+ pinMode(MISO_PIN, INPUT);
94+ pinMode(SS_PIN, OUTPUT);
95+
96+ // enable SPI
97+ #ifdef ESP32
98+ CCSPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN);
99+ #else
100+ CCSPI.begin();
101+ #endif
102+}
103+/****************************************************************
104+*FUNCTION NAME:SpiEnd
105+*FUNCTION :spi communication disable
106+*INPUT :none
107+*OUTPUT :none
108+****************************************************************/
109+void ELECHOUSE_CC1101::SpiEnd(void)
110+{
111+ // disable SPI
112+ CCSPI.endTransaction();
113+ CCSPI.end();
114+}
115+/****************************************************************
116+*FUNCTION NAME: GDO_Set()
117+*FUNCTION : set GDO0,GDO2 pin for serial pinmode.
118+*INPUT : none
119+*OUTPUT : none
120+****************************************************************/
121+void ELECHOUSE_CC1101::GDO_Set (void)
122+{
123+ pinMode(GDO0, OUTPUT);
124+ pinMode(GDO2, INPUT);
125+}
126+/****************************************************************
127+*FUNCTION NAME: GDO_Set()
128+*FUNCTION : set GDO0 for internal transmission mode.
129+*INPUT : none
130+*OUTPUT : none
131+****************************************************************/
132+void ELECHOUSE_CC1101::GDO0_Set (void)
133+{
134+ pinMode(GDO0, INPUT);
135+}
136+/****************************************************************
137+*FUNCTION NAME:Reset
138+*FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100//
139+*INPUT :none
140+*OUTPUT :none
141+****************************************************************/
142+void ELECHOUSE_CC1101::Reset (void)
143+{
144+ digitalWrite(SS_PIN, LOW);
145+ delay(1);
146+ digitalWrite(SS_PIN, HIGH);
147+ delay(1);
148+ digitalWrite(SS_PIN, LOW);
149+ while(digitalRead(MISO_PIN));
150+ CCSPI.transfer(CC1101_SRES);
151+ while(digitalRead(MISO_PIN));
152+ digitalWrite(SS_PIN, HIGH);
153+}
154+/****************************************************************
155+*FUNCTION NAME:Init
156+*FUNCTION :CC1101 initialization
157+*INPUT :none
158+*OUTPUT :none
159+****************************************************************/
160+void ELECHOUSE_CC1101::Init(void)
161+{
162+ setSpi();
163+ SpiStart(); //spi initialization
164+ digitalWrite(SS_PIN, HIGH);
165+ digitalWrite(SCK_PIN, HIGH);
166+ digitalWrite(MOSI_PIN, LOW);
167+ Reset(); //CC1101 reset
168+ RegConfigSettings(); //CC1101 register config
169+ SpiEnd();
170+}
171+/****************************************************************
172+*FUNCTION NAME:SpiWriteReg
173+*FUNCTION :CC1101 write data to register
174+*INPUT :addr: register address; value: register value
175+*OUTPUT :none
176+****************************************************************/
177+void ELECHOUSE_CC1101::SpiWriteReg(byte addr, byte value)
178+{
179+ SpiStart();
180+ digitalWrite(SS_PIN, LOW);
181+ while(digitalRead(MISO_PIN));
182+ CCSPI.transfer(addr);
183+ CCSPI.transfer(value);
184+ digitalWrite(SS_PIN, HIGH);
185+ SpiEnd();
186+}
187+/****************************************************************
188+*FUNCTION NAME:SpiWriteBurstReg
189+*FUNCTION :CC1101 write burst data to register
190+*INPUT :addr: register address; buffer:register value array; num:number to write
191+*OUTPUT :none
192+****************************************************************/
193+void ELECHOUSE_CC1101::SpiWriteBurstReg(byte addr, byte *buffer, byte num)
194+{
195+ byte i, temp;
196+ SpiStart();
197+ temp = addr | WRITE_BURST;
198+ digitalWrite(SS_PIN, LOW);
199+ while(digitalRead(MISO_PIN));
200+ CCSPI.transfer(temp);
201+ for (i = 0; i < num; i++)
202+ {
203+ CCSPI.transfer(buffer[i]);
204+ }
205+ digitalWrite(SS_PIN, HIGH);
206+ SpiEnd();
207+}
208+/****************************************************************
209+*FUNCTION NAME:SpiStrobe
210+*FUNCTION :CC1101 Strobe
211+*INPUT :strobe: command; //refer define in CC1101.h//
212+*OUTPUT :none
213+****************************************************************/
214+void ELECHOUSE_CC1101::SpiStrobe(byte strobe)
215+{
216+ SpiStart();
217+ digitalWrite(SS_PIN, LOW);
218+ while(digitalRead(MISO_PIN));
219+ CCSPI.transfer(strobe);
220+ digitalWrite(SS_PIN, HIGH);
221+ SpiEnd();
222+}
223+/****************************************************************
224+*FUNCTION NAME:SpiReadReg
225+*FUNCTION :CC1101 read data from register
226+*INPUT :addr: register address
227+*OUTPUT :register value
228+****************************************************************/
229+byte ELECHOUSE_CC1101::SpiReadReg(byte addr)
230+{
231+ byte temp, value;
232+ SpiStart();
233+ temp = addr| READ_SINGLE;
234+ digitalWrite(SS_PIN, LOW);
235+ while(digitalRead(MISO_PIN));
236+ CCSPI.transfer(temp);
237+ value=CCSPI.transfer(0);
238+ digitalWrite(SS_PIN, HIGH);
239+ SpiEnd();
240+ return value;
241+}
242+
243+/****************************************************************
244+*FUNCTION NAME:SpiReadBurstReg
245+*FUNCTION :CC1101 read burst data from register
246+*INPUT :addr: register address; buffer:array to store register value; num: number to read
247+*OUTPUT :none
248+****************************************************************/
249+void ELECHOUSE_CC1101::SpiReadBurstReg(byte addr, byte *buffer, byte num)
250+{
251+ byte i,temp;
252+ SpiStart();
253+ temp = addr | READ_BURST;
254+ digitalWrite(SS_PIN, LOW);
255+ while(digitalRead(MISO_PIN));
256+ CCSPI.transfer(temp);
257+ for(i=0;i<num;i++)
258+ {
259+ buffer[i]=CCSPI.transfer(0);
260+ }
261+ digitalWrite(SS_PIN, HIGH);
262+ SpiEnd();
263+}
264+
265+/****************************************************************
266+*FUNCTION NAME:SpiReadStatus
267+*FUNCTION :CC1101 read status register
268+*INPUT :addr: register address
269+*OUTPUT :status value
270+****************************************************************/
271+byte ELECHOUSE_CC1101::SpiReadStatus(byte addr)
272+{
273+ byte value,temp;
274+ SpiStart();
275+ temp = addr | READ_BURST;
276+ digitalWrite(SS_PIN, LOW);
277+ while(digitalRead(MISO_PIN));
278+ CCSPI.transfer(temp);
279+ value=CCSPI.transfer(0);
280+ digitalWrite(SS_PIN, HIGH);
281+ SpiEnd();
282+ return value;
283+}
284+/****************************************************************
285+*FUNCTION NAME:SPI pin Settings
286+*FUNCTION :Set Spi pins
287+*INPUT :none
288+*OUTPUT :none
289+****************************************************************/
290+void ELECHOUSE_CC1101::setSpi(void){
291+ if (spi == 0){
292+ #if defined __AVR_ATmega168__ || defined __AVR_ATmega328P__
293+ SCK_PIN = 13; MISO_PIN = 12; MOSI_PIN = 11; SS_PIN = 10;
294+ #elif defined __AVR_ATmega1280__ || defined __AVR_ATmega2560__
295+ SCK_PIN = 52; MISO_PIN = 50; MOSI_PIN = 51; SS_PIN = 53;
296+ #elif ESP8266
297+ SCK_PIN = 14; MISO_PIN = 12; MOSI_PIN = 13; SS_PIN = 15;
298+ #elif ESP32
299+ SCK_PIN = 18; MISO_PIN = 19; MOSI_PIN = 23; SS_PIN = 5;
300+ #else
301+ SCK_PIN = 13; MISO_PIN = 12; MOSI_PIN = 11; SS_PIN = 10;
302+ #endif
303+}
304+}
305+/****************************************************************
306+*FUNCTION NAME:COSTUM SPI
307+*FUNCTION :set costum spi pins.
308+*INPUT :none
309+*OUTPUT :none
310+****************************************************************/
311+void ELECHOUSE_CC1101::setSpiPin(byte sck, byte miso, byte mosi, byte ss){
312+ spi = 1;
313+ SCK_PIN = sck;
314+ MISO_PIN = miso;
315+ MOSI_PIN = mosi;
316+ SS_PIN = ss;
317+}
318+/****************************************************************
319+*FUNCTION NAME:COSTUM SPI
320+*FUNCTION :set costum spi pins.
321+*INPUT :none
322+*OUTPUT :none
323+****************************************************************/
324+void ELECHOUSE_CC1101::addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul){
325+ spi = 1;
326+ SCK_PIN_M[modul] = sck;
327+ MISO_PIN_M[modul] = miso;
328+ MOSI_PIN_M[modul] = mosi;
329+ SS_PIN_M[modul] = ss;
330+}
331+/****************************************************************
332+*FUNCTION NAME:GDO Pin settings
333+*FUNCTION :set GDO Pins
334+*INPUT :none
335+*OUTPUT :none
336+****************************************************************/
337+void ELECHOUSE_CC1101::setGDO(byte gdo0, byte gdo2){
338+GDO0 = gdo0;
339+GDO2 = gdo2;
340+GDO_Set();
341+}
342+/****************************************************************
343+*FUNCTION NAME:GDO0 Pin setting
344+*FUNCTION :set GDO0 Pin
345+*INPUT :none
346+*OUTPUT :none
347+****************************************************************/
348+void ELECHOUSE_CC1101::setGDO0(byte gdo0){
349+GDO0 = gdo0;
350+GDO0_Set();
351+}
352+/****************************************************************
353+*FUNCTION NAME:GDO Pin settings
354+*FUNCTION :add GDO Pins
355+*INPUT :none
356+*OUTPUT :none
357+****************************************************************/
358+void ELECHOUSE_CC1101::addGDO(byte gdo0, byte gdo2, byte modul){
359+GDO0_M[modul] = gdo0;
360+GDO2_M[modul] = gdo2;
361+gdo_set=2;
362+GDO_Set();
363+}
364+/****************************************************************
365+*FUNCTION NAME:add GDO0 Pin
366+*FUNCTION :add GDO0 Pin
367+*INPUT :none
368+*OUTPUT :none
369+****************************************************************/
370+void ELECHOUSE_CC1101::addGDO0(byte gdo0, byte modul){
371+GDO0_M[modul] = gdo0;
372+gdo_set=1;
373+GDO0_Set();
374+}
375+/****************************************************************
376+*FUNCTION NAME:set Modul
377+*FUNCTION :change modul
378+*INPUT :none
379+*OUTPUT :none
380+****************************************************************/
381+void ELECHOUSE_CC1101::setModul(byte modul){
382+ SCK_PIN = SCK_PIN_M[modul];
383+ MISO_PIN = MISO_PIN_M[modul];
384+ MOSI_PIN = MOSI_PIN_M[modul];
385+ SS_PIN = SS_PIN_M[modul];
386+ if (gdo_set==1){
387+ GDO0 = GDO0_M[modul];
388+ }
389+ else if (gdo_set==2){
390+ GDO0 = GDO0_M[modul];
391+ GDO2 = GDO2_M[modul];
392+ }
393+}
394+/****************************************************************
395+*FUNCTION NAME:CCMode
396+*FUNCTION :Format of RX and TX data
397+*INPUT :none
398+*OUTPUT :none
399+****************************************************************/
400+void ELECHOUSE_CC1101::setCCMode(bool s){
401+ccmode = s;
402+if (ccmode == 1){
403+SpiWriteReg(CC1101_IOCFG2, 0x0B);
404+SpiWriteReg(CC1101_IOCFG0, 0x06);
405+SpiWriteReg(CC1101_PKTCTRL0, 0x05);
406+SpiWriteReg(CC1101_MDMCFG3, 0xF8);
407+SpiWriteReg(CC1101_MDMCFG4,11+m4RxBw);
408+}else{
409+SpiWriteReg(CC1101_IOCFG2, 0x0D);
410+SpiWriteReg(CC1101_IOCFG0, 0x0D);
411+SpiWriteReg(CC1101_PKTCTRL0, 0x32);
412+SpiWriteReg(CC1101_MDMCFG3, 0x93);
413+SpiWriteReg(CC1101_MDMCFG4, 7+m4RxBw);
414+}
415+setModulation(modulation);
416+}
417+/****************************************************************
418+*FUNCTION NAME:Modulation
419+*FUNCTION :set CC1101 Modulation
420+*INPUT :none
421+*OUTPUT :none
422+****************************************************************/
423+void ELECHOUSE_CC1101::setModulation(byte m){
424+if (m>4){m=4;}
425+modulation = m;
426+Split_MDMCFG2();
427+switch (m)
428+{
429+case 0: m2MODFM=0x00; frend0=0x10; break; // 2-FSK
430+case 1: m2MODFM=0x10; frend0=0x10; break; // GFSK
431+case 2: m2MODFM=0x30; frend0=0x11; break; // ASK
432+case 3: m2MODFM=0x40; frend0=0x10; break; // 4-FSK
433+case 4: m2MODFM=0x70; frend0=0x10; break; // MSK
434+}
435+SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM);
436+SpiWriteReg(CC1101_FREND0, frend0);
437+setPA(pa);
438+}
439+/****************************************************************
440+*FUNCTION NAME:PA Power
441+*FUNCTION :set CC1101 PA Power
442+*INPUT :none
443+*OUTPUT :none
444+****************************************************************/
445+void ELECHOUSE_CC1101::setPA(int p)
446+{
447+int a;
448+pa = p;
449+
450+if (MHz >= 300 && MHz <= 348){
451+if (pa <= -30){a = PA_TABLE_315[0];}
452+else if (pa > -30 && pa <= -20){a = PA_TABLE_315[1];}
453+else if (pa > -20 && pa <= -15){a = PA_TABLE_315[2];}
454+else if (pa > -15 && pa <= -10){a = PA_TABLE_315[3];}
455+else if (pa > -10 && pa <= 0){a = PA_TABLE_315[4];}
456+else if (pa > 0 && pa <= 5){a = PA_TABLE_315[5];}
457+else if (pa > 5 && pa <= 7){a = PA_TABLE_315[6];}
458+else if (pa > 7){a = PA_TABLE_315[7];}
459+last_pa = 1;
460+}
461+else if (MHz >= 378 && MHz <= 464){
462+if (pa <= -30){a = PA_TABLE_433[0];}
463+else if (pa > -30 && pa <= -20){a = PA_TABLE_433[1];}
464+else if (pa > -20 && pa <= -15){a = PA_TABLE_433[2];}
465+else if (pa > -15 && pa <= -10){a = PA_TABLE_433[3];}
466+else if (pa > -10 && pa <= 0){a = PA_TABLE_433[4];}
467+else if (pa > 0 && pa <= 5){a = PA_TABLE_433[5];}
468+else if (pa > 5 && pa <= 7){a = PA_TABLE_433[6];}
469+else if (pa > 7){a = PA_TABLE_433[7];}
470+last_pa = 2;
471+}
472+else if (MHz >= 779 && MHz <= 899.99){
473+if (pa <= -30){a = PA_TABLE_868[0];}
474+else if (pa > -30 && pa <= -20){a = PA_TABLE_868[1];}
475+else if (pa > -20 && pa <= -15){a = PA_TABLE_868[2];}
476+else if (pa > -15 && pa <= -10){a = PA_TABLE_868[3];}
477+else if (pa > -10 && pa <= -6){a = PA_TABLE_868[4];}
478+else if (pa > -6 && pa <= 0){a = PA_TABLE_868[5];}
479+else if (pa > 0 && pa <= 5){a = PA_TABLE_868[6];}
480+else if (pa > 5 && pa <= 7){a = PA_TABLE_868[7];}
481+else if (pa > 7 && pa <= 10){a = PA_TABLE_868[8];}
482+else if (pa > 10){a = PA_TABLE_868[9];}
483+last_pa = 3;
484+}
485+else if (MHz >= 900 && MHz <= 928){
486+if (pa <= -30){a = PA_TABLE_915[0];}
487+else if (pa > -30 && pa <= -20){a = PA_TABLE_915[1];}
488+else if (pa > -20 && pa <= -15){a = PA_TABLE_915[2];}
489+else if (pa > -15 && pa <= -10){a = PA_TABLE_915[3];}
490+else if (pa > -10 && pa <= -6){a = PA_TABLE_915[4];}
491+else if (pa > -6 && pa <= 0){a = PA_TABLE_915[5];}
492+else if (pa > 0 && pa <= 5){a = PA_TABLE_915[6];}
493+else if (pa > 5 && pa <= 7){a = PA_TABLE_915[7];}
494+else if (pa > 7 && pa <= 10){a = PA_TABLE_915[8];}
495+else if (pa > 10){a = PA_TABLE_915[9];}
496+last_pa = 4;
497+}
498+if (modulation == 2){
499+PA_TABLE[0] = 0;
500+PA_TABLE[1] = a;
501+}else{
502+PA_TABLE[0] = a;
503+PA_TABLE[1] = 0;
504+}
505+SpiWriteBurstReg(CC1101_PATABLE,PA_TABLE,8);
506+}
507+/****************************************************************
508+*FUNCTION NAME:Frequency Calculator
509+*FUNCTION :Calculate the basic frequency.
510+*INPUT :none
511+*OUTPUT :none
512+****************************************************************/
513+void ELECHOUSE_CC1101::setMHZ(float mhz){
514+byte freq2 = 0;
515+byte freq1 = 0;
516+byte freq0 = 0;
517+
518+MHz = mhz;
519+
520+for (bool i = 0; i==0;){
521+if (mhz >= 26){
522+mhz-=26;
523+freq2+=1;
524+}
525+else if (mhz >= 0.1015625){
526+mhz-=0.1015625;
527+freq1+=1;
528+}
529+else if (mhz >= 0.00039675){
530+mhz-=0.00039675;
531+freq0+=1;
532+}
533+else{i=1;}
534+}
535+if (freq0 > 255){freq1+=1;freq0-=256;}
536+
537+SpiWriteReg(CC1101_FREQ2, freq2);
538+SpiWriteReg(CC1101_FREQ1, freq1);
539+SpiWriteReg(CC1101_FREQ0, freq0);
540+
541+Calibrate();
542+}
543+/****************************************************************
544+*FUNCTION NAME:Calibrate
545+*FUNCTION :Calibrate frequency
546+*INPUT :none
547+*OUTPUT :none
548+****************************************************************/
549+void ELECHOUSE_CC1101::Calibrate(void){
550+
551+if (MHz >= 300 && MHz <= 348){
552+SpiWriteReg(CC1101_FSCTRL0, map(MHz, 300, 348, clb1[0], clb1[1]));
553+if (MHz < 322.88){SpiWriteReg(CC1101_TEST0,0x0B);}
554+else{
555+SpiWriteReg(CC1101_TEST0,0x09);
556+int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2);
557+if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);}
558+if (last_pa != 1){setPA(pa);}
559+}
560+}
561+else if (MHz >= 378 && MHz <= 464){
562+SpiWriteReg(CC1101_FSCTRL0, map(MHz, 378, 464, clb2[0], clb2[1]));
563+if (MHz < 430.5){SpiWriteReg(CC1101_TEST0,0x0B);}
564+else{
565+SpiWriteReg(CC1101_TEST0,0x09);
566+int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2);
567+if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);}
568+if (last_pa != 2){setPA(pa);}
569+}
570+}
571+else if (MHz >= 779 && MHz <= 899.99){
572+SpiWriteReg(CC1101_FSCTRL0, map(MHz, 779, 899, clb3[0], clb3[1]));
573+if (MHz < 861){SpiWriteReg(CC1101_TEST0,0x0B);}
574+else{
575+SpiWriteReg(CC1101_TEST0,0x09);
576+int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2);
577+if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);}
578+if (last_pa != 3){setPA(pa);}
579+}
580+}
581+else if (MHz >= 900 && MHz <= 928){
582+SpiWriteReg(CC1101_FSCTRL0, map(MHz, 900, 928, clb4[0], clb4[1]));
583+SpiWriteReg(CC1101_TEST0,0x09);
584+int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2);
585+if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);}
586+if (last_pa != 4){setPA(pa);}
587+}
588+}
589+/****************************************************************
590+*FUNCTION NAME:Calibration offset
591+*FUNCTION :Set calibration offset
592+*INPUT :none
593+*OUTPUT :none
594+****************************************************************/
595+void ELECHOUSE_CC1101::setClb(byte b, byte s, byte e){
596+if (b == 1){
597+clb1[0]=s;
598+clb1[1]=e;
599+}
600+else if (b == 2){
601+clb2[0]=s;
602+clb2[1]=e;
603+}
604+else if (b == 3){
605+clb3[0]=s;
606+clb3[1]=e;
607+}
608+else if (b == 4){
609+clb4[0]=s;
610+clb4[1]=e;
611+}
612+}
613+/****************************************************************
614+*FUNCTION NAME:getCC1101
615+*FUNCTION :Test Spi connection and return 1 when true.
616+*INPUT :none
617+*OUTPUT :none
618+****************************************************************/
619+bool ELECHOUSE_CC1101::getCC1101(void){
620+setSpi();
621+if (SpiReadStatus(0x31)>0){
622+return 1;
623+}else{
624+return 0;
625+}
626+}
627+/****************************************************************
628+*FUNCTION NAME:getMode
629+*FUNCTION :Return the Mode. Sidle = 0, TX = 1, Rx = 2.
630+*INPUT :none
631+*OUTPUT :none
632+****************************************************************/
633+byte ELECHOUSE_CC1101::getMode(void){
634+return trxstate;
635+}
636+/****************************************************************
637+*FUNCTION NAME:Set Sync_Word
638+*FUNCTION :Sync Word
639+*INPUT :none
640+*OUTPUT :none
641+****************************************************************/
642+void ELECHOUSE_CC1101::setSyncWord(byte sh, byte sl){
643+SpiWriteReg(CC1101_SYNC1, sh);
644+SpiWriteReg(CC1101_SYNC0, sl);
645+}
646+/****************************************************************
647+*FUNCTION NAME:Set ADDR
648+*FUNCTION :Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
649+*INPUT :none
650+*OUTPUT :none
651+****************************************************************/
652+void ELECHOUSE_CC1101::setAddr(byte v){
653+SpiWriteReg(CC1101_ADDR, v);
654+}
655+/****************************************************************
656+*FUNCTION NAME:Set PQT
657+*FUNCTION :Preamble quality estimator threshold
658+*INPUT :none
659+*OUTPUT :none
660+****************************************************************/
661+void ELECHOUSE_CC1101::setPQT(byte v){
662+Split_PKTCTRL1();
663+pc1PQT = 0;
664+if (v>7){v=7;}
665+pc1PQT = v*32;
666+SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK);
667+}
668+/****************************************************************
669+*FUNCTION NAME:Set CRC_AUTOFLUSH
670+*FUNCTION :Enable automatic flush of RX FIFO when CRC is not OK
671+*INPUT :none
672+*OUTPUT :none
673+****************************************************************/
674+void ELECHOUSE_CC1101::setCRC_AF(bool v){
675+Split_PKTCTRL1();
676+pc1CRC_AF = 0;
677+if (v==1){pc1CRC_AF=8;}
678+SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK);
679+}
680+/****************************************************************
681+*FUNCTION NAME:Set APPEND_STATUS
682+*FUNCTION :When enabled, two status bytes will be appended to the payload of the packet
683+*INPUT :none
684+*OUTPUT :none
685+****************************************************************/
686+void ELECHOUSE_CC1101::setAppendStatus(bool v){
687+Split_PKTCTRL1();
688+pc1APP_ST = 0;
689+if (v==1){pc1APP_ST=4;}
690+SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK);
691+}
692+/****************************************************************
693+*FUNCTION NAME:Set ADR_CHK
694+*FUNCTION :Controls address check configuration of received packages
695+*INPUT :none
696+*OUTPUT :none
697+****************************************************************/
698+void ELECHOUSE_CC1101::setAdrChk(byte v){
699+Split_PKTCTRL1();
700+pc1ADRCHK = 0;
701+if (v>3){v=3;}
702+pc1ADRCHK = v;
703+SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK);
704+}
705+/****************************************************************
706+*FUNCTION NAME:Set WHITE_DATA
707+*FUNCTION :Turn data whitening on / off.
708+*INPUT :none
709+*OUTPUT :none
710+****************************************************************/
711+void ELECHOUSE_CC1101::setWhiteData(bool v){
712+Split_PKTCTRL0();
713+pc0WDATA = 0;
714+if (v == 1){pc0WDATA=64;}
715+SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf);
716+}
717+/****************************************************************
718+*FUNCTION NAME:Set PKT_FORMAT
719+*FUNCTION :Format of RX and TX data
720+*INPUT :none
721+*OUTPUT :none
722+****************************************************************/
723+void ELECHOUSE_CC1101::setPktFormat(byte v){
724+Split_PKTCTRL0();
725+pc0PktForm = 0;
726+if (v>3){v=3;}
727+pc0PktForm = v*16;
728+SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf);
729+}
730+/****************************************************************
731+*FUNCTION NAME:Set CRC
732+*FUNCTION :CRC calculation in TX and CRC check in RX
733+*INPUT :none
734+*OUTPUT :none
735+****************************************************************/
736+void ELECHOUSE_CC1101::setCrc(bool v){
737+Split_PKTCTRL0();
738+pc0CRC_EN = 0;
739+if (v==1){pc0CRC_EN=4;}
740+SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf);
741+}
742+/****************************************************************
743+*FUNCTION NAME:Set LENGTH_CONFIG
744+*FUNCTION :Configure the packet length
745+*INPUT :none
746+*OUTPUT :none
747+****************************************************************/
748+void ELECHOUSE_CC1101::setLengthConfig(byte v){
749+Split_PKTCTRL0();
750+pc0LenConf = 0;
751+if (v>3){v=3;}
752+pc0LenConf = v;
753+SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf);
754+}
755+/****************************************************************
756+*FUNCTION NAME:Set PACKET_LENGTH
757+*FUNCTION :Indicates the packet length
758+*INPUT :none
759+*OUTPUT :none
760+****************************************************************/
761+void ELECHOUSE_CC1101::setPacketLength(byte v){
762+SpiWriteReg(CC1101_PKTLEN, v);
763+}
764+/****************************************************************
765+*FUNCTION NAME:Set DCFILT_OFF
766+*FUNCTION :Disable digital DC blocking filter before demodulator
767+*INPUT :none
768+*OUTPUT :none
769+****************************************************************/
770+void ELECHOUSE_CC1101::setDcFilterOff(bool v){
771+Split_MDMCFG2();
772+m2DCOFF = 0;
773+if (v==1){m2DCOFF=128;}
774+SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM);
775+}
776+/****************************************************************
777+*FUNCTION NAME:Set MANCHESTER
778+*FUNCTION :Enables Manchester encoding/decoding
779+*INPUT :none
780+*OUTPUT :none
781+****************************************************************/
782+void ELECHOUSE_CC1101::setManchester(bool v){
783+Split_MDMCFG2();
784+m2MANCH = 0;
785+if (v==1){m2MANCH=8;}
786+SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM);
787+}
788+/****************************************************************
789+*FUNCTION NAME:Set SYNC_MODE
790+*FUNCTION :Combined sync-word qualifier mode
791+*INPUT :none
792+*OUTPUT :none
793+****************************************************************/
794+void ELECHOUSE_CC1101::setSyncMode(byte v){
795+Split_MDMCFG2();
796+m2SYNCM = 0;
797+if (v>7){v=7;}
798+m2SYNCM=v;
799+SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM);
800+}
801+/****************************************************************
802+*FUNCTION NAME:Set FEC
803+*FUNCTION :Enable Forward Error Correction (FEC)
804+*INPUT :none
805+*OUTPUT :none
806+****************************************************************/
807+void ELECHOUSE_CC1101::setFEC(bool v){
808+Split_MDMCFG1();
809+m1FEC=0;
810+if (v==1){m1FEC=128;}
811+SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP);
812+}
813+/****************************************************************
814+*FUNCTION NAME:Set PRE
815+*FUNCTION :Sets the minimum number of preamble bytes to be transmitted.
816+*INPUT :none
817+*OUTPUT :none
818+****************************************************************/
819+void ELECHOUSE_CC1101::setPRE(byte v){
820+Split_MDMCFG1();
821+m1PRE=0;
822+if (v>7){v=7;}
823+m1PRE = v*16;
824+SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP);
825+}
826+/****************************************************************
827+*FUNCTION NAME:Set Channel
828+*FUNCTION :none
829+*INPUT :none
830+*OUTPUT :none
831+****************************************************************/
832+void ELECHOUSE_CC1101::setChannel(byte ch){
833+chan = ch;
834+SpiWriteReg(CC1101_CHANNR, chan);
835+}
836+/****************************************************************
837+*FUNCTION NAME:Set Channel spacing
838+*FUNCTION :none
839+*INPUT :none
840+*OUTPUT :none
841+****************************************************************/
842+void ELECHOUSE_CC1101::setChsp(float f){
843+Split_MDMCFG1();
844+byte MDMCFG0 = 0;
845+m1CHSP = 0;
846+if (f > 405.456543){f = 405.456543;}
847+if (f < 25.390625){f = 25.390625;}
848+for (int i = 0; i<5; i++){
849+if (f <= 50.682068){
850+f -= 25.390625;
851+f /= 0.0991825;
852+MDMCFG0 = f;
853+float s1 = (f - MDMCFG0) *10;
854+if (s1 >= 5){MDMCFG0++;}
855+i = 5;
856+}else{
857+m1CHSP++;
858+f/=2;
859+}
860+}
861+SpiWriteReg(19,m1CHSP+m1FEC+m1PRE);
862+SpiWriteReg(20,MDMCFG0);
863+}
864+/****************************************************************
865+*FUNCTION NAME:Set Receive bandwidth
866+*FUNCTION :none
867+*INPUT :none
868+*OUTPUT :none
869+****************************************************************/
870+void ELECHOUSE_CC1101::setRxBW(float f){
871+Split_MDMCFG4();
872+int s1 = 3;
873+int s2 = 3;
874+for (int i = 0; i<3; i++){
875+if (f > 101.5625){f/=2; s1--;}
876+else{i=3;}
877+}
878+for (int i = 0; i<3; i++){
879+if (f > 58.1){f/=1.25; s2--;}
880+else{i=3;}
881+}
882+s1 *= 64;
883+s2 *= 16;
884+m4RxBw = s1 + s2;
885+SpiWriteReg(16,m4RxBw+m4DaRa);
886+}
887+/****************************************************************
888+*FUNCTION NAME:Set Data Rate
889+*FUNCTION :none
890+*INPUT :none
891+*OUTPUT :none
892+****************************************************************/
893+void ELECHOUSE_CC1101::setDRate(float d){
894+Split_MDMCFG4();
895+float c = d;
896+byte MDMCFG3 = 0;
897+if (c > 1621.83){c = 1621.83;}
898+if (c < 0.0247955){c = 0.0247955;}
899+m4DaRa = 0;
900+for (int i = 0; i<20; i++){
901+if (c <= 0.0494942){
902+c = c - 0.0247955;
903+c = c / 0.00009685;
904+MDMCFG3 = c;
905+float s1 = (c - MDMCFG3) *10;
906+if (s1 >= 5){MDMCFG3++;}
907+i = 20;
908+}else{
909+m4DaRa++;
910+c = c/2;
911+}
912+}
913+SpiWriteReg(16, m4RxBw+m4DaRa);
914+SpiWriteReg(17, MDMCFG3);
915+}
916+/****************************************************************
917+*FUNCTION NAME:Set Devitation
918+*FUNCTION :none
919+*INPUT :none
920+*OUTPUT :none
921+****************************************************************/
922+void ELECHOUSE_CC1101::setDeviation(float d){
923+float f = 1.586914;
924+float v = 0.19836425;
925+int c = 0;
926+if (d > 380.859375){d = 380.859375;}
927+if (d < 1.586914){d = 1.586914;}
928+for (int i = 0; i<255; i++){
929+f+=v;
930+if (c==7){v*=2;c=-1;i+=8;}
931+if (f>=d){c=i;i=255;}
932+c++;
933+}
934+SpiWriteReg(21,c);
935+}
936+/****************************************************************
937+*FUNCTION NAME:Split PKTCTRL0
938+*FUNCTION :none
939+*INPUT :none
940+*OUTPUT :none
941+****************************************************************/
942+void ELECHOUSE_CC1101::Split_PKTCTRL1(void){
943+int calc = SpiReadStatus(7);
944+pc1PQT = 0;
945+pc1CRC_AF = 0;
946+pc1APP_ST = 0;
947+pc1ADRCHK = 0;
948+for (bool i = 0; i==0;){
949+if (calc >= 32){calc-=32; pc1PQT+=32;}
950+else if (calc >= 8){calc-=8; pc1CRC_AF+=8;}
951+else if (calc >= 4){calc-=4; pc1APP_ST+=4;}
952+else {pc1ADRCHK = calc; i=1;}
953+}
954+}
955+/****************************************************************
956+*FUNCTION NAME:Split PKTCTRL0
957+*FUNCTION :none
958+*INPUT :none
959+*OUTPUT :none
960+****************************************************************/
961+void ELECHOUSE_CC1101::Split_PKTCTRL0(void){
962+int calc = SpiReadStatus(8);
963+pc0WDATA = 0;
964+pc0PktForm = 0;
965+pc0CRC_EN = 0;
966+pc0LenConf = 0;
967+for (bool i = 0; i==0;){
968+if (calc >= 64){calc-=64; pc0WDATA+=64;}
969+else if (calc >= 16){calc-=16; pc0PktForm+=16;}
970+else if (calc >= 4){calc-=4; pc0CRC_EN+=4;}
971+else {pc0LenConf = calc; i=1;}
972+}
973+}
974+/****************************************************************
975+*FUNCTION NAME:Split MDMCFG1
976+*FUNCTION :none
977+*INPUT :none
978+*OUTPUT :none
979+****************************************************************/
980+void ELECHOUSE_CC1101::Split_MDMCFG1(void){
981+int calc = SpiReadStatus(19);
982+m1FEC = 0;
983+m1PRE = 0;
984+m1CHSP = 0;
985+int s2 = 0;
986+for (bool i = 0; i==0;){
987+if (calc >= 128){calc-=128; m1FEC+=128;}
988+else if (calc >= 16){calc-=16; m1PRE+=16;}
989+else {m1CHSP = calc; i=1;}
990+}
991+}
992+/****************************************************************
993+*FUNCTION NAME:Split MDMCFG2
994+*FUNCTION :none
995+*INPUT :none
996+*OUTPUT :none
997+****************************************************************/
998+void ELECHOUSE_CC1101::Split_MDMCFG2(void){
999+int calc = SpiReadStatus(18);
1000+m2DCOFF = 0;
1001+m2MODFM = 0;
1002+m2MANCH = 0;
1003+m2SYNCM = 0;
1004+for (bool i = 0; i==0;){
1005+if (calc >= 128){calc-=128; m2DCOFF+=128;}
1006+else if (calc >= 16){calc-=16; m2MODFM+=16;}
1007+else if (calc >= 8){calc-=8; m2MANCH+=8;}
1008+else{m2SYNCM = calc; i=1;}
1009+}
1010+}
1011+/****************************************************************
1012+*FUNCTION NAME:Split MDMCFG4
1013+*FUNCTION :none
1014+*INPUT :none
1015+*OUTPUT :none
1016+****************************************************************/
1017+void ELECHOUSE_CC1101::Split_MDMCFG4(void){
1018+int calc = SpiReadStatus(16);
1019+m4RxBw = 0;
1020+m4DaRa = 0;
1021+for (bool i = 0; i==0;){
1022+if (calc >= 64){calc-=64; m4RxBw+=64;}
1023+else if (calc >= 16){calc -= 16; m4RxBw+=16;}
1024+else{m4DaRa = calc; i=1;}
1025+}
1026+}
1027+/****************************************************************
1028+*FUNCTION NAME:RegConfigSettings
1029+*FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100//
1030+*INPUT :none
1031+*OUTPUT :none
1032+****************************************************************/
1033+void ELECHOUSE_CC1101::RegConfigSettings(void)
1034+{
1035+ SpiWriteReg(CC1101_FSCTRL1, 0x06);
1036+
1037+ setCCMode(ccmode);
1038+ setMHZ(MHz);
1039+
1040+ SpiWriteReg(CC1101_MDMCFG1, 0x02);
1041+ SpiWriteReg(CC1101_MDMCFG0, 0xF8);
1042+ SpiWriteReg(CC1101_CHANNR, chan);
1043+ SpiWriteReg(CC1101_DEVIATN, 0x47);
1044+ SpiWriteReg(CC1101_FREND1, 0x56);
1045+ SpiWriteReg(CC1101_MCSM0 , 0x18);
1046+ SpiWriteReg(CC1101_FOCCFG, 0x16);
1047+ SpiWriteReg(CC1101_BSCFG, 0x1C);
1048+ SpiWriteReg(CC1101_AGCCTRL2, 0xC7);
1049+ SpiWriteReg(CC1101_AGCCTRL1, 0x00);
1050+ SpiWriteReg(CC1101_AGCCTRL0, 0xB2);
1051+ SpiWriteReg(CC1101_FSCAL3, 0xE9);
1052+ SpiWriteReg(CC1101_FSCAL2, 0x2A);
1053+ SpiWriteReg(CC1101_FSCAL1, 0x00);
1054+ SpiWriteReg(CC1101_FSCAL0, 0x1F);
1055+ SpiWriteReg(CC1101_FSTEST, 0x59);
1056+ SpiWriteReg(CC1101_TEST2, 0x81);
1057+ SpiWriteReg(CC1101_TEST1, 0x35);
1058+ SpiWriteReg(CC1101_TEST0, 0x09);
1059+ SpiWriteReg(CC1101_PKTCTRL1, 0x04);
1060+ SpiWriteReg(CC1101_ADDR, 0x00);
1061+ SpiWriteReg(CC1101_PKTLEN, 0x00);
1062+}
1063+/****************************************************************
1064+*FUNCTION NAME:SetTx
1065+*FUNCTION :set CC1101 send data
1066+*INPUT :none
1067+*OUTPUT :none
1068+****************************************************************/
1069+void ELECHOUSE_CC1101::SetTx(void)
1070+{
1071+ SpiStrobe(CC1101_SIDLE);
1072+ SpiStrobe(CC1101_STX); //start send
1073+ trxstate=1;
1074+}
1075+/****************************************************************
1076+*FUNCTION NAME:SetRx
1077+*FUNCTION :set CC1101 to receive state
1078+*INPUT :none
1079+*OUTPUT :none
1080+****************************************************************/
1081+void ELECHOUSE_CC1101::SetRx(void)
1082+{
1083+ SpiStrobe(CC1101_SIDLE);
1084+ SpiStrobe(CC1101_SRX); //start receive
1085+ trxstate=2;
1086+}
1087+/****************************************************************
1088+*FUNCTION NAME:SetTx
1089+*FUNCTION :set CC1101 send data and change frequency
1090+*INPUT :none
1091+*OUTPUT :none
1092+****************************************************************/
1093+void ELECHOUSE_CC1101::SetTx(float mhz)
1094+{
1095+ SpiStrobe(CC1101_SIDLE);
1096+ setMHZ(mhz);
1097+ SpiStrobe(CC1101_STX); //start send
1098+ trxstate=1;
1099+}
1100+/****************************************************************
1101+*FUNCTION NAME:SetRx
1102+*FUNCTION :set CC1101 to receive state and change frequency
1103+*INPUT :none
1104+*OUTPUT :none
1105+****************************************************************/
1106+void ELECHOUSE_CC1101::SetRx(float mhz)
1107+{
1108+ SpiStrobe(CC1101_SIDLE);
1109+ setMHZ(mhz);
1110+ SpiStrobe(CC1101_SRX); //start receive
1111+ trxstate=2;
1112+}
1113+/****************************************************************
1114+*FUNCTION NAME:RSSI Level
1115+*FUNCTION :Calculating the RSSI Level
1116+*INPUT :none
1117+*OUTPUT :none
1118+****************************************************************/
1119+int ELECHOUSE_CC1101::getRssi(void)
1120+{
1121+int rssi;
1122+rssi=SpiReadStatus(CC1101_RSSI);
1123+if (rssi >= 128){rssi = (rssi-256)/2-74;}
1124+else{rssi = (rssi/2)-74;}
1125+return rssi;
1126+}
1127+/****************************************************************
1128+*FUNCTION NAME:LQI Level
1129+*FUNCTION :get Lqi state
1130+*INPUT :none
1131+*OUTPUT :none
1132+****************************************************************/
1133+byte ELECHOUSE_CC1101::getLqi(void)
1134+{
1135+byte lqi;
1136+lqi=SpiReadStatus(CC1101_LQI);
1137+return lqi;
1138+}
1139+/****************************************************************
1140+*FUNCTION NAME:SetSres
1141+*FUNCTION :Reset CC1101
1142+*INPUT :none
1143+*OUTPUT :none
1144+****************************************************************/
1145+void ELECHOUSE_CC1101::setSres(void)
1146+{
1147+ SpiStrobe(CC1101_SRES);
1148+ trxstate=0;
1149+}
1150+/****************************************************************
1151+*FUNCTION NAME:setSidle
1152+*FUNCTION :set Rx / TX Off
1153+*INPUT :none
1154+*OUTPUT :none
1155+****************************************************************/
1156+void ELECHOUSE_CC1101::setSidle(void)
1157+{
1158+ SpiStrobe(CC1101_SIDLE);
1159+ trxstate=0;
1160+}
1161+/****************************************************************
1162+*FUNCTION NAME:goSleep
1163+*FUNCTION :set cc1101 Sleep on
1164+*INPUT :none
1165+*OUTPUT :none
1166+****************************************************************/
1167+void ELECHOUSE_CC1101::goSleep(void){
1168+ trxstate=0;
1169+ SpiStrobe(0x36);//Exit RX / TX, turn off frequency synthesizer and exit
1170+ SpiStrobe(0x39);//Enter power down mode when CSn goes high.
1171+}
1172+/****************************************************************
1173+*FUNCTION NAME:Char direct SendData
1174+*FUNCTION :use CC1101 send data
1175+*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61
1176+*OUTPUT :none
1177+****************************************************************/
1178+void ELECHOUSE_CC1101::SendData(char *txchar)
1179+{
1180+int len = strlen(txchar);
1181+byte chartobyte[len];
1182+for (int i = 0; i<len; i++){chartobyte[i] = txchar[i];}
1183+SendData(chartobyte,len);
1184+}
1185+/****************************************************************
1186+*FUNCTION NAME:SendData
1187+*FUNCTION :use CC1101 send data
1188+*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61
1189+*OUTPUT :none
1190+****************************************************************/
1191+void ELECHOUSE_CC1101::SendData(byte *txBuffer,byte size)
1192+{
1193+ SpiWriteReg(CC1101_TXFIFO,size);
1194+ SpiWriteBurstReg(CC1101_TXFIFO,txBuffer,size); //write data to send
1195+ SpiStrobe(CC1101_SIDLE);
1196+ SpiStrobe(CC1101_STX); //start send
1197+ while (!digitalRead(GDO0)); // Wait for GDO0 to be set -> sync transmitted
1198+ while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet
1199+ SpiStrobe(CC1101_SFTX); //flush TXfifo
1200+ trxstate=1;
1201+}
1202+/****************************************************************
1203+*FUNCTION NAME:Char direct SendData
1204+*FUNCTION :use CC1101 send data without GDO
1205+*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61
1206+*OUTPUT :none
1207+****************************************************************/
1208+void ELECHOUSE_CC1101::SendData(char *txchar,int t)
1209+{
1210+int len = strlen(txchar);
1211+byte chartobyte[len];
1212+for (int i = 0; i<len; i++){chartobyte[i] = txchar[i];}
1213+SendData(chartobyte,len,t);
1214+}
1215+/****************************************************************
1216+*FUNCTION NAME:SendData
1217+*FUNCTION :use CC1101 send data without GDO
1218+*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61
1219+*OUTPUT :none
1220+****************************************************************/
1221+void ELECHOUSE_CC1101::SendData(byte *txBuffer,byte size,int t)
1222+{
1223+ SpiWriteReg(CC1101_TXFIFO,size);
1224+ SpiWriteBurstReg(CC1101_TXFIFO,txBuffer,size); //write data to send
1225+ SpiStrobe(CC1101_SIDLE);
1226+ SpiStrobe(CC1101_STX); //start send
1227+ delay(t);
1228+ SpiStrobe(CC1101_SFTX); //flush TXfifo
1229+ trxstate=1;
1230+}
1231+/****************************************************************
1232+*FUNCTION NAME:Check CRC
1233+*FUNCTION :none
1234+*INPUT :none
1235+*OUTPUT :none
1236+****************************************************************/
1237+bool ELECHOUSE_CC1101::CheckCRC(void){
1238+byte lqi=SpiReadStatus(CC1101_LQI);
1239+bool crc_ok = bitRead(lqi,7);
1240+if (crc_ok == 1){
1241+return 1;
1242+}else{
1243+SpiStrobe(CC1101_SFRX);
1244+SpiStrobe(CC1101_SRX);
1245+return 0;
1246+}
1247+}
1248+/****************************************************************
1249+*FUNCTION NAME:CheckRxFifo
1250+*FUNCTION :check receive data or not
1251+*INPUT :none
1252+*OUTPUT :flag: 0 no data; 1 receive data
1253+****************************************************************/
1254+bool ELECHOUSE_CC1101::CheckRxFifo(int t){
1255+if(trxstate!=2){SetRx();}
1256+if(SpiReadStatus(CC1101_RXBYTES) & BYTES_IN_RXFIFO){
1257+delay(t);
1258+return 1;
1259+}else{
1260+return 0;
1261+}
1262+}
1263+/****************************************************************
1264+*FUNCTION NAME:CheckReceiveFlag
1265+*FUNCTION :check receive data or not
1266+*INPUT :none
1267+*OUTPUT :flag: 0 no data; 1 receive data
1268+****************************************************************/
1269+byte ELECHOUSE_CC1101::CheckReceiveFlag(void)
1270+{
1271+ if(trxstate!=2){SetRx();}
1272+ if(digitalRead(GDO0)) //receive data
1273+ {
1274+ while (digitalRead(GDO0));
1275+ return 1;
1276+ }
1277+ else // no data
1278+ {
1279+ return 0;
1280+ }
1281+}
1282+/****************************************************************
1283+*FUNCTION NAME:ReceiveData
1284+*FUNCTION :read data received from RXfifo
1285+*INPUT :rxBuffer: buffer to store data
1286+*OUTPUT :size of data received
1287+****************************************************************/
1288+byte ELECHOUSE_CC1101::ReceiveData(byte *rxBuffer)
1289+{
1290+ byte size;
1291+ byte status[2];
1292+
1293+ if(SpiReadStatus(CC1101_RXBYTES) & BYTES_IN_RXFIFO)
1294+ {
1295+ size=SpiReadReg(CC1101_RXFIFO);
1296+ SpiReadBurstReg(CC1101_RXFIFO,rxBuffer,size);
1297+ SpiReadBurstReg(CC1101_RXFIFO,status,2);
1298+ SpiStrobe(CC1101_SFRX);
1299+ SpiStrobe(CC1101_SRX);
1300+ return size;
1301+ }
1302+ else
1303+ {
1304+ SpiStrobe(CC1101_SFRX);
1305+ SpiStrobe(CC1101_SRX);
1306+ return 0;
1307+ }
1308+}
1309+ELECHOUSE_CC1101 ELECHOUSE_cc1101;
A firmware/ELECHOUSE_CC1101_SRC_DRV.h View
@@ -0,0 +1,194 @@
1+/*
2+ ELECHOUSE_CC1101.cpp - CC1101 module library
3+ Copyright (c) 2010 Michael.
4+ Author: Michael, <www.elechouse.com>
5+ Version: November 12, 2010
6+
7+ This library is designed to use CC1101/CC1100 module on Arduino platform.
8+ CC1101/CC1100 module is an useful wireless module.Using the functions of the
9+ library, you can easily send and receive data by the CC1101/CC1100 module.
10+ Just have fun!
11+ For the details, please refer to the datasheet of CC1100/CC1101.
12+----------------------------------------------------------------------------------------------------------------
13+cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE).
14+----------------------------------------------------------------------------------------------------------------
15+*/
16+#ifndef ELECHOUSE_CC1101_SRC_DRV_h
17+#define ELECHOUSE_CC1101_SRC_DRV_h
18+
19+#include <Arduino.h>
20+
21+//***************************************CC1101 define**************************************************//
22+// CC1101 CONFIG REGSITER
23+#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration
24+#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration
25+#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration
26+#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
27+#define CC1101_SYNC1 0x04 // Sync word, high INT8U
28+#define CC1101_SYNC0 0x05 // Sync word, low INT8U
29+#define CC1101_PKTLEN 0x06 // Packet length
30+#define CC1101_PKTCTRL1 0x07 // Packet automation control
31+#define CC1101_PKTCTRL0 0x08 // Packet automation control
32+#define CC1101_ADDR 0x09 // Device address
33+#define CC1101_CHANNR 0x0A // Channel number
34+#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control
35+#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control
36+#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U
37+#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U
38+#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U
39+#define CC1101_MDMCFG4 0x10 // Modem configuration
40+#define CC1101_MDMCFG3 0x11 // Modem configuration
41+#define CC1101_MDMCFG2 0x12 // Modem configuration
42+#define CC1101_MDMCFG1 0x13 // Modem configuration
43+#define CC1101_MDMCFG0 0x14 // Modem configuration
44+#define CC1101_DEVIATN 0x15 // Modem deviation setting
45+#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration
46+#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration
47+#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration
48+#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration
49+#define CC1101_BSCFG 0x1A // Bit Synchronization configuration
50+#define CC1101_AGCCTRL2 0x1B // AGC control
51+#define CC1101_AGCCTRL1 0x1C // AGC control
52+#define CC1101_AGCCTRL0 0x1D // AGC control
53+#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout
54+#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout
55+#define CC1101_WORCTRL 0x20 // Wake On Radio control
56+#define CC1101_FREND1 0x21 // Front end RX configuration
57+#define CC1101_FREND0 0x22 // Front end TX configuration
58+#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration
59+#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration
60+#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration
61+#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration
62+#define CC1101_RCCTRL1 0x27 // RC oscillator configuration
63+#define CC1101_RCCTRL0 0x28 // RC oscillator configuration
64+#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control
65+#define CC1101_PTEST 0x2A // Production test
66+#define CC1101_AGCTEST 0x2B // AGC test
67+#define CC1101_TEST2 0x2C // Various test settings
68+#define CC1101_TEST1 0x2D // Various test settings
69+#define CC1101_TEST0 0x2E // Various test settings
70+
71+//CC1101 Strobe commands
72+#define CC1101_SRES 0x30 // Reset chip.
73+#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
74+ // If in RX/TX: Go to a wait state where only the synthesizer is
75+ // running (for quick RX / TX turnaround).
76+#define CC1101_SXOFF 0x32 // Turn off crystal oscillator.
77+#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
78+ // (enables quick start).
79+#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
80+ // MCSM0.FS_AUTOCAL=1.
81+#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
82+ // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
83+ // Only go to TX if channel is clear.
84+#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
85+ // Wake-On-Radio mode if applicable.
86+#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
87+#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
88+#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.
89+#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.
90+#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.
91+#define CC1101_SWORRST 0x3C // Reset real time clock.
92+#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two
93+ // INT8Us for simpler software.
94+//CC1101 STATUS REGSITER
95+#define CC1101_PARTNUM 0x30
96+#define CC1101_VERSION 0x31
97+#define CC1101_FREQEST 0x32
98+#define CC1101_LQI 0x33
99+#define CC1101_RSSI 0x34
100+#define CC1101_MARCSTATE 0x35
101+#define CC1101_WORTIME1 0x36
102+#define CC1101_WORTIME0 0x37
103+#define CC1101_PKTSTATUS 0x38
104+#define CC1101_VCO_VC_DAC 0x39
105+#define CC1101_TXBYTES 0x3A
106+#define CC1101_RXBYTES 0x3B
107+
108+//CC1101 PATABLE,TXFIFO,RXFIFO
109+#define CC1101_PATABLE 0x3E
110+#define CC1101_TXFIFO 0x3F
111+#define CC1101_RXFIFO 0x3F
112+
113+//************************************* class **************************************************//
114+class ELECHOUSE_CC1101
115+{
116+private:
117+ void SpiStart(void);
118+ void SpiEnd(void);
119+ void GDO_Set (void);
120+ void GDO0_Set (void);
121+ void Reset (void);
122+ void setSpi(void);
123+ void RegConfigSettings(void);
124+ void Calibrate(void);
125+ void Split_PKTCTRL0(void);
126+ void Split_PKTCTRL1(void);
127+ void Split_MDMCFG1(void);
128+ void Split_MDMCFG2(void);
129+ void Split_MDMCFG4(void);
130+public:
131+ void Init(void);
132+ byte SpiReadStatus(byte addr);
133+ void setSpiPin(byte sck, byte miso, byte mosi, byte ss);
134+ void addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul);
135+ void setGDO(byte gdo0, byte gdo2);
136+ void setGDO0(byte gdo0);
137+ void addGDO(byte gdo0, byte gdo2, byte modul);
138+ void addGDO0(byte gdo0, byte modul);
139+ void setModul(byte modul);
140+ void setCCMode(bool s);
141+ void setModulation(byte m);
142+ void setPA(int p);
143+ void setMHZ(float mhz);
144+ void setChannel(byte chnl);
145+ void setChsp(float f);
146+ void setRxBW(float f);
147+ void setDRate(float d);
148+ void setDeviation(float d);
149+ void SetTx(void);
150+ void SetRx(void);
151+ void SetTx(float mhz);
152+ void SetRx(float mhz);
153+ int getRssi(void);
154+ byte getLqi(void);
155+ void setSres(void);
156+ void setSidle(void);
157+ void goSleep(void);
158+ void SendData(byte *txBuffer, byte size);
159+ void SendData(char *txchar);
160+ void SendData(byte *txBuffer, byte size, int t);
161+ void SendData(char *txchar, int t);
162+ byte CheckReceiveFlag(void);
163+ byte ReceiveData(byte *rxBuffer);
164+ bool CheckCRC(void);
165+ void SpiStrobe(byte strobe);
166+ void SpiWriteReg(byte addr, byte value);
167+ void SpiWriteBurstReg(byte addr, byte *buffer, byte num);
168+ byte SpiReadReg(byte addr);
169+ void SpiReadBurstReg(byte addr, byte *buffer, byte num);
170+ void setClb(byte b, byte s, byte e);
171+ bool getCC1101(void);
172+ byte getMode(void);
173+ void setSyncWord(byte sh, byte sl);
174+ void setAddr(byte v);
175+ void setWhiteData(bool v);
176+ void setPktFormat(byte v);
177+ void setCrc(bool v);
178+ void setLengthConfig(byte v);
179+ void setPacketLength(byte v);
180+ void setDcFilterOff(bool v);
181+ void setManchester(bool v);
182+ void setSyncMode(byte v);
183+ void setFEC(bool v);
184+ void setPRE(byte v);
185+ void setPQT(byte v);
186+ void setCRC_AF(bool v);
187+ void setAppendStatus(bool v);
188+ void setAdrChk(byte v);
189+ bool CheckRxFifo(int t);
190+};
191+
192+extern ELECHOUSE_CC1101 ELECHOUSE_cc1101;
193+
194+#endif
A firmware/badusb.cpp View
@@ -0,0 +1,56 @@
1+#include <Arduino.h>
2+#include <USBHIDKeyboard.h>
3+
4+extern USBHIDKeyboard Keyboard;
5+
6+void runBadUSBDemo()
7+{
8+ delay(2000);
9+ Keyboard.println("");
10+ Keyboard.println("#-FEATURES:");
11+ Keyboard.println("1- WIFI ATTACKS");
12+ Keyboard.println("2- BLE ATTACKS");
13+ Keyboard.println("3- BAD USB");
14+ Keyboard.println("4- NFC");
15+ Keyboard.println("5- INFRARED");
16+ Keyboard.println("6- SUB-GHZ");
17+ Keyboard.println("7- GPIO");
18+ Keyboard.println("8- APPS");
19+ Keyboard.println("9- SETTINGS");
20+ Keyboard.println("10- FILES");
21+
22+}
23+
24+void runBadUSBOpenCMD()
25+{
26+ delay(2000);
27+ Keyboard.println("");
28+ Keyboard.println("#-FEATURES:");
29+ Keyboard.println("1- WIFI ATTACKS");
30+ Keyboard.println("2- BLE ATTACKS");
31+ Keyboard.println("3- BAD USB");
32+ Keyboard.println("4- NFC");
33+ Keyboard.println("5- INFRARED");
34+ Keyboard.println("6- SUB-GHZ");
35+ Keyboard.println("7- GPIO");
36+ Keyboard.println("8- APPS");
37+ Keyboard.println("9- SETTINGS");
38+ Keyboard.println("10- FILES");
39+}
40+
41+void runBadUSBRickroll()
42+{
43+ delay(2000);
44+ Keyboard.println("");
45+ Keyboard.println("#-FEATURES:");
46+ Keyboard.println("1- WIFI ATTACKS");
47+ Keyboard.println("2- BLE ATTACKS");
48+ Keyboard.println("3- BAD USB");
49+ Keyboard.println("4- NFC");
50+ Keyboard.println("5- INFRARED");
51+ Keyboard.println("6- SUB-GHZ");
52+ Keyboard.println("7- GPIO");
53+ Keyboard.println("8- APPS");
54+ Keyboard.println("9- SETTINGS");
55+ Keyboard.println("10- FILES");
56+}
A firmware/badusb.h View
@@ -0,0 +1,5 @@
1+#pragma once
2+
3+void runBadUSBDemo();
4+void runBadUSBOpenCMD();
5+void runBadUSBRickroll();
A firmware/blescanner.cpp View
@@ -0,0 +1,211 @@
1+#include <Arduino.h>
2+#include <BLEDevice.h>
3+#include <BLEScan.h>
4+#include <BLEAdvertisedDevice.h>
5+#include <vector>
6+
7+#include "display.h"
8+#include "buttons.h"
9+#include "config.h"
10+
11+// ===== DEVICE STRUCT =====
12+struct BLEDeviceInfo {
13+ String name;
14+ String address;
15+ int rssi;
16+ String manufacturer;
17+ String deviceType;
18+};
19+
20+static std::vector<BLEDeviceInfo> devices;
21+static BLEScan *pBLEScan;
22+static int selectedIndex = 0;
23+
24+// ===== CALLBACK =====
25+class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
26+ void onResult(BLEAdvertisedDevice advertisedDevice) override {
27+ BLEDeviceInfo dev;
28+
29+ String tempName = advertisedDevice.getName();
30+
31+ if (tempName.length() == 0 && advertisedDevice.haveServiceData()) {
32+ tempName = advertisedDevice.getServiceData().c_str();
33+ }
34+
35+ if (tempName.length() == 0) {
36+ String addr = advertisedDevice.getAddress().toString().c_str();
37+ tempName = "BLE_" + addr.substring(addr.length() - 5);
38+ }
39+
40+ dev.name = tempName;
41+ dev.address = advertisedDevice.getAddress().toString().c_str();
42+ dev.rssi = advertisedDevice.getRSSI();
43+
44+ if (advertisedDevice.haveManufacturerData()) {
45+ String mData = advertisedDevice.getManufacturerData().c_str();
46+
47+ if (mData.length() >= 2) {
48+ char buffer[10];
49+ sprintf(buffer, "0x%02X%02X",
50+ (uint8_t)mData[1],
51+ (uint8_t)mData[0]);
52+ dev.manufacturer = String(buffer);
53+ } else {
54+ dev.manufacturer = "unknown";
55+ }
56+ } else {
57+ dev.manufacturer = "unknown";
58+ }
59+
60+ if (advertisedDevice.haveServiceUUID()) {
61+ dev.deviceType =
62+ advertisedDevice.getServiceUUID().toString().c_str();
63+ } else {
64+ dev.deviceType = "unknown";
65+ }
66+
67+ devices.push_back(dev);
68+ }
69+};
70+
71+// ===== DRAW MENU =====
72+void ble_drawMenu()
73+{
74+ u8g2.clearBuffer();
75+
76+ if (devices.empty())
77+ {
78+ u8g2.setFont(u8g2_font_6x12_tr);
79+ u8g2.drawStr(0, 30, "No devices");
80+ u8g2.drawStr(0, 45, "Press BACK");
81+ }
82+ else
83+ {
84+ u8g2.setFont(u8g2_font_5x8_tr);
85+
86+ char counter[20];
87+ sprintf(counter, "%d/%d", selectedIndex + 1, (int)devices.size());
88+ u8g2.drawStr(0, 8, counter);
89+
90+ u8g2.setFont(u8g2_font_6x10_tr);
91+
92+ for (int i = 0; i < 3; i++)
93+ {
94+ int idx = selectedIndex + i;
95+ if (idx >= devices.size()) break;
96+
97+ int y = 22 + i * 14;
98+
99+ if (i == 0)
100+ {
101+ u8g2.drawBox(0, y - 10, 128, 12);
102+ u8g2.setDrawColor(0);
103+ }
104+
105+ String text = devices[idx].name;
106+ if (text.length() > 12)
107+ text = text.substring(0, 12) + "..";
108+
109+ text += " (" + String(devices[idx].rssi) + ")";
110+
111+ u8g2.drawStr(2, y, text.c_str());
112+
113+ if (i == 0)
114+ u8g2.setDrawColor(1);
115+ }
116+ }
117+
118+ u8g2.sendBuffer();
119+}
120+
121+// ===== DEVICE DETAILS =====
122+void ble_drawDetails(const BLEDeviceInfo &dev)
123+{
124+ u8g2.clearBuffer();
125+ u8g2.setFont(u8g2_font_5x8_tr);
126+
127+ u8g2.drawStr(0, 10, dev.name.c_str());
128+ u8g2.drawStr(0, 20, dev.address.c_str());
129+
130+ char rssiStr[20];
131+ sprintf(rssiStr, "RSSI: %d", dev.rssi);
132+ u8g2.drawStr(0, 30, rssiStr);
133+
134+ u8g2.drawStr(0, 40, dev.manufacturer.c_str());
135+
136+ u8g2.sendBuffer();
137+}
138+
139+// ===== SCAN =====
140+void ble_scan()
141+{
142+ devices.clear();
143+
144+ u8g2.clearBuffer();
145+ u8g2.drawStr(10, 30, "Scanning...");
146+ u8g2.sendBuffer();
147+
148+ BLEDevice::init("");
149+
150+ pBLEScan = BLEDevice::getScan();
151+ pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
152+ pBLEScan->setActiveScan(true);
153+ pBLEScan->setInterval(100);
154+ pBLEScan->setWindow(99);
155+
156+ pBLEScan->start(5, false);
157+
158+ // remove duplicates
159+ std::vector<BLEDeviceInfo> unique;
160+ for (auto &d : devices)
161+ {
162+ bool exists = false;
163+ for (auto &u : unique)
164+ {
165+ if (u.address == d.address)
166+ {
167+ exists = true;
168+ break;
169+ }
170+ }
171+ if (!exists) unique.push_back(d);
172+ }
173+
174+ devices = unique;
175+}
176+
177+// ===== MAIN LOOP =====
178+void ble_loop()
179+{
180+ static uint32_t lastPress = 0;
181+
182+ if (millis() - lastPress < 200)
183+ return;
184+
185+ if (btnDown() && selectedIndex < (int)devices.size() - 1)
186+ {
187+ selectedIndex++;
188+ ble_drawMenu();
189+ lastPress = millis();
190+ }
191+ else if (btnUp() && selectedIndex > 0)
192+ {
193+ selectedIndex--;
194+ ble_drawMenu();
195+ lastPress = millis();
196+ }
197+ else if (btnSelect() && !devices.empty())
198+ {
199+ ble_drawDetails(devices[selectedIndex]);
200+ delay(3000);
201+ ble_drawMenu();
202+ lastPress = millis();
203+ }
204+ else if (btnBack())
205+ {
206+ ble_scan();
207+ selectedIndex = 0;
208+ ble_drawMenu();
209+ lastPress = millis();
210+ }
211+}
A firmware/blescanner.h View
@@ -0,0 +1,5 @@
1+#pragma once
2+
3+void ble_scan();
4+void ble_loop();
5+void ble_drawMenu();
A firmware/buttons.cpp View
@@ -0,0 +1,20 @@
1+#include "buttons.h"
2+#include <Arduino.h>
3+
4+#define BTN_UP 4
5+#define BTN_DOWN 5
6+#define BTN_SELECT 6
7+#define BTN_BACK 7
8+
9+void buttonsInit()
10+{
11+ pinMode(BTN_UP, INPUT_PULLUP);
12+ pinMode(BTN_DOWN, INPUT_PULLUP);
13+ pinMode(BTN_SELECT, INPUT_PULLUP);
14+ pinMode(BTN_BACK, INPUT_PULLUP);
15+}
16+
17+bool btnUp() { return !digitalRead(BTN_UP); }
18+bool btnDown() { return !digitalRead(BTN_DOWN); }
19+bool btnSelect() { return !digitalRead(BTN_SELECT); }
20+bool btnBack() { return !digitalRead(BTN_BACK); }
A firmware/buttons.h View
@@ -0,0 +1,8 @@
1+#pragma once
2+
3+void buttonsInit();
4+
5+bool btnUp();
6+bool btnDown();
7+bool btnSelect();
8+bool btnBack();
A firmware/cc1101.cpp View
@@ -0,0 +1,150 @@
1+#include <Arduino.h>
2+#include "ELECHOUSE_CC1101_SRC_DRV.h"
3+#include "cc1101.h"
4+#include "config.h"
5+
6+// ===== CONFIG =====
7+#define RAW_BUF_MAX 512
8+
9+// ===== STATE =====
10+static bool cc1101Inited = false;
11+
12+// ===== CAPTURE STATE =====
13+volatile unsigned long captureBuffer[RAW_BUF_MAX];
14+volatile int pulseIndex = 0;
15+volatile unsigned long lastEdgeTime = 0;
16+volatile bool capturing = false;
17+
18+// ===== RF SETTINGS =====
19+float currentFreq = 433.92;
20+float dataRate = 3.79372;
21+float deviation = 0.0;
22+float rxBW = 325.0;
23+int powerLevel = 10;
24+
25+// ===== ISR =====
26+void IRAM_ATTR pulseISR()
27+{
28+ unsigned long now = micros();
29+
30+ if (!capturing) return;
31+ if (pulseIndex >= RAW_BUF_MAX) return;
32+
33+ unsigned long duration = now - lastEdgeTime;
34+
35+ if (duration < 50) return;
36+
37+ captureBuffer[pulseIndex++] = duration;
38+ lastEdgeTime = now;
39+}
40+
41+// ===== OOK SETUP =====
42+void setupOOKMode()
43+{
44+ ELECHOUSE_cc1101.SetRx();
45+ ELECHOUSE_cc1101.setMHZ(currentFreq);
46+
47+ ELECHOUSE_cc1101.setModulation(0); // ASK/OOK
48+ ELECHOUSE_cc1101.setDRate(dataRate);
49+ ELECHOUSE_cc1101.setDeviation(0);
50+ ELECHOUSE_cc1101.setRxBW(rxBW);
51+ ELECHOUSE_cc1101.setSyncMode(0);
52+ ELECHOUSE_cc1101.setPA(powerLevel);
53+}
54+
55+// ===== INIT (LAZY, SAFE) =====
56+bool initCC1101()
57+{
58+ if (cc1101Inited)
59+ return true;
60+
61+ Serial.println("Initializing CC1101...");
62+
63+ // IMPORTANT: no detachInterrupt here (causes crash if not installed)
64+
65+ ELECHOUSE_cc1101.setSpiPin(
66+ cc1101_SCK,
67+ cc1101_MISO,
68+ cc1101_MOSI,
69+ CC1101_CS
70+ );
71+
72+ ELECHOUSE_cc1101.setGDO(CC1101_GDO0, CC1101_GDO2);
73+
74+ if (!ELECHOUSE_cc1101.getCC1101())
75+ {
76+ Serial.println("❌ CC1101 NOT FOUND");
77+ return false;
78+ }
79+
80+ delay(10); // let SPI settle
81+
82+ ELECHOUSE_cc1101.Init(); // THIS WAS YOUR FREEZE POINT
83+ setupOOKMode();
84+
85+ pinMode(CC1101_GDO0, INPUT);
86+
87+ Serial.println("✅ CC1101 READY");
88+
89+ cc1101Inited = true;
90+ return true;
91+}
92+
93+// ===== CAPTURE CONTROL =====
94+void startCapture()
95+{
96+ pulseIndex = 0;
97+ capturing = true;
98+ lastEdgeTime = micros();
99+
100+ attachInterrupt(
101+ digitalPinToInterrupt(CC1101_GDO0),
102+ pulseISR,
103+ CHANGE
104+ );
105+
106+ Serial.println("Capture started");
107+}
108+
109+bool isCC1101Ready() {
110+ return cc1101Inited;
111+}
112+
113+void stopCapture()
114+{
115+ capturing = false;
116+
117+ detachInterrupt(digitalPinToInterrupt(CC1101_GDO0));
118+
119+ Serial.println("Capture stopped");
120+}
121+
122+// ===== DEBUG PRINT =====
123+void printCapture()
124+{
125+ Serial.println("Captured pulses:");
126+
127+ for (int i = 0; i < pulseIndex; i++)
128+ {
129+ Serial.println(captureBuffer[i]);
130+ }
131+}
132+
133+
134+// ===== REPLAY =====
135+void replaySignal()
136+{
137+ Serial.println("Replaying...");
138+
139+ ELECHOUSE_cc1101.SetTx();
140+ pinMode(CC1101_GDO0, OUTPUT);
141+
142+ for (int i = 0; i < pulseIndex; i++)
143+ {
144+ digitalWrite(CC1101_GDO0, (i % 2 == 0) ? HIGH : LOW);
145+ delayMicroseconds(captureBuffer[i]);
146+ }
147+
148+ digitalWrite(CC1101_GDO0, LOW);
149+ ELECHOUSE_cc1101.SetRx();
150+}
A firmware/cc1101.h View
@@ -0,0 +1,9 @@
1+#pragma once
2+
3+bool initCC1101();
4+bool isCC1101Ready();
5+
6+void startCapture();
7+void stopCapture();
8+void printCapture();
9+void replaySignal();
A firmware/config.h View
@@ -0,0 +1,48 @@
1+#pragma once
2+
3+// ================= NRF24 =================
4+#define CE1_PIN 10
5+#define CSN1_PIN 11
6+
7+#define CE2_PIN 12
8+#define CSN2_PIN 13
9+
10+#define NRF_SCK 18
11+#define NRF_MISO 16
12+#define NRF_MOSI 17
13+
14+// ================== OLED ===================
15+#define OLED_SDA_PIN 8
16+#define OLED_SCL_PIN 9
17+
18+/////////////////cc1101 vars//////////////
19+// CC1101 via FSPI
20+#define cc1101_SCK 15
21+#define cc1101_MISO 3
22+#define cc1101_MOSI 46
23+
24+//////////////cc1101(1)//////////
25+#define CC1101_CS 45
26+#define CC1101_GDO0 21
27+#define CC1101_GDO2 47
28+
29+/////////////cc1101(2)//////////
30+#define CC1101_2_CS 40
31+#define CC1101_2_GDO0 41
32+#define CC1101_2_GDO2 42
33+
34+// SD Card via HSPI
35+#define SD_SCK 14
36+#define SD_MISO 39
37+#define SD_MOSI 38
38+#define SD_CS 37
39+
40+
41+// =================== Buttons ====================
42+#define BTN_UP 4
43+#define BTN_DOWN 5
44+#define BTN_SELECT 6
45+#define BTN_BACK 7
46+#define BTN_LEFT 1
47+#define BTN_RIGHT 2
48+
A firmware/data/ESP32-BLE-Mouse.zip View

[Binary file]

A firmware/device_check.cpp View
@@ -0,0 +1,242 @@
1+#include <Arduino.h>
2+#include <SPI.h>
3+#include <Wire.h>
4+#include <RF24.h>
5+#include "ELECHOUSE_CC1101_SRC_DRV.h"
6+
7+#include "display.h"
8+#include "buttons.h"
9+#include "config.h"
10+
11+// ===== EXTERNALS =====
12+extern RF24 radio1;
13+extern RF24 radio2;
14+extern SPIClass *RADIO_SPI;
15+extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
16+
17+// ===== RESULTS =====
18+struct DeviceStatus {
19+ bool nrf_link = false;
20+ bool nrf1 = false;
21+ bool nrf2 = false;
22+ bool cc1101 = false;
23+ bool oled = true;
24+ bool buttons = false;
25+};
26+
27+// ===== NRF CHECK =====
28+bool checkNRF(RF24 &radio)
29+{
30+ // safer: only init if needed
31+ if (!radio.isChipConnected()) {
32+ if (!radio.begin(RADIO_SPI))
33+ return false;
34+ }
35+
36+ return radio.isChipConnected();
37+}
38+
39+// ===== CC1101 CHECK =====
40+bool checkCC1101()
41+{
42+ ELECHOUSE_cc1101.setSpiPin(
43+ cc1101_SCK,
44+ cc1101_MISO,
45+ cc1101_MOSI,
46+ CC1101_CS
47+ );
48+
49+ delay(5); // important stabilization
50+
51+ return ELECHOUSE_cc1101.getCC1101();
52+}
53+
54+// ===== BUTTON CHECK =====
55+bool checkButtons()
56+{
57+ u8g2.clearBuffer();
58+ u8g2.setFont(u8g2_font_6x10_tr);
59+ u8g2.drawStr(0, 20, "Press any button...");
60+ u8g2.sendBuffer();
61+
62+ unsigned long start = millis();
63+
64+ while (millis() - start < 2000)
65+ {
66+ if (!digitalRead(BTN_UP) ||
67+ !digitalRead(BTN_DOWN) ||
68+ !digitalRead(BTN_SELECT) ||
69+ !digitalRead(BTN_BACK))
70+ {
71+ return true;
72+ }
73+ }
74+
75+ return false;
76+}
77+
78+// ===== DRAW =====
79+#define MAX_ITEMS 6
80+#define VISIBLE_ROWS 5
81+
82+const char* labels[MAX_ITEMS] = {
83+ "NRF1",
84+ "NRF2",
85+ "LINK",
86+ "CC1101",
87+ "BUTTONS",
88+ "OLED"
89+};
90+
91+bool values[MAX_ITEMS];
92+
93+int selectedIndex = 0;
94+int offset = 0;
95+
96+void drawStatus(DeviceStatus &s)
97+{
98+ values[0] = s.nrf1;
99+ values[1] = s.nrf2;
100+ values[2] = s.nrf_link;
101+ values[3] = s.cc1101;
102+ values[4] = s.buttons;
103+ values[5] = s.oled;
104+
105+ u8g2.clearBuffer();
106+ u8g2.setFont(u8g2_font_6x10_tr);
107+
108+ // scrolling logic
109+ if (selectedIndex < offset)
110+ offset = selectedIndex;
111+
112+ if (selectedIndex >= offset + VISIBLE_ROWS)
113+ offset = selectedIndex - VISIBLE_ROWS + 1;
114+
115+ for (int i = 0; i < VISIBLE_ROWS; i++)
116+ {
117+ int item = offset + i;
118+ if (item >= MAX_ITEMS) break;
119+
120+ int y = 12 + i * 10;
121+
122+ if (item == selectedIndex)
123+ {
124+ u8g2.drawBox(0, y - 9, 128, 10);
125+ u8g2.setDrawColor(0);
126+ }
127+
128+ u8g2.drawStr(2, y, labels[item]);
129+
130+ if (values[item])
131+ u8g2.drawStr(80, y, "OK");
132+ else
133+ u8g2.drawStr(80, y, "FAIL");
134+
135+ if (item == selectedIndex)
136+ u8g2.setDrawColor(1);
137+ }
138+
139+ u8g2.sendBuffer();
140+}
141+
142+bool testNRFLink()
143+{
144+ const byte address[6] = "00001";
145+ uint8_t payload = 0xAB;
146+ uint8_t received = 0;
147+
148+ // --- init radios ---
149+ if (!radio1.begin(RADIO_SPI)) return false;
150+ if (!radio2.begin(RADIO_SPI)) return false;
151+
152+ radio1.setPALevel(RF24_PA_LOW);
153+ radio2.setPALevel(RF24_PA_LOW);
154+
155+ radio1.setDataRate(RF24_1MBPS);
156+ radio2.setDataRate(RF24_1MBPS);
157+
158+ radio1.setChannel(100);
159+ radio2.setChannel(100);
160+
161+ radio1.setAutoAck(false);
162+ radio2.setAutoAck(false);
163+
164+ // --- configure pipes ---
165+ radio1.openWritingPipe(address);
166+ radio2.openReadingPipe(0, address);
167+
168+ radio2.startListening();
169+
170+ delay(50);
171+
172+ // --- send ---
173+ radio1.stopListening();
174+ bool sent = radio1.write(&payload, sizeof(payload));
175+
176+ if (!sent) return false;
177+
178+ // --- receive ---
179+ unsigned long start = millis();
180+
181+ while (millis() - start < 200)
182+ {
183+ if (radio2.available())
184+ {
185+ radio2.read(&received, sizeof(received));
186+ return (received == payload);
187+ }
188+ }
189+
190+ return false;
191+}
192+
193+// ===== MAIN =====
194+void device_check_run()
195+{
196+ DeviceStatus status;
197+
198+ Serial.println("Running device diagnostics...");
199+
200+ // NRF
201+ // NRF link test
202+ status.nrf_link = testNRFLink();
203+ status.nrf1 = checkNRF(radio1);
204+ status.nrf2 = checkNRF(radio2);
205+
206+ // CC1101
207+ status.cc1101 = checkCC1101();
208+
209+ // Buttons
210+ status.buttons = checkButtons();
211+
212+ drawStatus(status);
213+
214+ Serial.println("Diagnostics complete");
215+
216+while (1)
217+{
218+drawStatus(status);
219+
220+if (btnUp())
221+{
222+selectedIndex--;
223+if (selectedIndex < 0) selectedIndex = MAX_ITEMS - 1;
224+delay(150);
225+}
226+
227+if (btnDown())
228+{
229+selectedIndex++;
230+if (selectedIndex >= MAX_ITEMS) selectedIndex = 0;
231+delay(150);
232+}
233+
234+if (btnBack())
235+{
236+delay(150);
237+break;
238+}
239+}}
240+
241+
242+
A firmware/device_check.h View
@@ -0,0 +1,3 @@
1+#pragma once
2+
3+void device_check_run();
A firmware/display.cpp View
@@ -0,0 +1,16 @@
1+#include "display.h"
2+#include <Wire.h>
3+#include "config.h"
4+
5+
6+U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
7+ U8G2_R0,
8+ U8X8_PIN_NONE
9+);
10+
11+void displayInit()
12+{
13+ Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN);
14+ u8g2.begin();
15+ u8g2.setFont(u8g2_font_6x12_tr);
16+}
A firmware/display.h View
@@ -0,0 +1,7 @@
1+#pragma once
2+
3+#include <U8g2lib.h>
4+
5+extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
6+
7+void displayInit();
A firmware/firmware.ino View
@@ -0,0 +1,128 @@
1+#include <Arduino.h>
2+#include <USB.h>
3+#include <USBHIDKeyboard.h>
4+
5+#include <BLEDevice.h>
6+#include <BLEScan.h>
7+
8+#include <RF24.h>
9+#include <nRF24L01.h>
10+
11+#include "ELECHOUSE_CC1101_SRC_DRV.h"
12+
13+#include <WiFi.h>
14+#include <esp_wifi.h>
15+
16+#include <esp_chip_info.h>
17+#include <esp_heap_caps.h>
18+#include <esp_system.h>
19+#include <SPI.h>
20+
21+
22+#include "display.h"
23+#include "buttons.h"
24+#include "menu.h"
25+
26+#include "config.h"
27+#include "cc1101.h"
28+
29+// ================= USB HID =================
30+USBHIDKeyboard Keyboard;
31+
32+
33+RF24 radio1(CE1_PIN, CSN1_PIN);
34+RF24 radio2(CE2_PIN, CSN2_PIN);
35+SPIClass *RADIO_SPI;
36+
37+
38+
39+
40+// ================= BLE SCAN =================
41+BLEScan *pBLEScan;
42+
43+
44+void startBLEScan()
45+{
46+ BLEDevice::init("");
47+
48+ pBLEScan = BLEDevice::getScan();
49+
50+ pBLEScan->setActiveScan(true);
51+
52+ pBLEScan->start(5);
53+
54+ Serial.println("BLE scan complete");
55+}
56+
57+// ================= SYSTEM INFO =================
58+void printSystemUsage()
59+{
60+ esp_chip_info_t chip_info;
61+
62+ esp_chip_info(&chip_info);
63+
64+ Serial.printf("CPU cores: %d\n", chip_info.cores);
65+
66+ Serial.printf(
67+ "Free heap: %d bytes\n",
68+ heap_caps_get_free_size(MALLOC_CAP_DEFAULT)
69+ );
70+
71+ Serial.printf(
72+ "PSRAM free: %d bytes\n",
73+ heap_caps_get_free_size(MALLOC_CAP_SPIRAM)
74+ );
75+}
76+
77+void showSplash()
78+{
79+ u8g2.clearBuffer();
80+
81+ u8g2.setFont(u8g2_font_logisoso20_tr); // big font
82+ u8g2.drawStr(10, 40, "Orion-RF");
83+
84+ u8g2.setFont(u8g2_font_5x8_tr); // small subtitle
85+ u8g2.drawStr(25, 58, "Initializing...");
86+
87+ u8g2.sendBuffer();
88+
89+ delay(1500); // 1.5 sec
90+}
91+
92+
93+// ================= SETUP =================
94+void setup()
95+{
96+ Serial.begin(115200);
97+
98+ displayInit();
99+ showSplash();
100+
101+ buttonsInit();
102+ menuInit();
103+
104+ delay(1500);
105+
106+ USB.begin();
107+ Keyboard.begin();
108+
109+ // NRF SPI safety
110+ pinMode(CSN1_PIN, OUTPUT);
111+ digitalWrite(CSN1_PIN, HIGH);
112+
113+ pinMode(CSN2_PIN, OUTPUT);
114+ digitalWrite(CSN2_PIN, HIGH);
115+
116+ RADIO_SPI = new SPIClass(FSPI);
117+ RADIO_SPI->begin(NRF_SCK, NRF_MISO, NRF_MOSI);
118+
119+ printSystemUsage();
120+
121+ Serial.println("SYSTEM READY");
122+}
123+
124+// ================= LOOP =================
125+void loop()
126+{
127+ menuLoop();
128+}
A firmware/menu.cpp View
@@ -0,0 +1,278 @@
1+#include <Arduino.h>
2+#include "menu.h"
3+#include "display.h"
4+#include "buttons.h"
5+#include "badusb.h"
6+#include "nrf24.h"
7+#include "cc1101.h"
8+#include "blescanner.h"
9+#include "wifi_scan.h"
10+#include "wifi_analyzer.h"
11+#include "device_check.h"
12+
13+// ================= FEATURE HANDLERS =================
14+void runSystemInfoFeature();
15+void runRFCaptureFeature();
16+void runBLEScanFeature();
17+
18+
19+
20+// ================= MENU DATA =================
21+
22+// Root menu
23+const char *mainMenuItems[] = {
24+ "BadUSB",
25+ "RF Capture",
26+ "NRF Jammer",
27+ "BLE Scan",
28+ "Wifi Scan",
29+ "Wifi Analyzer",
30+ "System Info",
31+ "Device Check",
32+ "Restart"
33+};
34+
35+Menu mainMenu = {mainMenuItems, sizeof(mainMenuItems) / sizeof(mainMenuItems[0])};
36+
37+// BadUSB submenu
38+const char *badusbItems[] = {
39+ "Demo",
40+ "Open CMD",
41+ "Rickroll"};
42+
43+Menu badusbMenu = {badusbItems, 3};
44+
45+// ================= MENU STATE =================
46+
47+Menu *currentMenu = &mainMenu;
48+
49+int menuIndex = 0;
50+int menuOffset = 0;
51+
52+#define MENU_VISIBLE_ROWS 4
53+
54+bool insideFeature = false;
55+
56+// ================= DRAW =================
57+
58+void drawMenu()
59+{
60+ u8g2.clearBuffer();
61+
62+ // scroll handling
63+ if (menuIndex < menuOffset)
64+ menuOffset = menuIndex;
65+
66+ if (menuIndex >= menuOffset + MENU_VISIBLE_ROWS)
67+ menuOffset = menuIndex - MENU_VISIBLE_ROWS + 1;
68+
69+ for (int i = 0; i < MENU_VISIBLE_ROWS; i++)
70+ {
71+ int item = menuOffset + i;
72+
73+ if (item >= currentMenu->size)
74+ break;
75+
76+ if (item == menuIndex)
77+ u8g2.drawStr(0, 14 + i * 14, ">");
78+
79+ u8g2.drawStr(10, 14 + i * 14, currentMenu->items[item]);
80+ }
81+
82+ // scroll indicators
83+ if (menuOffset > 0)
84+ u8g2.drawStr(118, 10, "^");
85+
86+ if (menuOffset + MENU_VISIBLE_ROWS < currentMenu->size)
87+ u8g2.drawStr(118, 62, "v");
88+
89+ u8g2.sendBuffer();
90+}
91+
92+// ================= FEATURE EXECUTION =================
93+
94+void launchFeature()
95+{
96+ insideFeature = true;
97+
98+ if (currentMenu == &mainMenu)
99+ {
100+ switch (menuIndex)
101+ {
102+ case 0: // BadUSB → enter submenu
103+ currentMenu = &badusbMenu;
104+ menuIndex = 0;
105+ menuOffset = 0;
106+ break;
107+
108+ case 1:
109+ if (!isCC1101Ready()) {
110+ if (!initCC1101()) {
111+ Serial.println("CC1101 failed");
112+ return;
113+ }
114+ }
115+
116+ Serial.println("Ready to capture...");
117+
118+ startCapture();
119+ delay(5000);
120+ stopCapture();
121+ printCapture();
122+ break;
123+ case 2:
124+ startNRFJammer();
125+ break;
126+
127+ case 3:
128+ ble_scan();
129+ ble_drawMenu();
130+ while (1) {
131+ ble_loop();
132+ if (btnBack())
133+ break;
134+ }
135+ break;
136+
137+ case 4:
138+ {
139+ // Start scan once
140+ wifi_scan_start();
141+ wifi_scan_draw();
142+
143+ while (1) {
144+ wifi_scan_loop();
145+ // EXIT condition handled ONLY here
146+ if (btnBack()) {
147+ delay(150); // debounce
148+ break;
149+ }
150+ }
151+ break;
152+ }
153+ case 5:
154+ {
155+
156+ wifi_analyzer_start();
157+
158+ bool prevBack = false;
159+ while (1)
160+ {
161+ wifi_analyzer_loop();
162+ bool nowBack = btnBack();
163+ if (nowBack && !prevBack)
164+ {
165+ delay(150);
166+ break;
167+ }
168+ prevBack = nowBack;
169+ }
170+ break;
171+ }
172+
173+ case 6:
174+ runSystemInfoFeature();
175+ break;
176+ case 7:
177+ device_check_run();
178+ break;
179+ case 8:
180+ u8g2.clearBuffer();
181+ u8g2.setFont(u8g2_font_6x13_tr);
182+ u8g2.drawStr(30, 30, "Restarting...");
183+ u8g2.sendBuffer();
184+ delay(1000);
185+ ESP.restart();
186+ break;
187+ }
188+ }
189+ else if (currentMenu == &badusbMenu)
190+ {
191+ switch (menuIndex)
192+ {
193+ case 0:
194+ runBadUSBDemo();
195+ break;
196+
197+ case 1:
198+ Serial.println("Open CMD payload");
199+ runBadUSBOpenCMD();
200+ break;
201+
202+ case 2:
203+ Serial.println("Rickroll payload");
204+ runBadUSBRickroll();
205+ break;
206+ }
207+ }
208+
209+ insideFeature = false;
210+
211+ drawMenu();
212+}
213+
214+// ================= INIT =================
215+
216+void menuInit()
217+{
218+ currentMenu = &mainMenu;
219+ menuIndex = 0;
220+ menuOffset = 0;
221+
222+ drawMenu();
223+}
224+
225+// ================= LOOP =================
226+
227+void menuLoop()
228+{
229+ static uint32_t lastPress = 0;
230+
231+ if (insideFeature)
232+ return;
233+
234+ if (millis() - lastPress < 150)
235+ return;
236+
237+ if (btnUp())
238+ {
239+ menuIndex--;
240+
241+ if (menuIndex < 0)
242+ menuIndex = currentMenu->size - 1;
243+
244+ drawMenu();
245+ lastPress = millis();
246+ }
247+
248+ else if (btnDown())
249+ {
250+ menuIndex++;
251+
252+ if (menuIndex >= currentMenu->size)
253+ menuIndex = 0;
254+
255+ drawMenu();
256+ lastPress = millis();
257+ }
258+
259+ else if (btnSelect())
260+ {
261+ launchFeature();
262+ lastPress = millis();
263+ }
264+
265+ else if (btnBack())
266+ {
267+ if (currentMenu != &mainMenu)
268+ {
269+ currentMenu = &mainMenu;
270+ menuIndex = 0;
271+ menuOffset = 0;
272+
273+ drawMenu();
274+ }
275+
276+ lastPress = millis();
277+ }
278+}
A firmware/menu.h View
@@ -0,0 +1,10 @@
1+#pragma once
2+
3+struct Menu
4+{
5+ const char **items;
6+ int size;
7+};
8+
9+void menuInit();
10+void menuLoop();
A firmware/nrf24.cpp View
@@ -0,0 +1,99 @@
1+#include <Arduino.h>
2+#include <RF24.h>
3+#include "buttons.h"
4+#include "nrf24.h"
5+#include "display.h"
6+#define JAM_DURATION 500
7+
8+extern SPIClass *RADIO_SPI;
9+extern RF24 radio1;
10+extern RF24 radio2;
11+
12+void initNRF(RF24 &radio)
13+{
14+ radio.begin(RADIO_SPI);
15+
16+ radio.setAutoAck(false);
17+ radio.stopListening();
18+
19+ radio.setRetries(0, 0);
20+ radio.setDataRate(RF24_2MBPS);
21+radio.setPALevel(RF24_PA_MAX);
22+
23+ radio.openWritingPipe(0xE7E7E7E7E7LL);
24+}
25+
26+
27+void jamChannels(const char* label, int startCh, int endCh) {
28+ byte data1[32], data2[32];
29+ for (int i = 0; i < 32; i++) {
30+ data1[i] = random(0, 256);
31+ data2[i] = random(0, 256);
32+ }
33+
34+ for (int ch = startCh; ch <= endCh; ch++) {
35+ // Status screen
36+ u8g2.clearBuffer();
37+ u8g2.drawStr(0, 10, "Jamming:");
38+ u8g2.setCursor(60, 10);
39+ u8g2.print(label);
40+ u8g2.setCursor(0, 30);
41+ u8g2.print("Channel: ");
42+ u8g2.print(ch);
43+ u8g2.sendBuffer();
44+
45+ unsigned long startTime = millis();
46+ while (millis() - startTime < JAM_DURATION) {
47+ radio1.setChannel(ch);
48+ radio1.stopListening();
49+ radio1.write(data1, sizeof(data1));
50+ delayMicroseconds(100);
51+
52+ radio2.setChannel(ch);
53+ radio2.stopListening();
54+ radio2.write(data2, sizeof(data2));
55+ delayMicroseconds(100);
56+
57+ }
58+}
59+}
60+
61+
62+void nrfJammerSweep()
63+{
64+ static uint8_t ch1 = 0;
65+ static uint8_t ch2 = 124;
66+
67+ uint8_t payload[32] = {0xFF};
68+
69+ radio1.setChannel(ch1);
70+ radio1.writeFast(payload, sizeof(payload));
71+
72+ radio2.setChannel(ch2);
73+ radio2.writeFast(payload, sizeof(payload));
74+
75+ ch1++;
76+ ch2--;
77+
78+ if (ch1 > 124) ch1 = 0;
79+ if (ch2 > 124) ch2 = 124;
80+}
81+
82+void startNRFJammer()
83+{
84+ initNRF(radio1);
85+ initNRF(radio2);
86+
87+ Serial.println("NRF JAMMER STARTED");
88+ // nrfJammerSweep();
89+ jamChannels("Bluetooth", 0, 78);
90+
91+
92+ if (btnBack())
93+ {
94+ Serial.println("Jammer stopped");
95+ return;
96+ }
97+
98+ delayMicroseconds(200);
99+}
A firmware/nrf24.h View
@@ -0,0 +1,14 @@
1+#pragma once
2+
3+#include <RF24.h>
4+
5+// Initialization
6+void initNRF(RF24 &radio);
7+
8+// Jammer modes
9+void startNRFJammer(); // dual-radio sweep jammer
10+void stopNRFJammer(); // (optional, for future)
11+
12+// Advanced (later)
13+void nrfJammerSweep(); // internal, but can expose if needed
14+void nrfSetChannel(uint8_t ch);
A firmware/stubs.cpp View
@@ -0,0 +1,13 @@
1+#include <Arduino.h>
2+
3+
4+void runRFCaptureFeature()
5+{
6+ Serial.println("RF Capture not implemented yet");
7+}
8+
9+
10+void runBLEScanFeature()
11+{
12+ Serial.println("BLE Scan not implemented yet");
13+}
A firmware/sysinfo.cpp View
@@ -0,0 +1,87 @@
1+#include <Arduino.h>
2+#include "display.h"
3+#include "buttons.h"
4+#include <esp_chip_info.h>
5+#include <esp_heap_caps.h>
6+
7+void runSystemInfoFeature()
8+{
9+ esp_chip_info_t chip_info;
10+
11+ esp_chip_info(&chip_info);
12+
13+ while (true)
14+ {
15+ //u8g2.clearBuffer();
16+
17+ //char buf[32];
18+
19+ //sprintf(buf, "Cores: %d", chip_info.cores);
20+ //u8g2.drawStr(0, 14, buf);
21+
22+ //sprintf(buf, "Heap: %d",
23+ // heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
24+ //u8g2.drawStr(0, 28, buf);
25+
26+
27+ //u8g2.drawStr(0, 60, "BACK to exit");
28+
29+ // Get RAM info
30+ size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
31+ size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
32+ int ramUsage = 100 - ((freeHeap * 100) / totalHeap);
33+
34+ // Get Flash info
35+ //uint32_t flashSize = spi_flash_get_chip_size();
36+ uint32_t flashSize = ESP.getFlashChipSize();
37+ uint32_t flashUsed = ESP.getSketchSize();
38+ int flashUsage = (flashUsed * 100) / flashSize;
39+
40+ // Temperature (approx)
41+ uint8_t temperature = temperatureRead();
42+
43+ // Chip info
44+ esp_chip_info_t chip_info;
45+ esp_chip_info(&chip_info);
46+
47+ u8g2.clearBuffer();
48+ u8g2.setFont(u8g2_font_6x12_tr);
49+
50+ char buf[32];
51+
52+ // Box 1 - RAM
53+ u8g2.drawFrame(0, 0, 128, 12);
54+ sprintf(buf, "RAM: %d%% used", ramUsage);
55+ u8g2.drawStr(4, 9, buf);
56+
57+ // Box 2 - Flash
58+ u8g2.drawFrame(0, 12, 128, 12);
59+ sprintf(buf, "Flash: %d%% used", flashUsage);
60+ u8g2.drawStr(4, 21, buf);
61+
62+ // Box 3 - Temp (FULL WIDTH now)
63+ u8g2.drawFrame(0, 24, 128, 12);
64+ sprintf(buf, "Temp: %d C", temperature);
65+ u8g2.drawStr(4, 33, buf);
66+
67+ // Box 4 - Chip info (FULL WIDTH)
68+ u8g2.drawFrame(0, 36, 128, 12);
69+ sprintf(buf, "Cores: %d Rev: %d", chip_info.cores, chip_info.revision);
70+ u8g2.drawStr(4, 45, buf);
71+
72+ // Box 5 - PSRAM (KB)
73+ u8g2.drawFrame(0, 48, 128, 12);
74+ sprintf(buf, "PSRAM: %lu KB", heap_caps_get_free_size(MALLOC_CAP_SPIRAM) / 1024);
75+ u8g2.drawStr(4, 57, buf);
76+
77+ u8g2.sendBuffer();
78+
79+ if (btnBack())
80+ {
81+ delay(200);
82+ return;
83+ }
84+
85+ delay(100);
86+ }
87+}
A firmware/sysinfo.h View
@@ -0,0 +1,3 @@
1+#pragma once
2+
3+void runSystemInfoFeature();
A firmware/wifi_analyzer.cpp View
@@ -0,0 +1,147 @@
1+#include <Arduino.h>
2+#include <WiFi.h>
3+#include <esp_wifi.h>
4+
5+#include "display.h"
6+#include "buttons.h"
7+
8+// ===== CONFIG =====
9+#define GRAPH_WIDTH 128
10+#define GRAPH_HEIGHT 44
11+#define GRAPH_TOP 10
12+#define MAX_POINTS 128
13+#define SPIKE_THRESHOLD 30
14+
15+// ===== STATE =====
16+struct SnifferGraph {
17+ uint8_t graphData[MAX_POINTS];
18+ uint8_t currentChannel = 1;
19+ volatile uint16_t packetCounter = 0;
20+ unsigned long lastChannelSwitch = 0;
21+ unsigned long lastUpdate = 0;
22+};
23+
24+static SnifferGraph sniffer;
25+
26+// ===== CALLBACK =====
27+void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type)
28+{
29+ if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL)
30+ {
31+ sniffer.packetCounter++;
32+ }
33+}
34+
35+// ===== INIT =====
36+void wifi_analyzer_start()
37+{
38+ // display init (safe to call again)
39+ u8g2.clearBuffer();
40+ u8g2.setFont(u8g2_font_5x8_tr);
41+ u8g2.drawStr(0, 10, "Starting analyzer...");
42+ u8g2.sendBuffer();
43+
44+ // reset graph
45+ memset(sniffer.graphData, 0, sizeof(sniffer.graphData));
46+ sniffer.packetCounter = 0;
47+ sniffer.currentChannel = 1;
48+
49+ // reset WiFi
50+ WiFi.disconnect(true, true);
51+ esp_wifi_stop();
52+ delay(200);
53+ esp_wifi_deinit();
54+
55+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
56+ esp_wifi_init(&cfg);
57+ esp_wifi_set_storage(WIFI_STORAGE_RAM);
58+ esp_wifi_set_mode(WIFI_MODE_NULL);
59+ esp_wifi_start();
60+
61+ esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
62+ esp_wifi_set_promiscuous_rx_cb(snifferCallback);
63+ esp_wifi_set_promiscuous(true);
64+}
65+
66+// ===== HELPERS =====
67+static void switchChannel()
68+{
69+ sniffer.currentChannel++;
70+ if (sniffer.currentChannel > 13) sniffer.currentChannel = 1;
71+
72+ esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
73+}
74+
75+static void updateGraph(uint8_t value)
76+{
77+ for (int i = 0; i < MAX_POINTS - 1; i++)
78+ {
79+ sniffer.graphData[i] = sniffer.graphData[i + 1];
80+ }
81+
82+ sniffer.graphData[MAX_POINTS - 1] = value;
83+}
84+
85+static void drawGraph(uint16_t pktCount)
86+{
87+ u8g2.clearBuffer();
88+ u8g2.setFont(u8g2_font_5x8_tr);
89+
90+ char line1[16];
91+ char line2[16];
92+
93+ sprintf(line1, "Ch:%d", sniffer.currentChannel);
94+ sprintf(line2, "Pkts:%d", pktCount * 5);
95+
96+ u8g2.drawStr(0, 8, line1);
97+ u8g2.drawStr(60, 8, line2);
98+
99+ for (int x = 1; x < GRAPH_WIDTH; x++)
100+ {
101+ int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1];
102+ int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x];
103+
104+ u8g2.drawLine(x - 1, y1, x, y2);
105+ }
106+
107+ if (pktCount >= SPIKE_THRESHOLD)
108+ {
109+ u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT);
110+ }
111+
112+ u8g2.sendBuffer();
113+}
114+
115+// ===== LOOP =====
116+void wifi_analyzer_loop()
117+{
118+ static uint32_t lastPress = 0;
119+ unsigned long now = millis();
120+
121+ // channel hopping
122+ if (now - sniffer.lastChannelSwitch >= 1000)
123+ {
124+ sniffer.lastChannelSwitch = now;
125+ switchChannel();
126+ }
127+
128+ // graph update
129+ if (now - sniffer.lastUpdate >= 200)
130+ {
131+ sniffer.lastUpdate = now;
132+
133+ uint16_t pktCount = sniffer.packetCounter;
134+
135+ uint8_t scaled = pktCount * 2;
136+ uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT);
137+
138+ updateGraph(value);
139+ drawGraph(pktCount);
140+
141+ sniffer.packetCounter = 0;
142+ }
143+
144+ // optional: small debounce to not hammer CPU
145+ if (millis() - lastPress < 10)
146+ return;
147+}
A firmware/wifi_analyzer.h View
@@ -0,0 +1,4 @@
1+#pragma once
2+
3+void wifi_analyzer_start();
4+void wifi_analyzer_loop();
A firmware/wifi_scan.cpp View
@@ -0,0 +1,152 @@
1+#include <Arduino.h>
2+#include <WiFi.h>
3+#include "display.h"
4+#include "buttons.h"
5+
6+#define MAX_NETWORKS 30
7+
8+struct WiFiNet {
9+ String ssid;
10+ int rssi;
11+ int channel;
12+ bool encrypted;
13+};
14+
15+static WiFiNet networks[MAX_NETWORKS];
16+static int networkCount = 0;
17+static int selectedIndex = 0;
18+
19+// ===== SCAN =====
20+void wifi_scan_start()
21+{
22+ u8g2.clearBuffer();
23+ u8g2.drawStr(10, 30, "Scanning WiFi...");
24+ u8g2.sendBuffer();
25+
26+ WiFi.mode(WIFI_STA);
27+ WiFi.disconnect();
28+
29+ delay(100);
30+
31+ int n = WiFi.scanNetworks();
32+
33+ networkCount = min(n, MAX_NETWORKS);
34+
35+ for (int i = 0; i < networkCount; i++)
36+ {
37+ networks[i].ssid = WiFi.SSID(i);
38+ networks[i].rssi = WiFi.RSSI(i);
39+ networks[i].channel = WiFi.channel(i);
40+ networks[i].encrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
41+ }
42+
43+ selectedIndex = 0;
44+}
45+
46+// ===== DRAW =====
47+void wifi_scan_draw()
48+{
49+ u8g2.clearBuffer();
50+
51+ if (networkCount == 0)
52+ {
53+ u8g2.drawStr(0, 30, "No networks");
54+ u8g2.drawStr(0, 45, "Press BACK");
55+ }
56+ else
57+ {
58+ char counter[20];
59+ sprintf(counter, "%d/%d", selectedIndex + 1, networkCount);
60+ u8g2.setFont(u8g2_font_5x8_tr);
61+ u8g2.drawStr(0, 8, counter);
62+
63+ u8g2.setFont(u8g2_font_6x10_tr);
64+
65+ for (int i = 0; i < 3; i++)
66+ {
67+ int idx = selectedIndex + i;
68+ if (idx >= networkCount) break;
69+
70+ int y = 22 + i * 14;
71+
72+ if (i == 0)
73+ {
74+ u8g2.drawBox(0, y - 10, 128, 12);
75+ u8g2.setDrawColor(0);
76+ }
77+
78+ String text = networks[idx].ssid;
79+ if (text.length() > 10)
80+ text = text.substring(0, 10) + "..";
81+
82+ text += " (" + String(networks[idx].rssi) + ")";
83+
84+ u8g2.drawStr(2, y, text.c_str());
85+
86+ if (i == 0)
87+ u8g2.setDrawColor(1);
88+ }
89+ }
90+
91+ u8g2.sendBuffer();
92+}
93+
94+// ===== DETAILS =====
95+void wifi_drawDetails()
96+{
97+ if (networkCount == 0) return;
98+
99+ WiFiNet &net = networks[selectedIndex];
100+
101+ u8g2.clearBuffer();
102+ u8g2.setFont(u8g2_font_5x8_tr);
103+
104+ u8g2.drawStr(0, 10, net.ssid.c_str());
105+
106+ char rssi[20];
107+ sprintf(rssi, "RSSI: %d", net.rssi);
108+ u8g2.drawStr(0, 20, rssi);
109+
110+ char ch[20];
111+ sprintf(ch, "CH: %d", net.channel);
112+ u8g2.drawStr(0, 30, ch);
113+
114+ u8g2.drawStr(0, 40, net.encrypted ? "Secured" : "Open");
115+
116+ u8g2.sendBuffer();
117+}
118+
119+// ===== LOOP =====
120+void wifi_scan_loop()
121+{
122+ static uint32_t lastPress = 0;
123+
124+ if (millis() - lastPress < 150)
125+ return;
126+
127+ if (btnDown() && selectedIndex < networkCount - 1)
128+ {
129+ selectedIndex++;
130+ wifi_scan_draw();
131+ lastPress = millis();
132+ }
133+ else if (btnUp() && selectedIndex > 0)
134+ {
135+ selectedIndex--;
136+ wifi_scan_draw();
137+ lastPress = millis();
138+ }
139+ else if (btnSelect() && networkCount > 0)
140+ {
141+ wifi_drawDetails();
142+ delay(3000);
143+ wifi_scan_draw();
144+ lastPress = millis();
145+ }
146+// else if (btnBack())
147+// {
148+// wifi_scan_start();
149+// wifi_scan_draw();
150+// lastPress = millis();
151+// }
152+}
A firmware/wifi_scan.h View
@@ -0,0 +1,5 @@
1+#pragma once
2+
3+void wifi_scan_start();
4+void wifi_scan_loop();
5+void wifi_scan_draw();