rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
sbus.h File Reference

Futaba S.BUS: sixteen channels in twenty-five bytes. More...

#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  sbus_frame_t
 One decoded S.BUS frame. More...
struct  sbus_decoder_t
 Decoder state for one S.BUS byte stream. More...

Macros

#define SBUS_FRAME_BYTES   25u
 Frame layout: byte count, header byte and channel count.
#define SBUS_HEADER   0x0Fu
#define SBUS_CHANNELS   16u
#define SBUS_RAW_MIN   0u
 Raw channel range: eleven bits.
#define SBUS_RAW_MAX   2047u
#define SBUS_RAW_1000US   172u
 The two ends of the range a transmitter at its endpoints actually sends, and what they mean in microseconds.
#define SBUS_RAW_2000US   1811u
#define SBUS_GAP_US   2000u
 Silence that means a frame boundary.
#define SBUS_FLAG_CH17   0x01u
 Flag bits in byte 23.
#define SBUS_FLAG_CH18   0x02u
#define SBUS_FLAG_FRAME_LOST   0x04u
#define SBUS_FLAG_FAILSAFE   0x08u

Functions

void sbus_decoder_reset (sbus_decoder_t *d)
 Clear a decoder, including its diagnostic counters.
bool sbus_decode_byte (sbus_decoder_t *d, uint8_t byte, uint32_t now_us, sbus_frame_t *out)
 Feed one byte with the time it arrived; true when out holds a frame.
uint16_t sbus_to_us (uint16_t raw)
 Microseconds for a raw channel value, clamped to a sane pulse.

Detailed Description

Futaba S.BUS: sixteen channels in twenty-five bytes.

Implements the S.BUS receiver protocol of Futaba. Futaba and S.BUS are names or trademarks of their respective owners; they are used here only to say which receivers this module works with (NOTICE, "Trademarks").

The wire is an inverted 8E2 UART (universal asynchronous receiver-transmitter) at 100 kbaud, produced by the IOmcu's PIO (programmable input/output); this file decodes the bytes.

S.BUS has no checksum and no escaping. A frame is a header byte, a bit-packed payload and a footer, and the header value 0x0F is an ordinary value inside channel data, so the header alone cannot locate a frame start: a decoder that trusts it locks onto the middle of a frame and reports sixteen plausible channels that are all wrong.

The frame boundary is the gap. Frames arrive every 7ms or 14ms and take 3ms to send, so there are at least 4ms of silence between them, against 120 microseconds between bytes within one. The decoder is fed a timestamp per byte and frames on that gap; the header and footer confirm.

Two flags outrank the channels. failsafe means the receiver has lost the transmitter and is generating the values it sends; frame lost means this frame did not arrive intact. Anything driven from S.BUS input treats failsafe as a stop, not as sixteen valid channels.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ SBUS_CHANNELS

#define SBUS_CHANNELS   16u

channels per frame

◆ SBUS_FLAG_CH17

#define SBUS_FLAG_CH17   0x01u

Flag bits in byte 23.

digital channel 17

◆ SBUS_FLAG_CH18

#define SBUS_FLAG_CH18   0x02u

digital channel 18

◆ SBUS_FLAG_FAILSAFE

#define SBUS_FLAG_FAILSAFE   0x08u

receiver is in failsafe

◆ SBUS_FLAG_FRAME_LOST

#define SBUS_FLAG_FRAME_LOST   0x04u

frame did not arrive intact

◆ SBUS_FRAME_BYTES

#define SBUS_FRAME_BYTES   25u

Frame layout: byte count, header byte and channel count.

bytes per frame, header to footer

◆ SBUS_GAP_US

#define SBUS_GAP_US   2000u

Silence that means a frame boundary.

Bytes within a frame are 120 microseconds apart at 100 kbaud 8E2; frames are at least 4ms apart. Two milliseconds sits clear of both, so it cannot split a frame and cannot join two.

◆ SBUS_HEADER

#define SBUS_HEADER   0x0Fu

first byte of every frame

◆ SBUS_RAW_1000US

#define SBUS_RAW_1000US   172u

The two ends of the range a transmitter at its endpoints actually sends, and what they mean in microseconds.

Not the raw limits: 172 and 1811 are what the protocol settled on, and a receiver can send outside them. raw value of a 1000us pulse

◆ SBUS_RAW_2000US

#define SBUS_RAW_2000US   1811u

raw value of a 2000us pulse

Function Documentation

◆ sbus_decode_byte()

bool sbus_decode_byte ( sbus_decoder_t * d,
uint8_t byte,
uint32_t now_us,
sbus_frame_t * out )

Feed one byte with the time it arrived; true when out holds a frame.

now_us paces the framing. A gap of SBUS_GAP_US or more starts a new frame, whatever was half-collected before it; the gap is the only reliable boundary this protocol has.

Parameters
dDecoder state. NULL returns false.
byteReceived byte.
now_usArrival time of the byte, in us.
outReceives the frame; may be NULL.
Returns
true when a frame with a valid footer completes.

◆ sbus_decoder_reset()

void sbus_decoder_reset ( sbus_decoder_t * d)

Clear a decoder, including its diagnostic counters.

Parameters
dDecoder to clear. NULL is ignored.

◆ sbus_to_us()

uint16_t sbus_to_us ( uint16_t raw)

Microseconds for a raw channel value, clamped to a sane pulse.

Parameters
rawRaw channel value.
Returns
Pulse width in us, clamped to 800 to 2200.