40 #include <px4_platform_common/px4_config.h> 47 #ifdef TIOCSSINGLEWIRE 48 #include <sys/ioctl.h> 57 #define SBUS_DEBUG_LEVEL 0 59 #if defined(__PX4_POSIX_OCPOC) 60 #include <sys/ioctl.h> 61 #include <linux/serial_core.h> 64 #define SBUS_START_SYMBOL 0x0f 66 #define SBUS_INPUT_CHANNELS 16 67 #define SBUS_FLAGS_BYTE 23 68 #define SBUS_FAILSAFE_BIT 3 69 #define SBUS_FRAMELOST_BIT 2 75 #define SBUS1_MAX_RATE_HZ 300 76 #define SBUS1_MIN_RATE_HZ 50 79 #define SBUS1_DEFAULT_RATE_HZ 72 89 #define SBUS_RANGE_MIN 200.0f 90 #define SBUS_RANGE_MAX 1800.0f 92 #define SBUS_TARGET_MIN 1000.0f 93 #define SBUS_TARGET_MAX 2000.0f 95 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 100 #define SBUS_SCALE_FACTOR ((SBUS_TARGET_MAX - SBUS_TARGET_MIN) / (SBUS_RANGE_MAX - SBUS_RANGE_MIN)) 101 #define SBUS_SCALE_OFFSET (int)(SBUS_TARGET_MIN - (SBUS_SCALE_FACTOR * SBUS_RANGE_MIN + 0.5f)) 106 #define SBUS2_FRAME_SIZE_RX_VOLTAGE 3 107 #define SBUS2_FRAME_SIZE_GPS_DIGIT 3 134 sbus_decode(uint64_t frame_time, uint8_t *frame, uint16_t *values, uint16_t *num_values,
135 bool *sbus_failsafe,
bool *sbus_frame_drop, uint16_t max_values);
140 int sbus_fd = open(device, O_RDWR | O_NONBLOCK);
155 #if defined(__PX4_POSIX_OCPOC) 156 struct termios options;
158 if (tcgetattr(sbus_fd, &options) != 0) {
162 tcflush(sbus_fd, TCIFLUSH);
163 bzero(&options,
sizeof(options));
165 options.c_cflag |= (CLOCAL | CREAD);
166 options.c_cflag &= ~CSIZE;
167 options.c_cflag |= CS8;
168 options.c_cflag |= PARENB;
169 options.c_cflag &= ~PARODD;
170 options.c_iflag |= INPCK;
171 options.c_cflag |= CSTOPB;
173 options.c_cc[VTIME] = 0;
174 options.c_cc[VMIN] = 0;
176 cfsetispeed(&options, B38400);
177 cfsetospeed(&options, B38400);
179 tcflush(sbus_fd, TCIFLUSH);
181 if ((tcsetattr(sbus_fd, TCSANOW, &options)) != 0) {
186 struct serial_struct serials;
188 if ((ioctl(sbus_fd, TIOCGSERIAL, &serials)) < 0) {
192 serials.flags = ASYNC_SPD_CUST;
193 serials.custom_divisor = serials.baud_base / baud;
195 if ((ioctl(sbus_fd, TIOCSSERIAL, &serials)) < 0) {
199 ioctl(sbus_fd, TIOCGSERIAL, &serials);
201 tcflush(sbus_fd, TCIFLUSH);
210 tcgetattr(sbus_fd, &t);
211 cfsetspeed(&t, 100000);
212 t.c_cflag |= (CSTOPB | PARENB);
213 tcsetattr(sbus_fd, TCSANOW, &t);
219 #ifdef TIOCSSINGLEWIRE 220 ioctl(sbus_fd, TIOCSSINGLEWIRE, SER_SINGLEWIRE_ENABLED);
239 uint8_t byteindex = 1;
253 for (
unsigned i = 0; (i < num_values) && (i < 16); ++i) {
257 if (value > 0x07ff) {
261 while (offset >= 8) {
266 oframe[byteindex] |= (value << (offset)) & 0xff;
267 oframe[byteindex + 1] |= (value >> (8 - offset)) & 0xff;
268 oframe[byteindex + 2] |= (value >> (16 - offset)) & 0xff;
282 sbus_input(
int sbus_fd, uint16_t *values, uint16_t *num_values,
bool *sbus_failsafe,
bool *sbus_frame_drop,
283 uint16_t max_channels)
320 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 321 printf(
"SBUS: RESET (TIME LIM)\n");
338 return sbus_parse(now, &buf[0], ret, values, num_values, sbus_failsafe,
343 sbus_parse(uint64_t now, uint8_t *frame,
unsigned len, uint16_t *values,
344 uint16_t *num_values,
bool *sbus_failsafe,
bool *sbus_frame_drop,
unsigned *frame_drops, uint16_t max_channels)
352 bool decode_ret =
false;
355 for (
unsigned d = 0; d < len; d++) {
361 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 362 printf(
"SBUS2: RESET (BUF LIM)\n");
369 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 370 printf(
"SBUS2: RESET (PACKET LIM)\n");
374 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 1 375 printf(
"sbus state: %s%s%s%s%s%s, count: %d, val: %02x\n",
414 decode_ret =
sbus_decode(now,
sbus_frame, values, num_values, sbus_failsafe, sbus_frame_drop, max_channels);
420 unsigned start_index = 0;
432 if (start_index != 0) {
434 for (
unsigned i = 0; i < partial_frame_count - start_index; i++) {
438 partial_frame_count -= start_index;
441 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 442 printf(
"DECODE RECOVERY: %d\n", start_index);
451 if (start_index == 0) {
478 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 2 480 printf(
"rx_voltage %d\n", (
int)rx_voltage);
511 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 512 uint16_t gps_something = (frame[1] << 8) | frame[2];
513 printf(
"gps_something %d\n", (
int)gps_something);
530 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 531 printf(
"UNKNOWN PROTO STATE");
565 { { 0, 0, 0xff, 0}, { 1, 0, 0x07, 8}, { 0, 0, 0x00, 0} },
566 { { 1, 3, 0x1f, 0}, { 2, 0, 0x3f, 5}, { 0, 0, 0x00, 0} },
567 { { 2, 6, 0x03, 0}, { 3, 0, 0xff, 2}, { 4, 0, 0x01, 10} },
568 { { 4, 1, 0x7f, 0}, { 5, 0, 0x0f, 7}, { 0, 0, 0x00, 0} },
569 { { 5, 4, 0x0f, 0}, { 6, 0, 0x7f, 4}, { 0, 0, 0x00, 0} },
570 { { 6, 7, 0x01, 0}, { 7, 0, 0xff, 1}, { 8, 0, 0x03, 9} },
571 { { 8, 2, 0x3f, 0}, { 9, 0, 0x1f, 6}, { 0, 0, 0x00, 0} },
572 { { 9, 5, 0x07, 0}, {10, 0, 0xff, 3}, { 0, 0, 0x00, 0} },
573 { {11, 0, 0xff, 0}, {12, 0, 0x07, 8}, { 0, 0, 0x00, 0} },
574 { {12, 3, 0x1f, 0}, {13, 0, 0x3f, 5}, { 0, 0, 0x00, 0} },
575 { {13, 6, 0x03, 0}, {14, 0, 0xff, 2}, {15, 0, 0x01, 10} },
576 { {15, 1, 0x7f, 0}, {16, 0, 0x0f, 7}, { 0, 0, 0x00, 0} },
577 { {16, 4, 0x0f, 0}, {17, 0, 0x7f, 4}, { 0, 0, 0x00, 0} },
578 { {17, 7, 0x01, 0}, {18, 0, 0xff, 1}, {19, 0, 0x03, 9} },
579 { {19, 2, 0x3f, 0}, {20, 0, 0x1f, 6}, { 0, 0, 0x00, 0} },
580 { {20, 5, 0x07, 0}, {21, 0, 0xff, 3}, { 0, 0, 0x00, 0} }
584 sbus_decode(uint64_t frame_time, uint8_t *frame, uint16_t *values, uint16_t *num_values,
585 bool *sbus_failsafe,
bool *sbus_frame_drop, uint16_t max_values)
591 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 592 printf(
"DECODE FAIL: ");
595 printf(
"%0x ", frame[i]);
632 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0 633 printf(
"DECODE FAIL: END MARKER\n");
644 for (
unsigned channel = 0; channel < chancount; channel++) {
647 for (
unsigned pick = 0; pick < 3; pick++) {
650 if (decode->
mask != 0) {
651 unsigned piece = frame[1 + decode->
byte];
653 piece &= decode->
mask;
666 if (max_values > 17 && chancount > 15) {
676 *num_values = chancount;
681 *sbus_failsafe =
true;
682 *sbus_frame_drop =
true;
691 *sbus_failsafe =
false;
692 *sbus_frame_drop =
true;
695 *sbus_failsafe =
false;
696 *sbus_frame_drop =
false;
static unsigned partial_frame_count
static bool sbus_decode(uint64_t frame_time, uint8_t *frame, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop, uint16_t max_values)
#define SBUS2_FRAME_SIZE_RX_VOLTAGE
#define SBUS_START_SYMBOL
Namespace encapsulating all device framework classes, functions and data.
High-resolution timer with callouts and timekeeping.
__EXPORT rc_decode_buf_t rc_decode_buf
#define SBUS1_MIN_RATE_HZ
unsigned sbus_dropped_frames()
The number of incomplete frames we encountered.
static void read(bootloader_app_shared_t *pshared)
static hrt_abstime last_rx_time
#define SBUS_FAILSAFE_BIT
#define SBUS_SCALE_FACTOR
#define SBUS1_DEFAULT_RATE_HZ
#define SBUS_FRAMELOST_BIT
static enum SBUS2_DECODE_STATE sbus_decode_state
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
static const struct sbus_bit_pick sbus_decoder[SBUS_INPUT_CHANNELS][3]
static unsigned sbus_frame_drops
int sbus_init(const char *device, bool singlewire)
static unsigned sbus1_frame_delay
static void write(bootloader_app_shared_t *pshared)
void sbus2_output(int sbus_fd, uint16_t *values, uint16_t num_values)
#define SBUS_INPUT_CHANNELS
uint8_t sbus_frame_t[SBUS_FRAME_SIZE+(SBUS_FRAME_SIZE/2)]
#define SBUS1_MAX_RATE_HZ
RC protocol definition for S.BUS.
void sbus1_set_output_rate_hz(uint16_t rate_hz)
void sbus1_output(int sbus_fd, uint16_t *values, uint16_t num_values)
#define SBUS_SCALE_OFFSET
bool sbus_parse(uint64_t now, uint8_t *frame, unsigned len, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop, unsigned *frame_drops, uint16_t max_channels)
static sbus_frame_t & sbus_frame
bool sbus_input(int sbus_fd, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop, uint16_t max_channels)
static void decode(bson_decoder_t decoder)
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
int sbus_config(int sbus_fd, bool singlewire)
Parse serial bytes on the S.BUS bus.
static hrt_abstime last_txframe_time