Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
pdec.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Fabien-B <fabien-b@github.com>
3 *
4 * This file is part of paparazzi. See LICENCE file.
5 *
6 * Pprz Decawave driver. Allows ranging, as well as TDOA.
7 */
8
10#include "mcu_periph/uart.h"
12#include "modules/core/abi.h"
14
15#include <stdio.h>
16#include <string.h>
17
18#define PDEC_SYNC_BYTE 0xff
19#define PDEC_FRAME_OVERHEAD 4
20#define PDEC_PACKED __attribute__((packed))
21
23
24static void _pdec_init(pdec_t *pdec);
26static void _pdec_event(pdec_t *pdec);
27
31
36
42
49
55
62
70
75
84
85static bool pdec_send_frame(pdec_t *pdec, const uint8_t *payload, uint8_t payload_len)
86{
88 uint8_t checksum = payload_len;
90 long fd = 0;
91
92 if (payload_len == 0) {
94 return false;
95 }
96
99 frame[2] = payload_len;
100 for (uint8_t i = 0; i < payload_len; i++) {
101 frame[3 + i] = payload[i];
102 checksum ^= payload[i];
103 }
104 frame[3 + payload_len] = checksum;
105
108 return true;
109}
110
112 const struct pdec_distance_payload *payload)
113{
114 result->dst_id = payload->dst_id;
115 result->status = (enum pdec_status)payload->status;
116 result->distance = payload->distance;
117 result->updated = true;
118}
119
121{
122 const uint8_t *payload = pdec->rx_payload;
123 uint8_t len = pdec->rx_len;
124 uint8_t msg_id;
125
126 if (len == 0) {
128 return;
129 }
130
131 msg_id = payload[0];
132 switch (msg_id) {
133 case PDEC_MSG_ERROR: {
134 if (len != sizeof(struct pdec_error_payload)) {
136 return;
137 }
138 const struct pdec_error_payload *msg = (const struct pdec_error_payload *)payload;
139 pdec->last_error.command = msg->command;
140 pdec->last_error.status = (enum pdec_status)msg->status;
141 pdec->last_error.updated = true;
142 break;
143 }
144
146 if (len != sizeof(struct pdec_distance_payload)) {
148 return;
149 }
151 break;
152
154 if (len != sizeof(struct pdec_distance_payload)) {
156 return;
157 }
159 break;
160
162 if (len < sizeof(struct pdec_device_list_payload)) {
164 return;
165 }
166 const struct pdec_device_list_payload *msg = (const struct pdec_device_list_payload *)payload;
167 uint8_t total_count = msg->count;
168 if (total_count > ((PDEC_MAX_PAYLOAD_LEN - sizeof(struct pdec_device_list_payload)) / sizeof(msg->device_ids[0])) ||
169 len != (uint8_t)(sizeof(struct pdec_device_list_payload) + (total_count * sizeof(msg->device_ids[0])))) {
171 return;
172 }
173 pdec->devices.total_count = total_count;
174 pdec->devices.count = total_count > PDEC_MAX_DEVICES ? PDEC_MAX_DEVICES : total_count;
176 for (uint8_t i = 0; i < pdec->devices.count; i++) {
177 pdec->devices.device_ids[i] = msg->device_ids[i];
178 }
179 pdec->devices.updated = true;
180 break;
181 }
182
184 if (len != sizeof(struct pdec_send_data_result_payload)) {
186 return;
187 }
188 const struct pdec_send_data_result_payload *msg = (const struct pdec_send_data_result_payload *)payload;
189 pdec->last_send_data.dst_id = msg->dst_id;
190 pdec->last_send_data.status = (enum pdec_status)msg->status;
191 pdec->last_send_data.sent_len = msg->sent_len;
193 break;
194 }
195
197 if (len != sizeof(struct pdec_ranging_event_payload)) {
199 return;
200 }
201 const struct pdec_ranging_event_payload *msg = (const struct pdec_ranging_event_payload *)payload;
205 pdec->last_ranging_event.distance = msg->distance;
209 msg->src_id,
210 msg->dst_id,
211 msg->distance
212 );
213 break;
214 }
215
217 if (len < sizeof(struct pdec_tdoa_report_event_payload)) {
219 return;
220 }
221 const struct pdec_tdoa_report_event_payload *msg = (const struct pdec_tdoa_report_event_payload *)payload;
222 uint8_t total_count = msg->count;
223 if (total_count > ((PDEC_MAX_PAYLOAD_LEN - sizeof(struct pdec_tdoa_report_event_payload)) /
224 sizeof(struct pdec_tdoa_report_payload)) ||
225 len != (uint8_t)(sizeof(struct pdec_tdoa_report_event_payload) +
226 (total_count * sizeof(struct pdec_tdoa_report_payload)))) {
228 return;
229 }
234 pdec->last_tdoa_report_event.timed_out = msg->timed_out != 0;
238 for (uint8_t i = 0; i < pdec->last_tdoa_report_event.count; i++) {
239 src_id[i] = msg->reports[i].reporter_id;
240 range_diff[i] = msg->reports[i].distance;
243 }
247 (uint16_t)msg->blink_id,
249 src_id,
251 );
252 break;
253 }
254
255 default:
257 return;
258 }
259
261}
262
264{
265 switch (pdec->rx_state) {
266 case PDEC_RX_SYNC_1:
267 if (byte == PDEC_SYNC_BYTE) {
269 }
270 break;
271
272 case PDEC_RX_SYNC_2:
273 if (byte == PDEC_SYNC_BYTE) {
275 } else {
277 }
278 break;
279
280 case PDEC_RX_LEN:
281 pdec->rx_len = byte;
282 pdec->rx_idx = 0;
285 break;
286
287 case PDEC_RX_PAYLOAD:
290 if (pdec->rx_idx >= pdec->rx_len) {
292 }
293 break;
294
295 case PDEC_RX_CHECKSUM:
296 if (pdec->rx_checksum == byte) {
298 } else {
300 }
302 break;
303
304 default:
306 break;
307 }
308}
309
310static void _pdec_init(pdec_t *pdec)
311{
312 memset(pdec, 0, sizeof(*pdec));
315}
316
318{
319 char buf[100];
320
321 if(pdec->last_error.updated) {
322
323
324 }
325 if(pdec->last_range.updated) {
326
327
328
329 }
331
332 }
333 if(pdec->devices.updated) {
334
335 }
337
338 }
341
342 int len = snprintf(buf, sizeof(buf), "[RNG]%x->%x:%0.2f",
347 }
350 int offset = snprintf(buf, sizeof(buf), "[TDOA]");
351 for(int i=0; i<pdec->last_tdoa_report_event.count; i++) {
352 offset += snprintf(buf+offset, sizeof(buf)-offset, "%x:%0.2f,",
355 }
357 }
358
359}
360
362{
363 while (uart_char_available(pdec->dev)) {
365 }
366}
367
369{
370 const struct pdec_target_cmd_payload payload = {
372 .dst_id = dst_id,
373 };
374 return pdec_send_frame(&pdec, (const uint8_t *)&payload, sizeof(payload));
375}
376
378{
379 const struct pdec_target_cmd_payload payload = {
381 .dst_id = dst_id,
382 };
383 return pdec_send_frame(&pdec, (const uint8_t *)&payload, sizeof(payload));
384}
385
387{
388 const struct pdec_cmd_payload payload = {
390 };
391 return pdec_send_frame(&pdec, (const uint8_t *)&payload, sizeof(payload));
392}
393
394bool pdec_send_data(uint16_t dst_id, const uint8_t *data, uint8_t len)
395{
396 uint8_t payload[sizeof(struct pdec_target_cmd_payload) + PDEC_MAX_DATA_LEN];
397 struct pdec_target_cmd_payload header = {
399 .dst_id = dst_id,
400 };
401
402 if (len > PDEC_MAX_DATA_LEN || (len > 0 && data == NULL)) {
404 return false;
405 }
406
407 memcpy(payload, &header, sizeof(header));
408 if (len > 0) {
409 memcpy(&payload[sizeof(header)], data, len);
410 }
411
412 return pdec_send_frame(&pdec, payload, (uint8_t)(sizeof(header) + len));
413}
414
415
416
417void pdec_init(void)
418{
420}
421
426
427void pdec_event(void)
428{
430}
431
432
Main include for ABI (AirBorneInterface).
Convenience defines for ABI sender IDs.
#define UWB_PDEC_ID
static uint8_t checksum
static uint8_t frame[20]
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
int uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition uart_arch.c:357
uint8_t uart_getch(struct uart_periph *p)
Definition uart_arch.c:348
uint16_t foo
Definition main_demo5.c:58
#define byte
struct pdec_tdoa_report_payload reports[]
Definition pdec.c:82
bool pdec_range(uint16_t dst_id)
Definition pdec.c:368
uint16_t dst_id
Definition pdec.c:45
bool pdec_get_distance(uint16_t dst_id)
Definition pdec.c:377
#define PDEC_PACKED
Definition pdec.c:20
static void pdec_parse_byte(pdec_t *pdec, uint8_t byte)
Definition pdec.c:263
uint8_t status
Definition pdec.c:40
static bool pdec_send_frame(pdec_t *pdec, const uint8_t *payload, uint8_t payload_len)
Definition pdec.c:85
static void pdec_parse_distance_result(struct pdec_distance_result *result, const struct pdec_distance_payload *payload)
Definition pdec.c:111
uint8_t command
Definition pdec.c:39
bool pdec_send_data(uint16_t dst_id, const uint8_t *data, uint8_t len)
Definition pdec.c:394
uint16_t reporter_id
Definition pdec.c:72
uint8_t id
Definition pdec.c:29
void pdec_event(void)
Definition pdec.c:427
static void _pdec_event(pdec_t *pdec)
Definition pdec.c:361
pdec_t pdec
Definition pdec.c:22
uint16_t device_ids[]
Definition pdec.c:53
void uwb_range(uint16_t dst_id)
Definition pdec.c:433
void pdec_periodic_report(void)
Definition pdec.c:422
uint8_t id
Definition pdec.c:38
void pdec_init(void)
Definition pdec.c:417
static void pdec_dispatch_frame(pdec_t *pdec)
Definition pdec.c:120
#define PDEC_FRAME_OVERHEAD
Definition pdec.c:19
#define PDEC_SYNC_BYTE
Definition pdec.c:18
static void _pdec_periodic_report(pdec_t *pdec)
Definition pdec.c:317
static void _pdec_init(pdec_t *pdec)
Definition pdec.c:310
bool pdec_list_devices(void)
Definition pdec.c:386
uint32_t tx_drops
Definition pdec.h:125
enum pdec_status status
Definition pdec.h:91
struct pdec_distance_result last_range
Definition pdec.h:132
uint16_t dst_id
Definition pdec.h:99
struct pdec_error_response last_error
Definition pdec.h:131
pdec_status
Definition pdec.h:44
uint8_t command
Definition pdec.h:69
uint8_t sent_len
Definition pdec.h:92
struct pdec_tdoa_report_event last_tdoa_report_event
Definition pdec.h:137
uint8_t expected_count
Definition pdec.h:111
enum pdec_status status
Definition pdec.h:70
uint32_t rx_unknown_messages
Definition pdec.h:123
float distance
Definition pdec.h:105
bool truncated
Definition pdec.h:84
struct pdec_device_list devices
Definition pdec.h:134
uint8_t count
Definition pdec.h:82
uint16_t src_id
Definition pdec.h:98
uint16_t reporter_id
Definition pdec.h:104
#define PDEC_MAX_PAYLOAD_LEN
Definition pdec.h:24
uint8_t rx_len
Definition pdec.h:142
uint8_t rx_idx
Definition pdec.h:143
struct pdec_counters counters
Definition pdec.h:138
enum pdec_status status
Definition pdec.h:76
uint16_t dst_id
Definition pdec.h:75
struct pdec_send_data_result last_send_data
Definition pdec.h:135
uint8_t rx_checksum
Definition pdec.h:144
#define PDEC_MAX_DATA_LEN
Definition pdec.h:25
uint16_t dst_id
Definition pdec.h:90
struct uart_periph * dev
Definition pdec.h:129
struct pdec_tdoa_report reports[PDEC_MAX_TDOA_REPORTS]
Definition pdec.h:116
uint32_t rx_checksum_errors
Definition pdec.h:121
pdec_event_kind
Definition pdec.h:53
uint32_t blink_id
Definition pdec.h:110
enum pdec_event_kind kind
Definition pdec.h:97
struct pdec_ranging_event last_ranging_event
Definition pdec.h:136
enum pdec_rx_state rx_state
Definition pdec.h:141
bool updated
Definition pdec.h:81
struct pdec_distance_result last_distance
Definition pdec.h:133
@ PDEC_CMD_GET_DISTANCE
Definition pdec.h:29
@ PDEC_CMD_SEND_DATA
Definition pdec.h:31
@ PDEC_CMD_RANGE
Definition pdec.h:28
@ PDEC_CMD_LIST_DEVICES
Definition pdec.h:30
uint32_t rx_length_errors
Definition pdec.h:122
uint8_t rx_payload[PDEC_MAX_PAYLOAD_LEN]
Definition pdec.h:145
@ PDEC_MSG_ERROR
Definition pdec.h:35
@ PDEC_MSG_DEVICE_LIST
Definition pdec.h:38
@ PDEC_MSG_SEND_DATA_RESULT
Definition pdec.h:39
@ PDEC_MSG_RANGING_EVENT
Definition pdec.h:40
@ PDEC_MSG_RANGE_RESULT
Definition pdec.h:36
@ PDEC_MSG_DISTANCE
Definition pdec.h:37
@ PDEC_MSG_TDOA_REPORT_EVENT
Definition pdec.h:41
uint8_t total_count
Definition pdec.h:113
uint32_t rx_frames
Definition pdec.h:120
uint32_t tx_frames
Definition pdec.h:124
@ PDEC_RX_CHECKSUM
Definition pdec.h:64
@ PDEC_RX_LEN
Definition pdec.h:62
@ PDEC_RX_SYNC_2
Definition pdec.h:61
@ PDEC_RX_PAYLOAD
Definition pdec.h:63
@ PDEC_RX_SYNC_1
Definition pdec.h:60
#define PDEC_MAX_DEVICES
Definition pdec.h:17
uint16_t device_ids[PDEC_MAX_DEVICES]
Definition pdec.h:85
#define PDEC_MAX_TDOA_REPORTS
Definition pdec.h:21
uint8_t total_count
Definition pdec.h:83
Definition pdec.h:128
int fd
Definition serial.c:26
void WEAK uart_put_buffer(struct uart_periph *p, long fd, const uint8_t *data, uint16_t len)
Definition uart.c:161
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
static const float offset[]
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.