Krolyxon
Commit ed0847b

Branches

Tags

Refs →

orion-rfsrcrfcc1101.cpp

357 lines · 7.6 KB · C++

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