Repository navigation
Expand file tree
/
Copy pathradio.cpp
More file actions
157 lines (130 loc) · 3.89 KB
/
Copy pathradio.cpp
File metadata and controls
157 lines (130 loc) · 3.89 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* @file radio.cpp
* @author sj728
*
* @brief Radio module implementation for the RFD900x
*/
#include "radio.hpp"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/uart.h"
#include "telemetry.hpp"
#include "time.h"
#include "pico/time.h"
#include "pins.hpp"
#include <cstdio>
#include <sstream>
#include <cstring>
#include <inttypes.h> // For PRId64
#ifdef RATS_VERBOSE
#define debug_log(...) \
do \
{ \
printf(__VA_ARGS__); \
} while (0)
#else
#define debug_log(...) \
do \
{ \
} while (0)
#endif
const uint32_t SYNC_WORD = 0x3E5D5967;
const size_t PACKET_SIZE = sizeof(Telemetry) + sizeof(SYNC_WORD);
void print_buffer_hex(const char *buffer, size_t size)
{
printf("Buffer bytes (hex): ");
for (size_t j = 0; j < size; j++)
{
printf("%02X ", (unsigned char)buffer[j]);
}
printf("\n");
}
bool read_sync_word(void *buffer, int start)
{
uint32_t sync_word;
std::memcpy(&sync_word, static_cast<char *>(buffer) + start, sizeof(sync_word));
// printf("Sync word: %08X\n", sync_word);
return sync_word == SYNC_WORD;
}
bool Radio::start()
{
// By default, the radio module has baudrate value rfm_baudrate, so we
// set that value on the local UART port
uart_init(UART_PORT, RFM_BAUDRATE);
gpio_set_function(RFM_TX, GPIO_FUNC_UART);
gpio_set_function(RFM_RX, GPIO_FUNC_UART);
// Set UART format to 8 data bits, 1 stop bit, no parity
uart_set_format(UART_PORT, 8, 1, UART_PARITY_NONE);
// Set flow control to false for both
uart_set_hw_flow(UART_PORT, false, false);
uart_set_fifo_enabled(UART_PORT, true);
return true;
}
bool Radio::read(std::vector<Telemetry> &result)
{
const size_t BUFFER_SIZE = 10000;
// Telemetry packet size in bytes
char data[BUFFER_SIZE];
size_t end_index = 0;
#ifdef RATS_TIME
const absolute_time_t start_time = get_absolute_time();
#endif
// If there isn't incoming data after 1ms, the data packet is over
const int timeout_us = 1000; // 1ms
while (uart_is_readable_within_us(UART_PORT, timeout_us))
{
const char c = uart_getc(UART_PORT);
// debug_log("Received character: %c\n", c);
// Append the character to the response buffer if there's space
if (end_index < BUFFER_SIZE)
{
data[end_index++] = c;
}
else
{
debug_log("Response buffer overflow: \n");
break;
}
}
// Store result if data was received
const bool data_received = (end_index != 0);
if (!data_received)
{
return false;
}
debug_log("\n\n");
debug_log("Data size: %d\n", end_index);
// print_buffer_hex(data, end_index);
// TODO: Salvage a packet if it got split between two data burts
size_t i = 0;
while (i < end_index)
{
// Keep reading until you find sync number
while (i + sizeof(SYNC_WORD) < end_index && !read_sync_word(data, i))
{
i++;
}
// If it's possible for the packet to have been fully delivered
if (i + PACKET_SIZE <= end_index)
{
// Extract the packet
Telemetry telemetry;
std::memcpy(&telemetry, data + i + sizeof(SYNC_WORD), sizeof(Telemetry));
// Store the packet
result.push_back(telemetry);
}
i += PACKET_SIZE;
}
#ifdef RATS_TIME
// Calculate elapsed time in seconds
const int64_t elapsed_us = absolute_time_diff_us(start_time, get_absolute_time());
// Print the elapsed time using the PRId64 macro for 64-bit integers
printf("Elapsed time: %" PRId64 " microseconds\n", elapsed_us);
#endif
// printf("Number of telemetry packets processed: %d\n", result.size());
if (result.size() == 0)
{
return false;
}
return true;
}