43 #define DSM_FRAME_SIZE 16 44 #define DSM_FRAME_CHANNELS 7 46 static uint64_t dsm_last_frame_time; 47 static unsigned dsm_channel_shift; 52 # define debug(fmt, args...) printf(fmt "\n", ##args) 54 # define debug(fmt, args...) do {} while(0) 89 *channel = (raw >> shift) & 0xf;
91 uint16_t data_mask = (1 << shift) - 1;
92 *value = raw & data_mask;
107 static uint32_t cs10;
108 static uint32_t cs11;
109 static unsigned samples;
123 const uint8_t *dp = &dsm_frame[2 + (2 * i)];
124 uint16_t raw = (dp[0] << 8) | dp[1];
125 unsigned channel,
value;
129 cs10 |= (1 << channel);
132 cs11 |= (1 << channel);
152 static uint32_t masks[] = {
161 unsigned votes10 = 0;
162 unsigned votes11 = 0;
164 for (
unsigned i = 0; i <
sizeof(masks)/
sizeof(masks[0]); i++) {
166 if (cs10 == masks[i])
169 if (cs11 == masks[i])
173 if ((votes11 == 1) && (votes10 == 0)) {
175 debug(
"DSM: 11-bit format");
179 if ((votes10 == 1) && (votes11 == 0)) {
181 debug(
"DSM: 10-bit format");
186 debug(
"DSM: format detect fail, 10: 0x%08x %d 11: 0x%08x %d", cs10, votes10, cs11, votes11);
195 dsm_decode(uint64_t frame_time,
const uint8_t dsm_frame[16], uint16_t *values, uint16_t *num_values, uint16_t max_values)
231 const uint8_t *dp = &dsm_frame[2 + (2 * i)];
232 uint16_t raw = (dp[0] << 8) | dp[1];
233 unsigned channel,
value;
239 if (channel >= max_values)
243 if (channel >= *num_values)
244 *num_values = channel + 1;
264 value = ((((int)value - 1024) * 1000) / 1700) + 1500;
289 values[channel] =
value;
298 if (*num_values == 13)
304 *num_values |= 0x8000;
314 #if defined(TEST_MAIN_PROGRAM) || defined(TEST_HEX_STRING) 315 static uint8_t dsm_partial_frame_count;
317 static enum DSM_DECODE_STATE {
318 DSM_DECODE_STATE_DESYNC = 0,
319 DSM_DECODE_STATE_SYNC
320 } dsm_decode_state = DSM_DECODE_STATE_DESYNC;
321 static uint64_t dsm_last_rx_time;
322 static uint16_t dsm_chan_count;
323 static uint16_t dsm_frame_drops;
326 dsm_parse(uint64_t now, uint8_t *frame,
unsigned len, uint16_t *values,
327 uint16_t *num_values,
bool *dsm_11_bit,
unsigned *frame_drops, uint16_t
max_channels)
333 bool decode_ret =
false;
336 for (
unsigned d = 0; d < len; d++) {
339 if (dsm_partial_frame_count ==
sizeof(dsm_frame) /
sizeof(dsm_frame[0])) {
340 dsm_partial_frame_count = 0;
341 dsm_decode_state = DSM_DECODE_STATE_DESYNC;
343 printf(
"DSM: RESET (BUF LIM)\n");
348 dsm_partial_frame_count = 0;
349 dsm_decode_state = DSM_DECODE_STATE_DESYNC;
351 printf(
"DSM: RESET (PACKET LIM)\n");
357 printf(
"dsm state: %s%s, count: %d, val: %02x\n",
358 (dsm_decode_state == DSM_DECODE_STATE_DESYNC) ?
"DSM_DECODE_STATE_DESYNC" :
"",
359 (dsm_decode_state == DSM_DECODE_STATE_SYNC) ?
"DSM_DECODE_STATE_SYNC" :
"",
360 dsm_partial_frame_count,
365 switch (dsm_decode_state) {
366 case DSM_DECODE_STATE_DESYNC:
369 if ((now - dsm_last_rx_time) > 5000) {
370 printf(
"resync %u\n", dsm_partial_frame_count);
371 dsm_decode_state = DSM_DECODE_STATE_SYNC;
372 dsm_partial_frame_count = 0;
374 dsm_frame[dsm_partial_frame_count++] = frame[d];
379 case DSM_DECODE_STATE_SYNC: {
380 dsm_frame[dsm_partial_frame_count++] = frame[d];
391 decode_ret =
dsm_decode(now, dsm_frame, values, &dsm_chan_count, max_channels);
394 printf(
"%u %u: ", ((
unsigned)(now/1000)) % 1000000, len);
396 printf(
"%02x ", (
unsigned)dsm_frame[i]);
403 dsm_partial_frame_count = 0;
406 if (decode_ret ==
false) {
407 dsm_decode_state = DSM_DECODE_STATE_DESYNC;
411 printf(
"%02x ", (
unsigned)dsm_frame[i]);
420 printf(
"UNKNOWN PROTO STATE");
429 *frame_drops = dsm_frame_drops;
433 *num_values = dsm_chan_count;
436 dsm_last_rx_time = now;
444 #ifdef TEST_MAIN_PROGRAM 448 #include <sys/types.h> 449 #include <sys/stat.h> 461 return 1.0e6*((ts.tv_sec + (ts.tv_nsec*1.0e-9)));
464 int main(
int argc,
const char *argv[])
466 int fd =
open(argv[1], O_RDONLY|O_CLOEXEC);
472 struct termios options;
474 tcgetattr(fd, &options);
476 cfsetispeed(&options, B115200);
477 cfsetospeed(&options, B115200);
479 options.c_cflag &= ~(PARENB|CSTOPB|CSIZE);
480 options.c_cflag |= CS8;
482 options.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
483 options.c_iflag &= ~(IXON|IXOFF|IXANY);
484 options.c_oflag &= ~OPOST;
486 if (tcsetattr(fd, TCSANOW, &options) != 0) {
490 tcflush(fd, TCIOFLUSH);
493 memset(values, 0,
sizeof(values));
497 uint16_t num_values = 0;
508 if (select(fd+1, &fds,
nullptr,
nullptr, &tv) != 1) {
513 if ((nread =
read(fd, b,
sizeof(b))) < 1) {
518 unsigned frame_drops;
520 if (dsm_parse(
micros64(), b, nread, values, &num_values, &dsm_11_bit, &frame_drops, 18)) {
522 printf(
"%u: ", num_values);
523 for (uint8_t i=0; i<num_values; i++) {
524 printf(
"%u:%4u ", i+1, values[i]);
531 #elif defined(TEST_HEX_STRING) 537 int main(
int argc,
const char *argv[])
542 for (uint8_t i=1; i<argc; i++) {
544 if (
sscanf(argv[i],
"%02x", &v) != 1 || v > 255) {
545 printf(
"Bad hex value at %u : %s\n", (
unsigned)i, argv[i]);
551 memset(values, 0,
sizeof(values));
554 uint16_t num_values = 0;
556 unsigned frame_drops;
560 if (dsm_parse(t, b,
sizeof(b), values, &num_values, &dsm_11_bit, &frame_drops, 18)) {
562 printf(
"%u: ", num_values);
563 for (uint8_t i=0; i<num_values; i++) {
564 printf(
"%u:%4u ", i+1, values[i]);
int printf(const char *fmt,...)
void clock_gettime(uint32_t a1, void *a2)
int open(const char *pathname, int flags)
POSIX Open a file with integer mode flags.
#define DSM_FRAME_CHANNELS
#define debug(fmt, args...)
static bool dsm_decode_channel(uint16_t raw, unsigned shift, unsigned *channel, unsigned *value)
void perror(const char *s)
POSIX perror() - convert POSIX errno to text with user message.
ssize_t read(int fd, void *buf, size_t count)
POSIX read count bytes from *buf to fileno fd.
int sscanf(const char *buf, const char *fmt,...)
bool dsm_decode(uint64_t frame_time, const uint8_t dsm_frame[16], uint16_t *values, uint16_t *num_values, uint16_t max_values)
int main(int argc, char const **argv)
static uint64_t dsm_last_frame_time
static unsigned dsm_channel_shift
static void dsm_guess_format(bool reset, const uint8_t dsm_frame[16])