Krolyxon
Commit 3672abc

Branches

Tags

Refs →

orion-rfsrcrfcc1101.cpp

408 lines · 7.9 KB · C++

1#include <Arduino.h>
2#include "../libs/ELECHOUSE_CC1101_SRC_DRV.h"
3#include "cc1101.h"
4#include "../config.h"
5#include "SPI.h"
6#include "../ui/display.h"
7#include "../utils/buttons.h"
8
9// ===== CONFIG =====
10#define RAW_BUF_MAX 512
11
12// ===== STATE =====
13static bool cc1101Inited = false;
14
15// ===== CAPTURE STATE =====
16volatile unsigned long captureBuffer[RAW_BUF_MAX];
17volatile int pulseIndex = 0;
18volatile unsigned long lastEdgeTime = 0;
19volatile bool capturing = false;
20
21// ===== RF SETTINGS =====
22float currentFreq = 433.92;
23float dataRate = 3.79372;
24float deviation = 0.0;
25float rxBW = 325.0;
26int powerLevel = 10;
27
28// ===== ISR =====
29void IRAM_ATTR pulseISR()
30{
31 unsigned long now = micros();
32
33 if (!capturing) return;
34 if (pulseIndex >= RAW_BUF_MAX) return;
35
36 unsigned long duration = now - lastEdgeTime;
37
38 if (duration < 150) return;
39
40 captureBuffer[pulseIndex++] = duration;
41 lastEdgeTime = now;
42}
43
44// ===== OOK SETUP =====
45void setupOOKMode()
46{
47 ELECHOUSE_cc1101.SetRx();
48 ELECHOUSE_cc1101.setMHZ(currentFreq);
49
50 ELECHOUSE_cc1101.setModulation(2); // ASK/OOK
51 ELECHOUSE_cc1101.setDRate(dataRate);
52 ELECHOUSE_cc1101.setDeviation(0);
53 ELECHOUSE_cc1101.setRxBW(rxBW);
54 ELECHOUSE_cc1101.setSyncMode(0);
55 ELECHOUSE_cc1101.setPA(powerLevel);
56}
57
58// ===== INIT (LAZY, SAFE) =====
59// ================= CC1101 INIT =================
60bool initCC1101()
61{
62 Serial.println();
63 Serial.println("===== CC1101 INIT =====");
64
65 // ===== SPI =====
66 SPI.begin(
67 cc1101_SCK,
68 cc1101_MISO,
69 cc1101_MOSI,
70 CC1101_CS
71 );
72
73 pinMode(CC1101_CS, OUTPUT);
74 digitalWrite(CC1101_CS, HIGH);
75
76 delay(100);
77
78 // ===== GDO =====
79 ELECHOUSE_cc1101.setGDO(
80 CC1101_GDO0,
81 -1
82 );
83
84 ELECHOUSE_cc1101.setSpiPin(
85 cc1101_SCK,
86 cc1101_MISO,
87 cc1101_MOSI,
88 CC1101_CS
89 );
90
91 // ===== DETECT =====
92 Serial.println("Checking chip...");
93
94 if (!ELECHOUSE_cc1101.getCC1101())
95 {
96 Serial.println("❌ CC1101 NOT FOUND");
97 return false;
98 }
99
100 Serial.println("✅ CC1101 FOUND");
101
102 // ===== IMPORTANT =====
103 // DO NOT CALL Init()
104 // it freezes on some ESP32-S3 setups
105
106 // ===== MANUAL CONFIG =====
107 ELECHOUSE_cc1101.setMHZ(currentFreq);
108
109 // 2 = ASK/OOK
110 ELECHOUSE_cc1101.setModulation(2);
111
112 ELECHOUSE_cc1101.setDRate(dataRate);
113
114 ELECHOUSE_cc1101.setRxBW(rxBW);
115
116 ELECHOUSE_cc1101.setDeviation(0);
117
118 // disable sync requirement
119 ELECHOUSE_cc1101.setSyncMode(0);
120
121 ELECHOUSE_cc1101.setPA(powerLevel);
122
123 // async serial mode
124 ELECHOUSE_cc1101.setCCMode(0);
125
126 // enter RX
127 ELECHOUSE_cc1101.SetRx();
128
129 pinMode(CC1101_GDO0, INPUT);
130
131 Serial.println("✅ RX MODE READY");
132
133 cc1101Inited = true;
134 return true;
135}
136// ===== CAPTURE CONTROL =====
137void startCapture()
138{
139 pulseIndex = 0;
140 capturing = true;
141 lastEdgeTime = micros();
142
143 attachInterrupt(
144 digitalPinToInterrupt(CC1101_GDO0),
145 pulseISR,
146 CHANGE
147 );
148
149 Serial.println("Looking for RF... ");
150}
151
152bool isCC1101Ready() {
153 return cc1101Inited;
154}
155
156void stopCapture()
157{
158 capturing = false;
159
160 detachInterrupt(digitalPinToInterrupt(CC1101_GDO0));
161
162 Serial.println("Capture stopped");
163}
164
165// ===== DEBUG PRINT =====
166void printCapture()
167{
168 Serial.println("Captured pulses:");
169
170 for (int i = 0; i < pulseIndex; i++)
171 {
172 Serial.println(captureBuffer[i]);
173 }
174}
175
176
177// ================= REPLAY =================
178void replaySignal()
179{
180 Serial.println();
181 Serial.println("Replaying signal...");
182
183 stopCapture();
184
185 ELECHOUSE_cc1101.SetTx();
186
187 pinMode(CC1101_GDO0, OUTPUT);
188
189 for (int i = 0; i < pulseIndex; i++)
190 {
191 digitalWrite(
192 CC1101_GDO0,
193 (i % 2 == 0) ? HIGH : LOW
194 );
195
196 delayMicroseconds(captureBuffer[i]);
197 }
198
199 digitalWrite(CC1101_GDO0, LOW);
200
201 ELECHOUSE_cc1101.SetRx();
202
203 pinMode(CC1101_GDO0, INPUT);
204
205 Serial.println("Replay complete");
206}
207
208
209void captureAndDisplay()
210{
211 if (!cc1101Inited)
212 {
213 if (!initCC1101())
214 {
215 u8g2.clearBuffer();
216 u8g2.setFont(u8g2_font_6x10_tr);
217 u8g2.drawStr(0, 20, "CC1101 Failed");
218 u8g2.sendBuffer();
219 return;
220 }
221 }
222
223 startCapture();
224
225 u8g2.clearBuffer();
226 u8g2.setFont(u8g2_font_6x10_tr);
227 u8g2.drawStr(0, 12, "CC1101 Capture");
228 u8g2.drawStr(0, 28, "Waiting RF...");
229 u8g2.drawStr(0, 60, "BACK = Exit");
230 u8g2.sendBuffer();
231
232 unsigned long lastSignal = millis();
233 int lastPulseCount = 0;
234
235 while (true)
236 {
237 // signal detected
238 if (pulseIndex > lastPulseCount)
239 {
240 lastPulseCount = pulseIndex;
241 lastSignal = millis();
242 }
243
244 // update OLED
245 u8g2.clearBuffer();
246 u8g2.setFont(u8g2_font_6x10_tr);
247
248 u8g2.drawStr(0, 12, "CC1101 Capture");
249
250 u8g2.setCursor(0, 28);
251 u8g2.print("Pulses: ");
252 u8g2.print(pulseIndex);
253
254 u8g2.setCursor(0, 42);
255 u8g2.print("Freq: ");
256 u8g2.print(currentFreq);
257 u8g2.print(" MHz");
258
259 if (pulseIndex > 0)
260 {
261 u8g2.drawStr(0, 54, "Signal Detected");
262 }
263 else
264 {
265 u8g2.drawStr(0, 54, "Waiting...");
266 }
267
268 u8g2.sendBuffer();
269
270 // auto print once capture stabilizes
271 if (pulseIndex > 20 && (millis() - lastSignal > 1500))
272 {
273 stopCapture();
274
275 Serial.println();
276 Serial.println("===== RF CAPTURE =====");
277
278 for (int i = 0; i < pulseIndex; i++)
279 {
280 Serial.print(captureBuffer[i]);
281 Serial.print(", ");
282 }
283
284 Serial.println();
285
286 u8g2.clearBuffer();
287 u8g2.setFont(u8g2_font_6x10_tr);
288 u8g2.drawStr(0, 15, "Capture Complete");
289
290 u8g2.setCursor(0, 35);
291}
292}
293}
294
295void handleMenu()
296{
297 if (!isCC1101Ready())
298 {
299 if (!initCC1101())
300 {
301 u8g2.clearBuffer();
302 u8g2.setFont(u8g2_font_6x10_tr);
303 u8g2.drawStr(0, 20, "CC1101 Failed");
304 u8g2.sendBuffer();
305 delay(1500);
306 return;
307 }
308 }
309
310 pulseIndex = 0;
311
312 startCapture();
313
314 // ===== CAPTURE FOR 5 SEC =====
315 unsigned long start = millis();
316
317 while (millis() - start < 5000)
318 {
319 noInterrupts();
320 int count = pulseIndex;
321 interrupts();
322
323 u8g2.clearBuffer();
324 u8g2.setFont(u8g2_font_6x10_tr);
325
326 u8g2.drawStr(0, 12, "RF Capturing...");
327
328 u8g2.setCursor(0, 30);
329 u8g2.print("Pulses: ");
330 u8g2.print(count);
331
332 u8g2.sendBuffer();
333
334 delay(50);
335 }
336
337 stopCapture();
338
339 // ===== DISPLAY CAPTURE BUFFER =====
340 int scroll = 0;
341
342 while (1)
343 {
344 noInterrupts();
345 int count = pulseIndex;
346 interrupts();
347
348 u8g2.clearBuffer();
349 u8g2.setFont(u8g2_font_5x8_tr);
350
351 u8g2.drawStr(0, 8, "Captured Buffer");
352
353 // display 6 lines
354 for (int i = 0; i < 6; i++)
355 {
356 int idx = scroll + i;
357
358 if (idx >= count)
359 break;
360
361 noInterrupts();
362 unsigned long val = captureBuffer[idx];
363 interrupts();
364
365 char buf[32];
366
367 snprintf(buf, sizeof(buf), "%03d: %lu", idx, val);
368
369 u8g2.drawStr(0, 20 + (i * 8), buf);
370 }
371
372 u8g2.sendBuffer();
373
374 // scroll down
375 if (btnDown())
376 {
377 if (scroll < count - 1)
378 scroll++;
379
380 delay(120);
381 }
382
383 // scroll up
384 if (btnUp())
385 {
386 if (scroll > 0)
387 scroll--;
388
389 delay(120);
390 }
391
392 // replay
393 if (btnSelect())
394 {
395 replaySignal();
396 delay(300);
397 }
398
399 // exit
400 if (btnBack())
401 {
402 delay(150);
403 return;
404 }
405
406 delay(20);
407 }
408}