-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRadioModule.cpp
More file actions
98 lines (77 loc) · 2.63 KB
/
Copy pathRadioModule.cpp
File metadata and controls
98 lines (77 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "RadioModule.h"
// NRF24 Pins
#define NRF_CE 4
#define NRF_CSN 5
#define FAILSAFE_TIMEOUT_MS 5000
RF24 radio(NRF_CE, NRF_CSN);
const byte rxAddress[6] = "CTRL1";
const byte txAddress[6] = "CTRL2";
// Local state pointers - made static to prevent linker conflicts
static FlightState* localState;
static SemaphoreHandle_t localMutex;
unsigned long lastPacketTime = 0;
unsigned long lastTelemetrySent = 0;
ControlPacket rxPkt;
void setupRadio(FlightState* statePtr, SemaphoreHandle_t mutexHandle) {
localState = statePtr;
localMutex = mutexHandle;
// Initialize standard VSPI for NRF24
SPI.begin(18, 19, 23, NRF_CSN);
if (!radio.begin()) {
Serial.println("NRF24 NOT FOUND! Halting radio setup.");
return;
}
radio.setChannel(100);
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS);
radio.setAutoAck(false);
radio.disableCRC();
radio.enableDynamicPayloads();
radio.openReadingPipe(1, rxAddress);
radio.openWritingPipe(txAddress);
radio.startListening();
lastPacketTime = millis();
Serial.println("NRF24 Initialized on Core 0");
}
// This function loops forever on Core 0
void radioTask(void *pvParameters) {
while (true) {
bool packetReceived = false;
// 1. Check for incoming control packets
while (radio.available()) {
uint8_t len = radio.getDynamicPayloadSize();
if (len == sizeof(ControlPacket)) {
radio.read(&rxPkt, sizeof(rxPkt));
lastPacketTime = millis();
packetReceived = true;
} else {
radio.flush_rx();
}
}
// 2. Safely transfer received data to Shared State & Grab Telemetry
if (xSemaphoreTake(localMutex, pdMS_TO_TICKS(5)) == pdTRUE) {
// Update Failsafe flag based on timeout
if (millis() - lastPacketTime >= FAILSAFE_TIMEOUT_MS) {
localState->failsafeActive = true;
} else {
localState->failsafeActive = false;
// If we got a packet, update the shared controls
if (packetReceived) {
localState->control = rxPkt;
}
}
// Read telemetry to send back (copy locally to minimize mutex lock time)
TelemetryPacket txPkt = localState->telemetry;
xSemaphoreGive(localMutex); // Unlock Mutex
// 3. Send Telemetry if needed (e.g., every 500ms or after RX)
if (packetReceived && (millis() - lastTelemetrySent >= 500)) {
radio.stopListening();
radio.write(&txPkt, sizeof(txPkt));
radio.startListening();
lastTelemetrySent = millis();
}
}
// Yield to the RTOS scheduler (crucial to prevent watchdog resets on Core 0)
vTaskDelay(pdMS_TO_TICKS(5));
}
}