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
37 // Range for pulses (ppm input) is [-512:+512]
38 void processSbusFrame(uint8_t * sbus
, int16_t * pulses
, uint32_t size
)
40 if (size
!= SBUS_FRAME_SIZE
|| sbus
[0] != SBUS_START_BYTE
|| sbus
[SBUS_FRAME_SIZE
-1] != SBUS_END_BYTE
) {
41 return; // not a valid SBUS frame
43 if ((sbus
[SBUS_FLAGS_IDX
] & (1<<SBUS_FAILSAFE_BIT
)) || (sbus
[SBUS_FLAGS_IDX
] & (1<<SBUS_FRAMELOST_BIT
))) {
44 return; // SBUS invalid frame or failsafe mode
47 sbus
++; // skip start byte
49 uint32_t inputbitsavailable
= 0;
50 uint32_t inputbits
= 0;
51 for (uint32_t i
=0; i
<MAX_TRAINER_CHANNELS
; i
++) {
52 while (inputbitsavailable
< SBUS_CH_BITS
) {
53 inputbits
|= *sbus
++ << inputbitsavailable
;
54 inputbitsavailable
+= 8;
56 *pulses
++ = ((int32_t) (inputbits
& SBUS_CH_MASK
) - SBUS_CH_CENTER
) * 5 / 8;
57 inputbitsavailable
-= SBUS_CH_BITS
;
58 inputbits
>>= SBUS_CH_BITS
;
61 ppmInputValidityTimer
= PPM_IN_VALID_TIMEOUT
;
64 void processSbusInput()
69 static uint8_t SbusIndex
= 0;
70 static uint16_t SbusTimer
;
71 static uint8_t SbusFrame
[SBUS_FRAME_SIZE
];
73 while (sbusGetByte(&rxchar
)) {
75 if (SbusIndex
> SBUS_FRAME_SIZE
-1) {
76 SbusIndex
= SBUS_FRAME_SIZE
-1;
78 SbusFrame
[SbusIndex
++] = rxchar
;
81 SbusTimer
= getTmr2MHz();
86 if ((uint16_t) (getTmr2MHz() - SbusTimer
) > SBUS_FRAME_GAP_DELAY
) {
87 processSbusFrame(SbusFrame
, ppmInput
, SbusIndex
);