Skip to content

Commit 84a590f

Browse files
committed
Add Spektrum satellite serial protocol
1 parent bc16587 commit 84a590f

File tree

7 files changed

+195
-3
lines changed

7 files changed

+195
-3
lines changed

src/include/common.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ enum eSerialProtocol : uint8_t
188188
PROTOCOL_SUMD,
189189
PROTOCOL_DJI_RS_PRO,
190190
PROTOCOL_HOTT_TLM
191+
PROTOCOL_SPEKTRUM_SATELLITE,
191192
};
192193

193194
enum eFailsafeMode : uint8_t
@@ -197,6 +198,14 @@ enum eFailsafeMode : uint8_t
197198
FAILSAFE_SET_POSITION
198199
};
199200

201+
enum eSatelliteSystem : uint8_t
202+
{
203+
DSMX_11MS,
204+
DSMX_22MS,
205+
DSM2_11MS,
206+
DSM2_22MS,
207+
};
208+
200209
#ifndef UNIT_TEST
201210
#if defined(RADIO_SX127X)
202211
#define RATE_MAX 6

src/lib/CONFIG/config.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,4 +1038,13 @@ void RxConfig::SetFailsafeMode(eFailsafeMode failsafeMode)
10381038
m_modified = true;
10391039
}
10401040
}
1041+
1042+
void RxConfig::SetSatelliteSystem(eSatelliteSystem satelliteSystem)
1043+
{
1044+
if (m_config.satelliteSystem != satelliteSystem)
1045+
{
1046+
m_config.satelliteSystem = satelliteSystem;
1047+
m_modified = true;
1048+
}
1049+
}
10411050
#endif

src/lib/CONFIG/config.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ typedef struct {
207207
uint8_t modelId;
208208
uint8_t serialProtocol:4,
209209
failsafeMode:2,
210-
unused:2;
210+
satelliteSystem:2;
211211
rx_config_pwm_t pwmChannels[PWM_MAX_CHANNELS];
212212
} rx_config_t;
213213

@@ -236,6 +236,7 @@ class RxConfig
236236
uint8_t GetRateInitialIdx() const { return m_config.rateInitialIdx; }
237237
eSerialProtocol GetSerialProtocol() const { return (eSerialProtocol)m_config.serialProtocol; }
238238
eFailsafeMode GetFailsafeMode() const { return (eFailsafeMode)m_config.failsafeMode; }
239+
eSatelliteSystem GetSatelliteSystem() const {return (eSatelliteSystem)m_config.satelliteSystem; }
239240

240241
// Setters
241242
void SetIsBound(bool isBound);
@@ -256,6 +257,7 @@ class RxConfig
256257
void SetRateInitialIdx(uint8_t rateInitialIdx);
257258
void SetSerialProtocol(eSerialProtocol serialProtocol);
258259
void SetFailsafeMode(eFailsafeMode failsafeMode);
260+
void SetSatelliteSystem(eSatelliteSystem satelliteSystem);
259261

260262
private:
261263
void UpgradeEepromV4();

src/lib/LUA/rx_devLUA.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@ static const char *rxModes = "50Hz;60Hz;100Hz;160Hz;333Hz;400Hz;10kHzDuty;On/Off
1818
static struct luaItem_selection luaSerialProtocol = {
1919
{"Protocol", CRSF_TEXT_SELECTION},
2020
0, // value
21-
"CRSF;Inverted CRSF;SBUS;Inverted SBUS;SUMD;DJI RS Pro;HoTT Telemetry",
21+
"CRSF;Inverted CRSF;SBUS;Inverted SBUS;SUMD;DJI RS Pro;HoTT Telemetry,Spektrum Satellite",
22+
STR_EMPTYSPACE
23+
};
24+
25+
static struct luaItem_selection luaSatelliteSystem = {
26+
{"Satellite System", CRSF_TEXT_SELECTION},
27+
0, // value
28+
"DSMX 11MS;DSMX 22MS;DSM2 11MS;DSM2 22MS",
2229
STR_EMPTYSPACE
2330
};
2431

@@ -312,7 +319,17 @@ static void registerLuaParameters()
312319
}
313320
});
314321

