PX4 Firmware
PX4 Autopilot Software http://px4.io
sbus.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2017 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file sbus.c
36  *
37  * Serial protocol decoder for the Futaba S.bus protocol.
38  */
39 
40 #include <px4_platform_common/px4_config.h>
41 
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <termios.h>
45 #include <string.h>
46 
47 #ifdef TIOCSSINGLEWIRE
48 #include <sys/ioctl.h>
49 #endif
50 
51 #include "sbus.h"
52 #include "common_rc.h"
53 #include <drivers/drv_hrt.h>
54 
55 using namespace time_literals;
56 
57 #define SBUS_DEBUG_LEVEL 0 /* Set debug output level */
58 
59 #if defined(__PX4_POSIX_OCPOC)
60 #include <sys/ioctl.h>
61 #include <linux/serial_core.h>
62 #endif
63 
64 #define SBUS_START_SYMBOL 0x0f
65 
66 #define SBUS_INPUT_CHANNELS 16
67 #define SBUS_FLAGS_BYTE 23
68 #define SBUS_FAILSAFE_BIT 3
69 #define SBUS_FRAMELOST_BIT 2
70 
71 // testing with a SBUS->PWM adapter shows that
72 // above 300Hz SBUS becomes unreliable. 333 would
73 // be the theoretical achievable, but at 333Hz some
74 // frames are lost
75 #define SBUS1_MAX_RATE_HZ 300
76 #define SBUS1_MIN_RATE_HZ 50
77 
78 // this is the rate of the old code
79 #define SBUS1_DEFAULT_RATE_HZ 72
80 
81 /*
82  Measured values with Futaba FX-30/R6108SB:
83  -+100% on TX: PCM 1.100/1.520/1.950ms -> SBus raw values: 350/1024/1700 (100% ATV)
84  -+140% on TX: PCM 0.930/1.520/2.112ms -> SBus raw values: 78/1024/1964 (140% ATV)
85  -+152% on TX: PCM 0.884/1.520/2.160ms -> SBus raw values: 1/1024/2047 (140% ATV plus dirty tricks)
86 */
87 
88 /* define range mapping here, -+100% -> 1000..2000 */
89 #define SBUS_RANGE_MIN 200.0f
90 #define SBUS_RANGE_MAX 1800.0f
91 
92 #define SBUS_TARGET_MIN 1000.0f
93 #define SBUS_TARGET_MAX 2000.0f
94 
95 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
96 # include <stdio.h>
97 #endif
98 
99 /* pre-calculate the floating point stuff as far as possible at compile time */
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))
102 
105 
106 #define SBUS2_FRAME_SIZE_RX_VOLTAGE 3
107 #define SBUS2_FRAME_SIZE_GPS_DIGIT 3
108 
109 static enum SBUS2_DECODE_STATE {
119 
121 
122 static unsigned partial_frame_count;
123 static unsigned sbus1_frame_delay = (1000U * 1000U) / SBUS1_DEFAULT_RATE_HZ;
124 
125 static unsigned sbus_frame_drops;
126 
127 unsigned
129 {
130  return sbus_frame_drops;
131 }
132 
133 static bool
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);
136 
137 int
138 sbus_init(const char *device, bool singlewire)
139 {
140  int sbus_fd = open(device, O_RDWR | O_NONBLOCK);
141 
142  int ret = sbus_config(sbus_fd, singlewire);
143 
144  if (!ret) {
145  return sbus_fd;
146 
147  } else {
148  return -1;
149  }
150 }
151 
152 int
153 sbus_config(int sbus_fd, bool singlewire)
154 {
155 #if defined(__PX4_POSIX_OCPOC)
156  struct termios options;
157 
158  if (tcgetattr(sbus_fd, &options) != 0) {
159  return -1;
160  }
161 
162  tcflush(sbus_fd, TCIFLUSH);
163  bzero(&options, sizeof(options));
164 
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;
172 
173  options.c_cc[VTIME] = 0;
174  options.c_cc[VMIN] = 0;
175 
176  cfsetispeed(&options, B38400);
177  cfsetospeed(&options, B38400);
178 
179  tcflush(sbus_fd, TCIFLUSH);
180 
181  if ((tcsetattr(sbus_fd, TCSANOW, &options)) != 0) {
182  return -1;
183  }
184 
185  int baud = 100000;
186  struct serial_struct serials;
187 
188  if ((ioctl(sbus_fd, TIOCGSERIAL, &serials)) < 0) {
189  return -1;
190  }
191 
192  serials.flags = ASYNC_SPD_CUST;
193  serials.custom_divisor = serials.baud_base / baud;
194 
195  if ((ioctl(sbus_fd, TIOCSSERIAL, &serials)) < 0) {
196  return -1;
197  }
198 
199  ioctl(sbus_fd, TIOCGSERIAL, &serials);
200 
201  tcflush(sbus_fd, TCIFLUSH);
202  return 0;
203 #else
204  int ret = -1;
205 
206  if (sbus_fd >= 0) {
207  struct termios t;
208 
209  /* 100000bps, even parity, two stop bits */
210  tcgetattr(sbus_fd, &t);
211  cfsetspeed(&t, 100000);
212  t.c_cflag |= (CSTOPB | PARENB);
213  tcsetattr(sbus_fd, TCSANOW, &t);
214 
215  if (singlewire) {
216  /* only defined in configs capable of IOCTL
217  * Note It is never turned off
218  */
219 #ifdef TIOCSSINGLEWIRE
220  ioctl(sbus_fd, TIOCSSINGLEWIRE, SER_SINGLEWIRE_ENABLED);
221 #endif
222  }
223 
224  /* initialise the decoder */
227  sbus_frame_drops = 0;
228 
229  ret = 0;
230  }
231 
232  return ret;
233 #endif
234 }
235 
236 void
237 sbus1_output(int sbus_fd, uint16_t *values, uint16_t num_values)
238 {
239  uint8_t byteindex = 1; /*Data starts one byte into the sbus frame. */
240  uint8_t offset = 0;
241  uint16_t value;
242  hrt_abstime now;
243 
244  now = hrt_absolute_time();
245 
246  if ((now - last_txframe_time) > sbus1_frame_delay) {
247  last_txframe_time = now;
248  uint8_t oframe[SBUS_FRAME_SIZE] = { 0x0f };
249 
250  /* 16 is sbus number of servos/channels minus 2 single bit channels.
251  * currently ignoring single bit channels. */
252 
253  for (unsigned i = 0; (i < num_values) && (i < 16); ++i) {
254  value = (uint16_t)(((values[i] - SBUS_SCALE_OFFSET) / SBUS_SCALE_FACTOR) + .5f);
255 
256  /*protect from out of bounds values and limit to 11 bits*/
257  if (value > 0x07ff) {
258  value = 0x07ff;
259  }
260 
261  while (offset >= 8) {
262  ++byteindex;
263  offset -= 8;
264  }
265 
266  oframe[byteindex] |= (value << (offset)) & 0xff;
267  oframe[byteindex + 1] |= (value >> (8 - offset)) & 0xff;
268  oframe[byteindex + 2] |= (value >> (16 - offset)) & 0xff;
269  offset += 11;
270  }
271 
272  write(sbus_fd, oframe, SBUS_FRAME_SIZE);
273  }
274 }
275 void
276 sbus2_output(int sbus_fd, uint16_t *values, uint16_t num_values)
277 {
278  sbus1_output(sbus_fd, values, num_values);
279 }
280 
281 bool
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)
284 {
285  /*
286  * Fetch bytes, but no more than we would need to complete
287  * a complete frame.
288  */
289  uint8_t buf[SBUS_FRAME_SIZE * 2];
290 
291  int ret = read(sbus_fd, &buf[0], SBUS_FRAME_SIZE);
292 
293  /* if the read failed for any reason, just give up here */
294  if (ret < 1) {
295  return false;
296  }
297 
298  const hrt_abstime now = hrt_absolute_time();
299 #ifdef __PX4_NUTTX /* limit time-based hardening to RTOS's where we have reliable timing */
300 
301  /*
302  * The S.BUS protocol doesn't provide reliable framing,
303  * so we detect frame boundaries by the inter-frame delay.
304  *
305  * The minimum frame spacing is 7ms; with 25 bytes at 100000bps
306  * frame transmission time is ~2ms.
307  *
308  * We expect to only be called when bytes arrive for processing,
309  * and if an interval of more than 3ms passes between calls,
310  * the first byte we read will be the first byte of a frame.
311  *
312  * In the case where byte(s) are dropped from a frame, this also
313  * provides a degree of protection. Of course, it would be better
314  * if we didn't drop bytes...
315  */
316  if (now - last_rx_time > 3_ms) {
317  if (partial_frame_count > 0) {
320 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
321  printf("SBUS: RESET (TIME LIM)\n");
322 #endif
323  }
324  }
325 
326  if (partial_frame_count == 0 && buf[0] != SBUS_START_SYMBOL) {
327  /* don't bother going through the buffer if we don't get the
328  * expected start symbol as a first byte */
330  return false;
331  }
332 
333 #endif /* __PX4_NUTTX */
334 
335  /*
336  * Try to decode something with what we got
337  */
338  return sbus_parse(now, &buf[0], ret, values, num_values, sbus_failsafe,
339  sbus_frame_drop, &sbus_frame_drops, max_channels);
340 }
341 
342 bool
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)
345 {
346 
347  last_rx_time = now;
348 
349  /* this is set by the decoding state machine and will default to false
350  * once everything that was decodable has been decoded.
351  */
352  bool decode_ret = false;
353 
354  /* keep decoding until we have consumed the buffer */
355  for (unsigned d = 0; d < len; d++) {
356 
357  /* overflow check */
358  if (partial_frame_count == sizeof(sbus_frame) / sizeof(sbus_frame[0])) {
361 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
362  printf("SBUS2: RESET (BUF LIM)\n");
363 #endif
364  }
365 
369 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
370  printf("SBUS2: RESET (PACKET LIM)\n");
371 #endif
372  }
373 
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",
376  (sbus_decode_state == SBUS2_DECODE_STATE_DESYNC) ? "SBUS2_DECODE_STATE_DESYNC" : "",
377  (sbus_decode_state == SBUS2_DECODE_STATE_SBUS_START) ? "SBUS2_DECODE_STATE_SBUS_START" : "",
378  (sbus_decode_state == SBUS2_DECODE_STATE_SBUS1_SYNC) ? "SBUS2_DECODE_STATE_SBUS1_SYNC" : "",
379  (sbus_decode_state == SBUS2_DECODE_STATE_SBUS2_SYNC) ? "SBUS2_DECODE_STATE_SBUS2_SYNC" : "",
380  (sbus_decode_state == SBUS2_DECODE_STATE_SBUS2_RX_VOLTAGE) ? "SBUS2_DECODE_STATE_SBUS2_RX_VOLTAGE" : "",
381  (sbus_decode_state == SBUS2_DECODE_STATE_SBUS2_GPS) ? "SBUS2_DECODE_STATE_SBUS2_GPS" : "",
383  (unsigned)frame[d]);
384 #endif
385 
386  switch (sbus_decode_state) {
388 
389  /* we are de-synced and only interested in the frame marker */
390  if (frame[d] == SBUS_START_SYMBOL) {
393  sbus_frame[partial_frame_count++] = frame[d];
394  }
395 
396  break;
397 
398  /* fall through */
401 
402  /* fall through */
404  sbus_frame[partial_frame_count++] = frame[d];
405 
406  /* decode whatever we got and expect */
408  break;
409  }
410 
411  /*
412  * Great, it looks like we might have a frame. Go ahead and decode it.
413  */
414  decode_ret = sbus_decode(now, sbus_frame, values, num_values, sbus_failsafe, sbus_frame_drop, max_channels);
415 
416  /*
417  * Offset recovery: If decoding failed, check if there is a second
418  * start marker in the packet.
419  */
420  unsigned start_index = 0;
421 
422  if (!decode_ret && sbus_decode_state == SBUS2_DECODE_STATE_DESYNC) {
423 
424  for (unsigned i = 1; i < partial_frame_count; i++) {
425  if (sbus_frame[i] == SBUS_START_SYMBOL) {
426  start_index = i;
427  break;
428  }
429  }
430 
431  /* we found a second start marker */
432  if (start_index != 0) {
433  /* shift everything in the buffer and reset the state machine */
434  for (unsigned i = 0; i < partial_frame_count - start_index; i++) {
435  sbus_frame[i] = sbus_frame[i + start_index];
436  }
437 
438  partial_frame_count -= start_index;
440 
441 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
442  printf("DECODE RECOVERY: %d\n", start_index);
443 #endif
444  }
445  }
446 
447  /* if there has been no successful attempt at saving a failed
448  * decoding run, reset the frame count for successful and
449  * unsuccessful decode runs.
450  */
451  if (start_index == 0) {
453  }
454 
455  }
456  break;
457 
459  sbus_frame[partial_frame_count++] = frame[d];
460 
462  /* this slot is unused and in fact S.BUS2 sync */
464  }
465 
467  break;
468  }
469 
470  /* find out which payload we're dealing with in this slot */
471  switch (sbus_frame[0]) {
472  case 0x03: {
473  // Observed values:
474  // (frame[0] == 0x3 && frame[1] == 0x84 && frame[2] == 0x0)
475  // (frame[0] == 0x3 && frame[1] == 0xc4 && frame[2] == 0x0)
476  // (frame[0] == 0x3 && frame[1] == 0x80 && frame[2] == 0x2f)
477  // (frame[0] == 0x3 && frame[1] == 0xc0 && frame[2] == 0x2f)
478 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 2
479  uint16_t rx_voltage = (sbus_frame[1] << 8) | sbus_frame[2];
480  printf("rx_voltage %d\n", (int)rx_voltage);
481 #endif
482  }
483 
485  break;
486 
487  default:
488  /* this is not what we expect it to be, go back to sync */
491  }
492 
493  }
494  break;
495 
497  sbus_frame[partial_frame_count++] = frame[d];
498 
500  /* this slot is unused and in fact S.BUS2 sync */
502  }
503 
504  if (partial_frame_count < 24) {
505  break;
506  }
507 
508  /* find out which payload we're dealing with in this slot */
509  switch (sbus_frame[0]) {
510  case 0x13: {
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);
514 #endif
515  }
516 
518  break;
519 
520  default:
521  /* this is not what we expect it to be, go back to sync */
524  /* throw unknown bytes away */
525  }
526  }
527  break;
528 
529  default:
530 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
531  printf("UNKNOWN PROTO STATE");
532 #endif
533  decode_ret = false;
534  }
535 
536 
537  }
538 
539  if (frame_drops) {
540  *frame_drops = sbus_frame_drops;
541  }
542 
543  /* return false as default */
544  return decode_ret;
545 }
546 
547 /*
548  * S.bus decoder matrix.
549  *
550  * Each channel value can come from up to 3 input bytes. Each row in the
551  * matrix describes up to three bytes, and each entry gives:
552  *
553  * - byte offset in the data portion of the frame
554  * - right shift applied to the data byte
555  * - mask for the data byte
556  * - left shift applied to the result into the channel value
557  */
559  uint8_t byte;
560  uint8_t rshift;
561  uint8_t mask;
562  uint8_t lshift;
563 };
564 static const struct sbus_bit_pick sbus_decoder[SBUS_INPUT_CHANNELS][3] = {
565  /* 0 */ { { 0, 0, 0xff, 0}, { 1, 0, 0x07, 8}, { 0, 0, 0x00, 0} },
566  /* 1 */ { { 1, 3, 0x1f, 0}, { 2, 0, 0x3f, 5}, { 0, 0, 0x00, 0} },
567  /* 2 */ { { 2, 6, 0x03, 0}, { 3, 0, 0xff, 2}, { 4, 0, 0x01, 10} },
568  /* 3 */ { { 4, 1, 0x7f, 0}, { 5, 0, 0x0f, 7}, { 0, 0, 0x00, 0} },
569  /* 4 */ { { 5, 4, 0x0f, 0}, { 6, 0, 0x7f, 4}, { 0, 0, 0x00, 0} },
570  /* 5 */ { { 6, 7, 0x01, 0}, { 7, 0, 0xff, 1}, { 8, 0, 0x03, 9} },
571  /* 6 */ { { 8, 2, 0x3f, 0}, { 9, 0, 0x1f, 6}, { 0, 0, 0x00, 0} },
572  /* 7 */ { { 9, 5, 0x07, 0}, {10, 0, 0xff, 3}, { 0, 0, 0x00, 0} },
573  /* 8 */ { {11, 0, 0xff, 0}, {12, 0, 0x07, 8}, { 0, 0, 0x00, 0} },
574  /* 9 */ { {12, 3, 0x1f, 0}, {13, 0, 0x3f, 5}, { 0, 0, 0x00, 0} },
575  /* 10 */ { {13, 6, 0x03, 0}, {14, 0, 0xff, 2}, {15, 0, 0x01, 10} },
576  /* 11 */ { {15, 1, 0x7f, 0}, {16, 0, 0x0f, 7}, { 0, 0, 0x00, 0} },
577  /* 12 */ { {16, 4, 0x0f, 0}, {17, 0, 0x7f, 4}, { 0, 0, 0x00, 0} },
578  /* 13 */ { {17, 7, 0x01, 0}, {18, 0, 0xff, 1}, {19, 0, 0x03, 9} },
579  /* 14 */ { {19, 2, 0x3f, 0}, {20, 0, 0x1f, 6}, { 0, 0, 0x00, 0} },
580  /* 15 */ { {20, 5, 0x07, 0}, {21, 0, 0xff, 3}, { 0, 0, 0x00, 0} }
581 };
582 
583 bool
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)
586 {
587 
588  /* check frame boundary markers to avoid out-of-sync cases */
589  if (frame[0] != SBUS_START_SYMBOL) {
591 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
592  printf("DECODE FAIL: ");
593 
594  for (unsigned i = 0; i < SBUS_FRAME_SIZE; i++) {
595  printf("%0x ", frame[i]);
596  }
597 
598  printf("\n");
599 #endif
601  return false;
602  }
603 
604  /* the last byte in the frame indicates what frame will follow after this one */
605  switch (frame[24]) {
606  case 0x00:
607  /* this is S.BUS 1 */
609  break;
610 
611  case 0x04:
612  /* receiver voltage */
614  break;
615 
616  case 0x14:
617  /* GPS / baro */
619  break;
620 
621  case 0x24:
622  /* Unknown SBUS2 data */
624  break;
625 
626  case 0x34:
627  /* Unknown SBUS2 data */
629  break;
630 
631  default:
632 #if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
633  printf("DECODE FAIL: END MARKER\n");
634 #endif
636  return false;
637  }
638 
639  /* we have received something we think is a frame */
640  unsigned chancount = (max_values > SBUS_INPUT_CHANNELS) ?
641  SBUS_INPUT_CHANNELS : max_values;
642 
643  /* use the decoder matrix to extract channel data */
644  for (unsigned channel = 0; channel < chancount; channel++) {
645  unsigned value = 0;
646 
647  for (unsigned pick = 0; pick < 3; pick++) {
648  const struct sbus_bit_pick *decode = &sbus_decoder[channel][pick];
649 
650  if (decode->mask != 0) {
651  unsigned piece = frame[1 + decode->byte];
652  piece >>= decode->rshift;
653  piece &= decode->mask;
654  piece <<= decode->lshift;
655 
656  value |= piece;
657  }
658  }
659 
660 
661  /* convert 0-2048 values to 1000-2000 ppm encoding in a not too sloppy fashion */
662  values[channel] = (uint16_t)(value * SBUS_SCALE_FACTOR + .5f) + SBUS_SCALE_OFFSET;
663  }
664 
665  /* decode switch channels if data fields are wide enough */
666  if (max_values > 17 && chancount > 15) {
667  chancount = 18;
668 
669  /* channel 17 (index 16) */
670  values[16] = ((frame[SBUS_FLAGS_BYTE] & (1 << 0)) ? 1000 : 0) + 998;
671  /* channel 18 (index 17) */
672  values[17] = ((frame[SBUS_FLAGS_BYTE] & (1 << 1)) ? 1000 : 0) + 998;
673  }
674 
675  /* note the number of channels decoded */
676  *num_values = chancount;
677 
678  /* decode and handle failsafe and frame-lost flags */
679  if (frame[SBUS_FLAGS_BYTE] & (1 << SBUS_FAILSAFE_BIT)) { /* failsafe */
680  /* report that we failed to read anything valid off the receiver */
681  *sbus_failsafe = true;
682  *sbus_frame_drop = true;
683 
684  } else if (frame[SBUS_FLAGS_BYTE] & (1 << SBUS_FRAMELOST_BIT)) { /* a frame was lost */
685  /* set a special warning flag
686  *
687  * Attention! This flag indicates a skipped frame only, not a total link loss! Handling this
688  * condition as fail-safe greatly reduces the reliability and range of the radio link,
689  * e.g. by prematurely issuing return-to-launch!!! */
690 
691  *sbus_failsafe = false;
692  *sbus_frame_drop = true;
693 
694  } else {
695  *sbus_failsafe = false;
696  *sbus_frame_drop = false;
697  }
698 
699  return true;
700 }
701 
702 /*
703  set output rate of SBUS in Hz
704  */
705 void sbus1_set_output_rate_hz(uint16_t rate_hz)
706 {
707  if (rate_hz > SBUS1_MAX_RATE_HZ) {
708  rate_hz = SBUS1_MAX_RATE_HZ;
709  }
710 
711  if (rate_hz < SBUS1_MIN_RATE_HZ) {
712  rate_hz = SBUS1_MIN_RATE_HZ;
713  }
714 
715  sbus1_frame_delay = (1000U * 1000U) / rate_hz;
716 }
static unsigned partial_frame_count
Definition: sbus.cpp:122
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)
Definition: sbus.cpp:584
uint8_t byte
Definition: sbus.cpp:559
#define SBUS_FLAGS_BYTE
Definition: sbus.cpp:67
#define SBUS2_FRAME_SIZE_RX_VOLTAGE
Definition: sbus.cpp:106
#define SBUS_START_SYMBOL
Definition: sbus.cpp:64
sbus_frame_t sbus_frame
Definition: common_rc.h:17
#define SBUS_FRAME_SIZE
Definition: sbus.h:49
Namespace encapsulating all device framework classes, functions and data.
Definition: CDev.cpp:47
High-resolution timer with callouts and timekeeping.
__EXPORT rc_decode_buf_t rc_decode_buf
Definition: common_rc.cpp:4
#define SBUS1_MIN_RATE_HZ
Definition: sbus.cpp:76
unsigned sbus_dropped_frames()
The number of incomplete frames we encountered.
Definition: sbus.cpp:128
static void read(bootloader_app_shared_t *pshared)
static hrt_abstime last_rx_time
Definition: sbus.cpp:103
#define SBUS_FAILSAFE_BIT
Definition: sbus.cpp:68
uint8_t rshift
Definition: sbus.cpp:560
#define SBUS_SCALE_FACTOR
Definition: sbus.cpp:100
#define SBUS1_DEFAULT_RATE_HZ
Definition: sbus.cpp:79
#define SBUS_FRAMELOST_BIT
Definition: sbus.cpp:69
static enum SBUS2_DECODE_STATE sbus_decode_state
uint8_t mask
Definition: sbus.cpp:561
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
static const struct sbus_bit_pick sbus_decoder[SBUS_INPUT_CHANNELS][3]
Definition: sbus.cpp:564
static unsigned sbus_frame_drops
Definition: sbus.cpp:125
int sbus_init(const char *device, bool singlewire)
Definition: sbus.cpp:138
static unsigned sbus1_frame_delay
Definition: sbus.cpp:123
static void write(bootloader_app_shared_t *pshared)
SBUS2_DECODE_STATE
Definition: sbus.cpp:109
void sbus2_output(int sbus_fd, uint16_t *values, uint16_t num_values)
Definition: sbus.cpp:276
#define SBUS_INPUT_CHANNELS
Definition: sbus.cpp:66
uint8_t sbus_frame_t[SBUS_FRAME_SIZE+(SBUS_FRAME_SIZE/2)]
Definition: sbus.h:52
#define SBUS1_MAX_RATE_HZ
Definition: sbus.cpp:75
RC protocol definition for S.BUS.
void sbus1_set_output_rate_hz(uint16_t rate_hz)
Definition: sbus.cpp:705
void sbus1_output(int sbus_fd, uint16_t *values, uint16_t num_values)
Definition: sbus.cpp:237
#define SBUS_SCALE_OFFSET
Definition: sbus.cpp:101
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)
Definition: sbus.cpp:343
static sbus_frame_t & sbus_frame
Definition: sbus.cpp:120
uint8_t lshift
Definition: sbus.cpp:562
bool sbus_input(int sbus_fd, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop, uint16_t max_channels)
Definition: sbus.cpp:282
static void decode(bson_decoder_t decoder)
Definition: test_bson.cpp:252
__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.
Definition: sbus.cpp:153
static hrt_abstime last_txframe_time
Definition: sbus.cpp:104