STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1#include <Ethernet.h>
2#include <EthernetUdp.h>
3#include <SPI.h>
4#include <daq-protocol.h>
5
6#include <cstring>
7
8#define ETH_CLK_PIN 39
9#define ETH_MISO_PIN 41
10#define ETH_MOSI_PIN 40
11#define ETH_CS_PIN 38
12
13IPAddress staticIP(192, 168, 2, 101);
14IPAddress gateway(192, 168, 2, 1);
15IPAddress subnet(255, 255, 255, 0);
16IPAddress dns(192, 168, 2, 1);
17
18unsigned int localPort = 5006; // Port to listen on
19uint8_t packetBuffer[MAX_PACKET_SIZE]; // Buffer to hold incoming packets
20
21EthernetUDP udp;
22
23byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE};
24
25// ============================================================================
26// INITIALIZATION
27// ============================================================================
28
29void setup() {
30 Serial.begin(115200);
31 Serial.println("Ethernet Test Receive Packet Suite");
32 Serial.println("===================================");
33
34 // Start SPI with custom pins
36 delay(1000);
37
38 // Initialize Ethernet with CS pin
39 Ethernet.init(ETH_CS_PIN);
40 delay(1000);
41
42 // Start Ethernet with static IP
44 delay(1000);
45
46 // Start UDP
47 udp.begin(localPort);
48
49 // Print board information at initialization
50 Serial.println("\nInitial Board Configuration:");
52 Serial.println("\nListening for UDP packets...\n");
53}
54
55// ============================================================================
56// BOARD INFORMATION
57// ============================================================================
58
59/**
60 * @brief Prints all board networking information to Serial
61 */
63 Serial.println("--- Board Network Information ---");
64
65 // IP Configuration
66 Serial.print("Static IP: ");
67 Serial.println(Ethernet.localIP());
68 Serial.print("Gateway: ");
69 Serial.println(gateway);
70 Serial.print("Subnet Mask: ");
71 Serial.println(subnet);
72 Serial.print("DNS Server: ");
73 Serial.println(dns);
74
75 // MAC Address
76 Serial.print("MAC Address: ");
77 for (int i = 0; i < 6; i++) {
78 if (i > 0)
79 Serial.print(":");
80 if (mac[i] < 0x10)
81 Serial.print("0");
82 Serial.print(mac[i], HEX);
83 }
84 Serial.println();
85
86 // UDP Configuration
87 Serial.print("UDP Local Port: ");
88 Serial.println(localPort);
89
90 // Ethernet Link Status
91 Serial.print("Ethernet Link Status: ");
92 if (Ethernet.linkStatus() == LinkON) {
93 Serial.println("Connected");
94 } else if (Ethernet.linkStatus() == LinkOFF) {
95 Serial.println("Disconnected");
96 } else {
97 Serial.println("Unknown");
98 }
99
100 Serial.println("--------------------------------");
101}
102
103// ============================================================================
104// PACKET DECODING AND PRINTING
105// ============================================================================
106
107/**
108 * @brief Prints raw packet data in hex format for debugging
109 */
110void printRawPacketData(const uint8_t* buffer, size_t size) {
111 Serial.println("Raw packet data (hex):");
112 for (size_t i = 0; i < size; i++) {
113 if (buffer[i] < 0x10)
114 Serial.print("0");
115 Serial.print(buffer[i], HEX);
116 Serial.print(" ");
117 if ((i + 1) % 16 == 0)
118 Serial.println();
119 }
120 if (size % 16 != 0)
121 Serial.println();
122}
123
124/**
125 * @brief Prints packet header information
126 */
127void printPacketHeader(const daq::PacketHeader& header) {
128 Serial.println("--- Packet Header ---");
129 Serial.print("Packet Type: ");
130 Serial.print(static_cast<int>(header.packet_type));
131 Serial.print(" (");
132
133 // Print type name
134 switch (header.packet_type) {
136 Serial.print("BOARD_HEARTBEAT");
137 break;
139 Serial.print("SERVER_HEARTBEAT");
140 break;
142 Serial.print("SENSOR_DATA");
143 break;
145 Serial.print("ACTUATOR_COMMAND");
146 break;
148 Serial.print("SENSOR_CONFIG");
149 break;
151 Serial.print("ACTUATOR_CONFIG");
152 break;
154 Serial.print("ABORT");
155 break;
157 Serial.print("ABORT_DONE");
158 break;
160 Serial.print("CLEAR_ABORT");
161 break;
162 default:
163 Serial.print("UNKNOWN");
164 break;
165 }
166 Serial.println(")");
167 Serial.print("Version: ");
168 Serial.println(header.version);
169 Serial.print("Timestamp: ");
170 Serial.println(header.timestamp);
171 Serial.println("---------------------");
172}
173
174/**
175 * @brief Prints Board Heartbeat packet information
176 */
177void printBoardHeartbeat(const daq::PacketHeader& header,
178 const daq::BoardHeartbeatPacket& data) {
179 Serial.println("=== Board Heartbeat Packet ===");
180 printPacketHeader(header);
181
182 Serial.println("--- Packet Data ---");
183 Serial.println(
184 "(Board role is implied by board_id / deployment; no board_type "
185 "field.)");
186 Serial.print("Board ID: ");
187 Serial.println(data.board_id);
188
189 Serial.print("Engine State: ");
190 Serial.print(static_cast<int>(data.engine_state));
191 Serial.print(" (");
192 switch (data.engine_state) {
194 Serial.print("SAFE");
195 break;
197 Serial.print("PRESSURIZING");
198 break;
200 Serial.print("LOX_FILL");
201 break;
203 Serial.print("FIRING");
204 break;
206 Serial.print("POST_FIRE");
207 break;
208 default:
209 Serial.print("UNKNOWN");
210 break;
211 }
212 Serial.println(")");
213
214 Serial.print("Board State: ");
215 Serial.print(static_cast<int>(data.board_state));
216 Serial.print(" (");
217 switch (data.board_state) {
219 Serial.print("SETUP");
220 break;
222 Serial.print("ACTIVE");
223 break;
225 Serial.print("CONNECTION_LOSS_DETECTED");
226 break;
228 Serial.print("NO_CONNECTION_ABORT");
229 break;
231 Serial.print("NO_CONN_ABORT_FOLLOWER");
232 break;
234 Serial.print("PT_ABORT");
235 break;
237 Serial.print("NO_PT_ABORT");
238 break;
240 Serial.print("ABORT_FINISHED");
241 break;
243 Serial.print("STANDALONE_ABORT");
244 break;
246 Serial.print("SELF_TEST");
247 break;
248 default:
249 Serial.print("UNKNOWN");
250 break;
251 }
252 Serial.println(")");
253 Serial.println("==============================");
254}
255
256/**
257 * @brief Prints Server Heartbeat packet information
258 */
259void printServerHeartbeat(const daq::PacketHeader& header,
260 const daq::ServerHeartbeatPacket& data) {
261 Serial.println("=== Server Heartbeat Packet ===");
262 printPacketHeader(header);
263
264 Serial.println("--- Packet Data ---");
265 Serial.print("Engine State: ");
266 Serial.print(static_cast<int>(data.engine_state));
267 Serial.print(" (");
268 switch (data.engine_state) {
270 Serial.print("SAFE");
271 break;
273 Serial.print("PRESSURIZING");
274 break;
276 Serial.print("LOX_FILL");
277 break;
279 Serial.print("FIRING");
280 break;
282 Serial.print("POST_FIRE");
283 break;
284 default:
285 Serial.print("UNKNOWN");
286 break;
287 }
288 Serial.println(")");
289 Serial.println("===============================");
290}
291
292/**
293 * @brief Attempts to decode and print packet information
294 * @param buffer The packet buffer
295 * @param size The size of the packet
296 */
297void decodeAndPrintPacket(const uint8_t* buffer, size_t size) {
298 if (!buffer || size == 0) {
299 Serial.println("Error: Invalid buffer or size");
300 return;
301 }
302
303 // Check minimum size for header
304 const size_t min_header_size = sizeof(daq::PacketHeader);
305 if (size < min_header_size) {
306 Serial.println("Error: Packet too small to contain header");
307 Serial.print("Received size: ");
308 Serial.print(size);
309 Serial.print(" bytes, minimum required: ");
310 Serial.print(min_header_size);
311 Serial.println(" bytes");
312 printRawPacketData(buffer, size);
313 return;
314 }
315
316 // Try to read the header first
317 daq::PacketHeader header;
318 memcpy(&header, buffer, min_header_size);
319
320 // Validate header
321 Serial.println("\n--- Attempting to decode packet ---");
322 printPacketHeader(header);
323
324 // Try to decode based on packet type
325 bool decoded = false;
326
327 switch (header.packet_type) {
329 daq::BoardHeartbeatPacket heartbeatData;
330 if (daq::parse_board_heartbeat_packet(buffer, size, header,
331 heartbeatData)) {
332 printBoardHeartbeat(header, heartbeatData);
333 decoded = true;
334 } else {
335 Serial.println("Error: Failed to parse Board Heartbeat packet");
336 Serial.print("Expected size: ");
337 Serial.print(sizeof(daq::PacketHeader) +
338 sizeof(daq::BoardHeartbeatPacket));
339 Serial.print(" bytes, received: ");
340 Serial.print(size);
341 Serial.println(" bytes");
342 }
343 break;
344 }
345
347 daq::ServerHeartbeatPacket heartbeatData;
348 if (daq::parse_server_heartbeat_packet(buffer, size, header,
349 heartbeatData)) {
350 printServerHeartbeat(header, heartbeatData);
351 decoded = true;
352 } else {
353 Serial.println(
354 "Error: Failed to parse Server Heartbeat packet");
355 Serial.print("Expected size: ");
356 Serial.print(sizeof(daq::PacketHeader) +
357 sizeof(daq::ServerHeartbeatPacket));
358 Serial.print(" bytes, received: ");
359 Serial.print(size);
360 Serial.println(" bytes");
361 }
362 break;
363 }
364
366 Serial.println(
367 "Packet type: SENSOR_DATA (not yet implemented for full "
368 "decoding)");
369 Serial.print("Packet size: ");
370 Serial.print(size);
371 Serial.println(" bytes");
372 // TODO: Add full sensor data parsing when needed
373 decoded = true; // At least we identified the type
374 break;
375
377 Serial.println(
378 "Packet type: ACTUATOR_COMMAND (not yet implemented for "
379 "full decoding)");
380 Serial.print("Packet size: ");
381 Serial.print(size);
382 Serial.println(" bytes");
383 // TODO: Add full actuator command parsing when needed
384 decoded = true; // At least we identified the type
385 break;
386
388 Serial.println(
389 "Packet type: SENSOR_CONFIG (not yet implemented for full "
390 "decoding)");
391 Serial.print("Packet size: ");
392 Serial.print(size);
393 Serial.println(" bytes");
394 // TODO: Add full sensor config parsing when needed
395 decoded = true; // At least we identified the type
396 break;
397
399 Serial.println(
400 "Packet type: ACTUATOR_CONFIG (not yet implemented for full "
401 "decoding)");
402 Serial.print("Packet size: ");
403 Serial.print(size);
404 Serial.println(" bytes");
405 // TODO: Add full actuator config parsing when needed
406 decoded = true; // At least we identified the type
407 break;
408
410 Serial.println(
411 "Packet type: ABORT (not yet implemented for full decoding)");
412 Serial.print("Packet size: ");
413 Serial.print(size);
414 Serial.println(" bytes");
415 // TODO: Add full abort parsing when needed
416 decoded = true; // At least we identified the type
417 break;
418
420 Serial.println(
421 "Packet type: ABORT_DONE (not yet implemented for full "
422 "decoding)");
423 Serial.print("Packet size: ");
424 Serial.print(size);
425 Serial.println(" bytes");
426 // TODO: Add full abort done parsing when needed
427 decoded = true; // At least we identified the type
428 break;
429
431 Serial.println(
432 "Packet type: CLEAR_ABORT (not yet implemented for full "
433 "decoding)");
434 Serial.print("Packet size: ");
435 Serial.print(size);
436 Serial.println(" bytes");
437 // TODO: Add full clear abort parsing when needed
438 decoded = true; // At least we identified the type
439 break;
440
441 default:
442 Serial.print("Error: Unknown packet type: ");
443 Serial.println(static_cast<int>(header.packet_type));
444 decoded = false;
445 break;
446 }
447
448 if (!decoded) {
449 Serial.println("\n--- Decoding failed, showing raw data ---");
450 printRawPacketData(buffer, size);
451 }
452
453 Serial.println("----------------------------------------\n");
454}
455
456// ============================================================================
457// MAIN LOOP
458// ============================================================================
459
460void loop() {
461 // Check for incoming UDP packets
462 int packetSize = udp.parsePacket();
463 if (packetSize) {
464 Serial.print("Received packet of size ");
465 Serial.print(packetSize);
466 Serial.print(" bytes from ");
467 IPAddress remoteIp = udp.remoteIP();
468 Serial.print(remoteIp);
469 Serial.print(":");
470 Serial.println(udp.remotePort());
471
472 // Read the packet into the buffer
473 int len = udp.read(packetBuffer, MAX_PACKET_SIZE);
474 if (len > 0) {
475 // Decode and print packet information
477 } else {
478 Serial.println("Error: Failed to read packet data");
479 }
480 }
481
482 // Small delay to prevent overwhelming the system
483 delay(10);
484}
static SerialStub Serial
Definition Arduino.h:128
#define HEX
Definition Arduino.h:24
static EthernetClass Ethernet
Definition Ethernet.h:116
#define MAX_PACKET_SIZE
Definition main.h:6
void delay(int ms)
void setup()
Definition main.cpp:142
void loop()
Definition main.cpp:201
IPAddress dns(192, 168, 2, 1)
byte mac[6]
Definition main.cpp:31
IPAddress subnet(255, 255, 255, 0)
IPAddress staticIP(192, 168, 2, BOARD_ID_DEFAULT)
EthernetUDP udp
Definition main.cpp:40
IPAddress gateway(0, 0, 0, 0)
static IPAddress subnet(255, 255, 255, 0)
static IPAddress gateway(192, 168, 2, 1)
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]
Definition main.cpp:15
IPAddress dns(192, 168, 2, 1)
unsigned int localPort
Definition main.cpp:13
IPAddress staticIP(192, 168, 2, 101)
void printBoardHeartbeat(const daq::PacketHeader &header, const daq::BoardHeartbeatPacket &data)
Prints Board Heartbeat packet information.
Definition main.cpp:177
void decodeAndPrintPacket(const uint8_t *buffer, size_t size)
Attempts to decode and print packet information.
Definition main.cpp:297
#define ETH_MOSI_PIN
Definition main.cpp:10
void printBoardInfo()
Prints all board networking information to Serial.
Definition main.cpp:62
#define ETH_CS_PIN
Definition main.cpp:11
void printServerHeartbeat(const daq::PacketHeader &header, const daq::ServerHeartbeatPacket &data)
Prints Server Heartbeat packet information.
Definition main.cpp:259
#define ETH_MISO_PIN
Definition main.cpp:9
void printPacketHeader(const daq::PacketHeader &header)
Prints packet header information.
Definition main.cpp:127
void printRawPacketData(const uint8_t *buffer, size_t size)
Prints raw packet data in hex format for debugging.
Definition main.cpp:110
#define ETH_CLK_PIN
Definition main.cpp:8
bool parse_server_heartbeat_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, ServerHeartbeatPacket &data_out)
Parses a Server Heartbeat packet from buffer.
bool parse_board_heartbeat_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, BoardHeartbeatPacket &data_out)
Parses a Board Heartbeat packet from buffer.