5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
24 #define SBUS_FRAME_GAP_DELAY 1000 // 500uS
26 #define SBUS_START_BYTE 0x0F
27 #define SBUS_END_BYTE 0x00
28 #define SBUS_FLAGS_IDX 23
29 #define SBUS_FRAMELOST_BIT 2
30 #define SBUS_FAILSAFE_BIT 3
32 #define SBUS_CH_BITS 11
33 #define SBUS_CH_MASK ((1<<SBUS_CH_BITS)-1)
35 #define SBUS_CH_CENTER 0x3E0
38 // Range for pulses (ppm input) is [-512:+512]
39 void processSbusFrame(uint8_t * sbus
, int16_t * pulses
, uint32_t size
)
41 if (size
!= SBUS_FRAME_SIZE
|| sbus
[0] != SBUS_START_BYTE
|| sbus
[SBUS_FRAME_SIZE
-1] != SBUS_END_BYTE
) {
42 return; // not a valid SBUS frame
44 if ((sbus
[SBUS_FLAGS_IDX
] & (1<<SBUS_FAILSAFE_BIT
)) || (sbus
[SBUS_FLAGS_IDX
] & (1<<SBUS_FRAMELOST_BIT
))) {
45 return; // SBUS invalid frame or failsafe mode
48 sbus
++; // skip start byte
50 uint32_t inputbitsavailable
= 0;
51 uint32_t inputbits
= 0;
52 for (uint32_t i
=0; i
<MAX_TRAINER_CHANNELS
; i
++) {
53 while (inputbitsavailable
< SBUS_CH_BITS
) {
54 inputbits
|= *sbus
++ << inputbitsavailable
;
55 inputbitsavailable
+= 8;
57 *pulses
++ = ((int32_t) (inputbits
& SBUS_CH_MASK
) - SBUS_CH_CENTER
) * 5 / 8;
58 inputbitsavailable
-= SBUS_CH_BITS
;
59 inputbits
>>= SBUS_CH_BITS
;
62 ppmInputValidityTimer
= PPM_IN_VALID_TIMEOUT
;
65 void processSbusInput()
70 static uint8_t SbusIndex
= 0;
71 static uint16_t SbusTimer
;
72 static uint8_t SbusFrame
[SBUS_FRAME_SIZE
];
74 while (sbusGetByte(&rxchar
)) {
76 if (SbusIndex
> SBUS_FRAME_SIZE
-1) {
77 SbusIndex
= SBUS_FRAME_SIZE
-1;
79 SbusFrame
[SbusIndex
++] = rxchar
;
82 SbusTimer
= getTmr2MHz();
87 if ((uint16_t) (getTmr2MHz() - SbusTimer
) > SBUS_FRAME_GAP_DELAY
) {
88 processSbusFrame(SbusFrame
, ppmInput
, SbusIndex
);