315-
if (config.GetSerialProtocol() == PROTOCOL_SBUS || config.GetSerialProtocol() == PROTOCOL_INVERTED_SBUS || config.GetSerialProtocol() == PROTOCOL_DJI_RS_PRO)
322+
if (config.GetSerialProtocol() == PROTOCOL_SPEKTRUM_SATELLITE)
323+
{
324+
registerLUAParameter(&luaSatelliteSystem, [](struct luaPropertiesCommon* item, uint8_t arg){
325+
config.SetSatelliteSystem((eSatelliteSystem)arg);
326+
});
327+
}
328+
329+
if (config.GetSerialProtocol() == PROTOCOL_SBUS ||
330+
config.GetSerialProtocol() == PROTOCOL_INVERTED_SBUS ||
331+
config.GetSerialProtocol() == PROTOCOL_DJI_RS_PRO ||
332+
config.GetSerialProtocol() == PROTOCOL_SPEKTRUM_SATELLITE)
316333
{
317334
registerLUAParameter(&luaFailsafeMode, [](struct luaPropertiesCommon* item, uint8_t arg){
318335
config.SetFailsafeMode((eFailsafeMode)arg);

src/src/rx-serial/SerialSatellite.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include "SerialSatellite.h"
2+
#include "CRSF.h"
3+
#include "config.h"
4+
#include "device.h"
5+
6+
#if defined(TARGET_RX)
7+
8+
extern RxConfig config;
9+
10+
static uint16_t crsfToSatellite(uint16_t crsfValue, uint8_t satelliteChannel, eSatelliteSystem protocol)
11+
{
12+
static constexpr uint16_t SATELLITE_MIN_US = 903;
13+
static constexpr uint16_t SATELLITE_MAX_US = 2097;
14+
15+
// Map the channel data
16+
const uint16_t us = constrain(CRSF_to_US(crsfValue), SATELLITE_MIN_US, SATELLITE_MAX_US);
17+
const float divisor = (protocol == DSM2_22MS) ? 1.166f
18+
: 0.583f;
19+
20+
uint16_t channelValue = roundf((us - SATELLITE_MIN_US) / divisor);
21+
22+
// Encode the channel information
23+
channelValue |= satelliteChannel << ((protocol == DSM2_22MS) ? 10 : 11);
24+
25+
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
26+
return __builtin_bswap16(channelValue);
27+
#else
28+
return channelValue;
29+
#endif // __BYTE_ORDER__
30+
}
31+
32+
uint32_t SerialSatellite::sendRCFrame(bool frameAvailable, uint32_t *channelData)
33+
{
34+
const eSatelliteSystem satelliteSystem = config.GetSatelliteSystem();
35+
const uint32_t callbackIntervalMs =
36+
((satelliteSystem == DSMX_11MS) || (satelliteSystem == DSM2_11MS)) ? 11 : 22;
37+
38+
if ((failsafe && config.GetFailsafeMode() == FAILSAFE_NO_PULSES) || (!sendPackets && connectionState != connected))
39+
{
40+
// Fade count does not overflow
41+
if (sendPackets && (fadeCount < UINT8_MAX))
42+
{
43+
++fadeCount;
44+
}
45+
return callbackIntervalMs;
46+
}
47+
sendPackets = true;
48+
49+
uint16_t outgoingPacket[SATELLITE_CHANNEL_DATA_LENGTH];
50+
for (uint8_t ii = 0; ii < SATELLITE_CHANNEL_DATA_LENGTH; ++ii)
51+
{
52+
// These channels are sent in every packet
53+
if (ii < SATELLITE_FIRST_RR_CHANNEL)
54+
{
55+
outgoingPacket[ii] = crsfToSatellite(channelData[ii],
56+
crsfToSatelliteChannelMap[ii],
57+
satelliteSystem);
58+
}
59+
// Round-robin channels
60+
else
61+
{
62+
outgoingPacket[ii] = crsfToSatellite(channelData[rr],
63+
crsfToSatelliteChannelMap[rr],
64+
satelliteSystem);
65+
66+
// Update the round-robin index
67+
++rr;
68+
if (rr >= SATELLITE_NUM_CHANNELS)
69+
{
70+
rr = SATELLITE_FIRST_RR_CHANNEL;
71+
}
72+
}
73+
}
74+
75+
uint8_t satelliteSystemValue{};
76+
switch (satelliteSystem)
77+
{
78+
case DSMX_11MS:
79+
satelliteSystemValue = 0xB2;
80+
break;
81+
case DSMX_22MS:
82+
satelliteSystemValue = 0xA2;
83+
break;
84+
case DSM2_11MS:
85+
satelliteSystemValue = 0x12;
86+
break;
87+
default:
88+
satelliteSystemValue = 0x01;
89+
}
90+
91+
// Transmit the fade count
92+
_outputPort->write(fadeCount);
93+
// Transmit the protocol in use
94+
_outputPort->write(satelliteSystemValue);
95+
// Transmit the channel data
96+
_outputPort->write(reinterpret_cast<uint8_t *>(outgoingPacket), sizeof(outgoingPacket)); // Channel data
97+
98+
return callbackIntervalMs;
99+
}
100+
101+
#endif // defined(TARGET_RX)

src/src/rx-serial/SerialSatellite.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "SerialIO.h"
2+
3+
class SerialSatellite : public SerialIO
4+
{
5+
public:
6+
SerialSatellite(Stream &out, Stream &in)
7+
: SerialIO(&out, &in) {}
8+
9+
virtual ~SerialSatellite() = default;
10+
11+
void queueLinkStatisticsPacket() override {}
12+
void queueMSPFrameTransmission(uint8_t *data) override {}
13+
uint32_t sendRCFrame(bool frameAvailable, uint32_t *channelData) override;
14+
15+
private:
16+
static constexpr uint16_t SATELLITE_NUM_CHANNELS = 12;
17+
static constexpr uint8_t SATELLITE_FIRST_RR_CHANNEL = 4;
18+
static constexpr uint8_t SATELLITE_CHANNEL_DATA_LENGTH = 7;
19+
20+
void processBytes(uint8_t *bytes, uint16_t size) override{};
21+
22+
static constexpr uint8_t crsfToSatelliteChannelMap[12] = {
23+
// clang-format off
24+
// CRSF // Satellite
25+
/*Channel 0*/ 1,
26+
/*Channel 1*/ 2,
27+
/*Channel 2*/ 0,
28+
/*Channel 3*/ 3,
29+
/*Channel 4*/ 11,
30+
/*Channel 5*/ 4,
31+
/*Channel 6*/ 5,
32+
/*Channel 7*/ 6,
33+
/*Channel 8*/ 7,
34+
/*Channel 9*/ 8,
35+
/*Channel 10*/ 9,
36+
/*Channel 11*/ 10,
37+
// clang-format on
38+
};
39+
40+
uint8_t fadeCount{0};
41+
uint8_t rr{SATELLITE_FIRST_RR_CHANNEL};
42+
bool sendPackets{false};
43+
};

src/src/rx_main.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "rx-serial/SerialSUMD.h"
2424
#include "rx-serial/SerialAirPort.h"
2525
#include "rx-serial/SerialHoTT_TLM.h"
26+
#include "rx-serial/SerialSatellite.h"
2627

2728
#include "rx-serial/devSerialIO.h"
2829
#include "devLED.h"
@@ -1168,6 +1169,7 @@ static void setupSerial()
11681169
{
11691170
bool sbusSerialOutput = false;
11701171
bool sumdSerialOutput = false;
1172+
bool spektrumSatelliteSerialOutput = false;
11711173

11721174
#if defined(PLATFORM_ESP8266) || defined(PLATFORM_ESP32)
11731175
bool hottTlmSerial = false;
@@ -1209,6 +1211,11 @@ static void setupSerial()
12091211
serialBaud = 19200;
12101212
}
12111213
#endif
1214+
else if (config.GetSerialProtocol() == PROTOCOL_SPEKTRUM_SATELLITE)
1215+
{
1216+
spektrumSatelliteSerialOutput = true;
1217+
serialBaud = 115200;
1218+
}
12121219
bool invert = config.GetSerialProtocol() == PROTOCOL_SBUS || config.GetSerialProtocol() == PROTOCOL_INVERTED_CRSF || config.GetSerialProtocol() == PROTOCOL_DJI_RS_PRO;
12131220

12141221
#ifdef PLATFORM_STM32
@@ -1309,6 +1316,10 @@ static void setupSerial()
13091316
serialIO = new SerialHoTT_TLM(SERIAL_PROTOCOL_TX, SERIAL_PROTOCOL_RX);
13101317
}
13111318
#endif
1319+
else if (spektrumSatelliteSerialOutput)
1320+
{
1321+
serialIO = new SerialSatellite(SERIAL_PROTOCOL_TX, SERIAL_PROTOCOL_RX);
1322+
}
13121323
else
13131324
{
13141325
serialIO = new SerialCRSF(SERIAL_PROTOCOL_TX, SERIAL_PROTOCOL_RX);

0 commit comments

Comments
 (0)