|
|
@ -46,6 +46,7 @@ |
|
|
|
#include <fcntl.h> |
|
|
|
#include <fcntl.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <termios.h> |
|
|
|
#include <termios.h> |
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "dsm.h" |
|
|
|
#include "dsm.h" |
|
|
|
#include <drivers/drv_hrt.h> |
|
|
|
#include <drivers/drv_hrt.h> |
|
|
@ -57,7 +58,7 @@ |
|
|
|
#define dsm_udelay(arg) up_udelay(arg) |
|
|
|
#define dsm_udelay(arg) up_udelay(arg) |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
//#define DSM_DEBUG
|
|
|
|
// #define DSM_DEBUG
|
|
|
|
|
|
|
|
|
|
|
|
static enum DSM_DECODE_STATE { |
|
|
|
static enum DSM_DECODE_STATE { |
|
|
|
DSM_DECODE_STATE_DESYNC = 0, |
|
|
|
DSM_DECODE_STATE_DESYNC = 0, |
|
|
@ -69,6 +70,7 @@ static hrt_abstime dsm_last_rx_time; /**< Timestamp when we last rece |
|
|
|
static hrt_abstime dsm_last_frame_time; /**< Timestamp for start of last valid dsm frame */ |
|
|
|
static hrt_abstime dsm_last_frame_time; /**< Timestamp for start of last valid dsm frame */ |
|
|
|
static uint8_t dsm_frame[DSM_BUFFER_SIZE]; /**< DSM dsm frame receive buffer */ |
|
|
|
static uint8_t dsm_frame[DSM_BUFFER_SIZE]; /**< DSM dsm frame receive buffer */ |
|
|
|
static uint8_t dsm_buf[DSM_FRAME_SIZE * 2]; |
|
|
|
static uint8_t dsm_buf[DSM_FRAME_SIZE * 2]; |
|
|
|
|
|
|
|
static uint16_t dsm_chan_buf[DSM_MAX_CHANNEL_COUNT]; |
|
|
|
static unsigned dsm_partial_frame_count; /**< Count of bytes received for current dsm frame */ |
|
|
|
static unsigned dsm_partial_frame_count; /**< Count of bytes received for current dsm frame */ |
|
|
|
static unsigned dsm_channel_shift = 0; /**< Channel resolution, 0=unknown, 1=10 bit, 2=11 bit */ |
|
|
|
static unsigned dsm_channel_shift = 0; /**< Channel resolution, 0=unknown, 1=10 bit, 2=11 bit */ |
|
|
|
static unsigned dsm_frame_drops = 0; /**< Count of incomplete DSM frames */ |
|
|
|
static unsigned dsm_frame_drops = 0; /**< Count of incomplete DSM frames */ |
|
|
@ -263,6 +265,19 @@ dsm_config(int fd) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
dsm_proto_init() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
dsm_channel_shift = 0; |
|
|
|
|
|
|
|
dsm_frame_drops = 0; |
|
|
|
|
|
|
|
dsm_chan_count = 0; |
|
|
|
|
|
|
|
dsm_decode_state = DSM_DECODE_STATE_DESYNC; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < DSM_MAX_CHANNEL_COUNT; i++) { |
|
|
|
|
|
|
|
dsm_chan_buf[i] = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Initialize the DSM receive functionality |
|
|
|
* Initialize the DSM receive functionality |
|
|
|
* |
|
|
|
* |
|
|
@ -278,10 +293,7 @@ dsm_init(const char *device) |
|
|
|
dsm_fd = open(device, O_RDONLY | O_NONBLOCK); |
|
|
|
dsm_fd = open(device, O_RDONLY | O_NONBLOCK); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
dsm_channel_shift = 0; |
|
|
|
dsm_proto_init(); |
|
|
|
dsm_frame_drops = 0; |
|
|
|
|
|
|
|
dsm_chan_count = 0; |
|
|
|
|
|
|
|
dsm_decode_state = DSM_DECODE_STATE_DESYNC; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ret = dsm_config(dsm_fd); |
|
|
|
int ret = dsm_config(dsm_fd); |
|
|
|
|
|
|
|
|
|
|
@ -494,7 +506,7 @@ dsm_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, bool |
|
|
|
/* if the value is unrealistic, fail the parsing entirely */ |
|
|
|
/* if the value is unrealistic, fail the parsing entirely */ |
|
|
|
if (values[i] < 600 || values[i] > 2400) { |
|
|
|
if (values[i] < 600 || values[i] > 2400) { |
|
|
|
#ifdef DSM_DEBUG |
|
|
|
#ifdef DSM_DEBUG |
|
|
|
printf("DSM: VALUE RANGE FAIL\n"); |
|
|
|
printf("DSM: VALUE RANGE FAIL: %d: %d\n", (int)i, (int)values[i]); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
dsm_chan_count = 0; |
|
|
|
dsm_chan_count = 0; |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -581,6 +593,11 @@ dsm_parse(uint64_t now, uint8_t *frame, unsigned len, uint16_t *values, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool decode_ret = false; |
|
|
|
bool decode_ret = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ensure there can be no overflows */ |
|
|
|
|
|
|
|
if (max_channels > sizeof(dsm_chan_buf) / sizeof(dsm_chan_buf[0])) { |
|
|
|
|
|
|
|
max_channels = sizeof(dsm_chan_buf) / sizeof(dsm_chan_buf[0]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* keep decoding until we have consumed the buffer */ |
|
|
|
/* keep decoding until we have consumed the buffer */ |
|
|
|
for (unsigned d = 0; d < len; d++) { |
|
|
|
for (unsigned d = 0; d < len; d++) { |
|
|
|
|
|
|
|
|
|
|
@ -636,7 +653,7 @@ dsm_parse(uint64_t now, uint8_t *frame, unsigned len, uint16_t *values, |
|
|
|
* Great, it looks like we might have a frame. Go ahead and |
|
|
|
* Great, it looks like we might have a frame. Go ahead and |
|
|
|
* decode it. |
|
|
|
* decode it. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
decode_ret = dsm_decode(now, values, &dsm_chan_count, dsm_11_bit, max_channels); |
|
|
|
decode_ret = dsm_decode(now, &dsm_chan_buf[0], &dsm_chan_count, dsm_11_bit, max_channels); |
|
|
|
|
|
|
|
|
|
|
|
/* we consumed the partial frame, reset */ |
|
|
|
/* we consumed the partial frame, reset */ |
|
|
|
dsm_partial_frame_count = 0; |
|
|
|
dsm_partial_frame_count = 0; |
|
|
@ -665,6 +682,14 @@ dsm_parse(uint64_t now, uint8_t *frame, unsigned len, uint16_t *values, |
|
|
|
|
|
|
|
|
|
|
|
if (decode_ret) { |
|
|
|
if (decode_ret) { |
|
|
|
*num_values = dsm_chan_count; |
|
|
|
*num_values = dsm_chan_count; |
|
|
|
|
|
|
|
memcpy(&values[0], &dsm_chan_buf[0], dsm_chan_count * sizeof(dsm_chan_buf[0])); |
|
|
|
|
|
|
|
#ifdef DSM_DEBUG |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < dsm_chan_count; i++) { |
|
|
|
|
|
|
|
printf("dsm_decode: %u: %u\n", i, values[0]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
dsm_last_rx_time = now; |
|
|
|
dsm_last_rx_time = now; |
|
|
|