mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 16:25:31 +03:00
Merge pull request #9960 from phobos-/f4-dsmx
Spektrum SPI protocol improvements
This commit is contained in:
commit
4abc447ffe
6 changed files with 135 additions and 87 deletions
|
@ -104,6 +104,8 @@ static const uint8_t pnCodes[5][9][8] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const uint8_t bindDataCode[16] = {0x98, 0x88, 0x1B, 0xE4, 0x30, 0x79, 0x03, 0x84, 0x98, 0x88, 0x1B, 0xE4, 0x30, 0x79, 0x03, 0x84};
|
||||
|
||||
static const uint8_t cyrf6936Config[][2] = {
|
||||
{CYRF6936_CLK_EN, CYRF6936_RXF}, // Enable the clock
|
||||
{CYRF6936_AUTO_CAL_TIME, 0x3C}, // From manual, needed for initialization
|
||||
|
@ -132,24 +134,26 @@ static const uint8_t cyrf6936TransferConfig[][2] = {
|
|||
typedef enum {
|
||||
DSM2_22 = 0x01,
|
||||
DSM2_11 = 0x02,
|
||||
DSM2_11_DX6 = 0x03,
|
||||
DSM2_11_DX8 = 0x12,
|
||||
DSMX_22 = 0xA2,
|
||||
DSMX_11 = 0xB2,
|
||||
} dsm_protocol_e;
|
||||
|
||||
#define IS_DSM2(x) (x == DSM2_22 || x == DSM2_11 || x == DSM2_11_DX8)
|
||||
#define IS_DSM2(x) (x == DSM2_22 || x == DSM2_11 || x == DSM2_11_DX6 || x == DSM2_11_DX8)
|
||||
#define IS_DSMX(x) (!IS_DSM2(x))
|
||||
|
||||
#define CHECK_MFG_ID(protocol, packet, id) ((IS_DSM2(protocol) && packet[0] == (~id[2]&0xFF) && packet[1] == (~id[3]&0xFF)) || \
|
||||
(IS_DSMX(protocol) && packet[0] == id[2] && packet[1] == id[3]))
|
||||
|
||||
typedef enum {
|
||||
DSM_RECEIVER_BIND = 0x0,
|
||||
DSM_RECEIVER_SYNC_A = 0x1,
|
||||
DSM_RECEIVER_SYNC_B = 0x2,
|
||||
DSM_RECEIVER_RECV = 0x3,
|
||||
DSM_RECEIVER_BIND = 0,
|
||||
DSM_RECEIVER_BIND2,
|
||||
DSM_RECEIVER_SYNC_A,
|
||||
DSM_RECEIVER_SYNC_B,
|
||||
DSM_RECEIVER_RECV,
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
DSM_RECEIVER_TLM = 0x4,
|
||||
DSM_RECEIVER_TLM,
|
||||
#endif
|
||||
} dsm_receiver_status_e;
|
||||
|
||||
|
@ -175,6 +179,8 @@ typedef struct dsmReceiver_s {
|
|||
uint32_t timeout;
|
||||
uint32_t timeLastPacket;
|
||||
|
||||
uint16_t bindPackets;
|
||||
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
uint32_t timeLastTelemetry;
|
||||
bool sendTelemetry;
|
||||
|
@ -264,68 +270,6 @@ static void resetReceiveTimeout(const uint32_t timeStamp)
|
|||
}
|
||||
}
|
||||
|
||||
static void checkTimeout(void)
|
||||
{
|
||||
const uint32_t time = micros();
|
||||
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
if (featureIsEnabled(FEATURE_TELEMETRY) && (time - dsmReceiver.timeLastTelemetry) > DSM_TELEMETRY_TIME_US) {
|
||||
dsmReceiver.timeLastTelemetry = time;
|
||||
dsmReceiver.sendTelemetry = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((time - dsmReceiver.timeLastPacket) > dsmReceiver.timeout) {
|
||||
cyrf6936SetMode(CYRF6936_MODE_SYNTH_RX, true);
|
||||
cyrf6936WriteRegister(CYRF6936_RX_ABORT, 0x00);
|
||||
|
||||
dsmReceiver.timeLastPacket += dsmReceiver.timeout;
|
||||
|
||||
switch (dsmReceiver.status) {
|
||||
case DSM_RECEIVER_BIND:
|
||||
dsmReceiver.rfChannel = (dsmReceiver.rfChannel + 2) % DSM_MAX_RF_CHANNEL;
|
||||
cyrf6936SetChannel(dsmReceiver.rfChannel);
|
||||
dsmReceiver.timeout = DSM_BIND_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
case DSM_RECEIVER_SYNC_A:
|
||||
case DSM_RECEIVER_SYNC_B:
|
||||
IS_DSM2(dsmReceiver.protocol) ? dsmReceiverSetNextSyncChannel() : dsmReceiverSetNextChannel();
|
||||
dsmReceiver.timeout = DSM_SYNC_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
case DSM_RECEIVER_RECV:
|
||||
dsmReceiver.missedPackets++;
|
||||
DEBUG_SET(DEBUG_RX_SPEKTRUM_SPI, 0, dsmReceiver.missedPackets);
|
||||
if (dsmReceiver.missedPackets < DSM_MAX_MISSED_PACKETS) {
|
||||
dsmReceiverSetNextChannel();
|
||||
if (dsmReceiver.crcSeed == ((dsmReceiver.mfgId[0] << 8) + dsmReceiver.mfgId[1])) {
|
||||
dsmReceiver.timeout = DSM_RECV_SHORT_TIMEOUT_US;
|
||||
} else {
|
||||
dsmReceiver.timeout = DSM_RECV_TIMEOUT_OFFSET_US + (dsmReceiver.numChannels < 8 ? DSM_RECV_LONG_TIMEOUT_US : DSM_RECV_MID_TIMEOUT_US);
|
||||
}
|
||||
cyrf6936StartRecv();
|
||||
} else {
|
||||
setRssiDirect(0, RSSI_SOURCE_RX_PROTOCOL);
|
||||
dsmReceiver.status = DSM_RECEIVER_SYNC_A;
|
||||
dsmReceiver.timeout = DSM_SYNC_TIMEOUT_US;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
case DSM_RECEIVER_TLM:
|
||||
DEBUG_SET(DEBUG_RX_SPEKTRUM_SPI, 2, (cyrf6936ReadRegister(CYRF6936_TX_IRQ_STATUS) & CYRF6936_TXC_IRQ) == 0);
|
||||
dsmReceiverSetNextChannel();
|
||||
dsmReceiver.status = DSM_RECEIVER_RECV;
|
||||
dsmReceiver.timeout = (dsmReceiver.numChannels < 8 ? DSM_RECV_LONG_TIMEOUT_US : DSM_RECV_MID_TIMEOUT_US) - DSM_TELEMETRY_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dsmReceiverStartBind(void)
|
||||
{
|
||||
uint8_t dataCode[16];
|
||||
|
@ -437,6 +381,96 @@ static void dsmSendTelemetryPacket(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void dsmSendBindPacket(void)
|
||||
{
|
||||
uint8_t packet[10];
|
||||
uint16_t sum = 384 - 0x10;
|
||||
packet[0] = 0xff ^ dsmReceiver.mfgId[0];
|
||||
packet[1] = 0xff ^ dsmReceiver.mfgId[1];
|
||||
packet[2] = 0xff ^ dsmReceiver.mfgId[2];
|
||||
packet[3] = 0xff ^ dsmReceiver.mfgId[3];
|
||||
packet[4] = 0x01;
|
||||
packet[5] = dsmReceiver.numChannels;
|
||||
packet[6] = dsmReceiver.protocol;
|
||||
packet[7] = 0x00;
|
||||
for(unsigned i = 0; i < 8; i++)
|
||||
sum += packet[i];
|
||||
packet[8] = sum >> 8;
|
||||
packet[9] = sum & 0xff;
|
||||
cyrf6936SetMode(CYRF6936_MODE_IDLE, true);
|
||||
cyrf6936SendLen(packet, 10);
|
||||
}
|
||||
|
||||
static void checkTimeout(void)
|
||||
{
|
||||
const uint32_t time = micros();
|
||||
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
if (featureIsEnabled(FEATURE_TELEMETRY) && (time - dsmReceiver.timeLastTelemetry) > DSM_TELEMETRY_TIME_US) {
|
||||
dsmReceiver.timeLastTelemetry = time;
|
||||
dsmReceiver.sendTelemetry = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((time - dsmReceiver.timeLastPacket) > dsmReceiver.timeout) {
|
||||
cyrf6936SetMode(CYRF6936_MODE_SYNTH_RX, true);
|
||||
cyrf6936WriteRegister(CYRF6936_RX_ABORT, 0x00);
|
||||
|
||||
dsmReceiver.timeLastPacket += dsmReceiver.timeout;
|
||||
|
||||
switch (dsmReceiver.status) {
|
||||
case DSM_RECEIVER_BIND:
|
||||
dsmReceiver.rfChannel = (dsmReceiver.rfChannel + 2) % DSM_MAX_RF_CHANNEL;
|
||||
cyrf6936SetChannel(dsmReceiver.rfChannel);
|
||||
dsmReceiver.timeout = DSM_BIND_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
case DSM_RECEIVER_BIND2:
|
||||
if (dsmReceiver.bindPackets++ > DSM_MAX_BIND_PACKETS) {
|
||||
dsmReceiverStartTransfer();
|
||||
} else {
|
||||
dsmReceiver.timeout = DSM_BIND_TIMEOUT_US;
|
||||
dsmSendBindPacket();
|
||||
}
|
||||
break;
|
||||
case DSM_RECEIVER_SYNC_A:
|
||||
case DSM_RECEIVER_SYNC_B:
|
||||
IS_DSM2(dsmReceiver.protocol) ? dsmReceiverSetNextSyncChannel() : dsmReceiverSetNextChannel();
|
||||
dsmReceiver.timeout = DSM_SYNC_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
case DSM_RECEIVER_RECV:
|
||||
dsmReceiver.missedPackets++;
|
||||
DEBUG_SET(DEBUG_RX_SPEKTRUM_SPI, 0, dsmReceiver.missedPackets);
|
||||
if (dsmReceiver.missedPackets < DSM_MAX_MISSED_PACKETS) {
|
||||
dsmReceiverSetNextChannel();
|
||||
if (dsmReceiver.crcSeed == ((dsmReceiver.mfgId[0] << 8) + dsmReceiver.mfgId[1])) {
|
||||
dsmReceiver.timeout = DSM_RECV_SHORT_TIMEOUT_US;
|
||||
} else {
|
||||
dsmReceiver.timeout = dsmReceiver.numChannels < 8 ? DSM_RECV_LONG_TIMEOUT_US : DSM_RECV_MID_TIMEOUT_US;
|
||||
}
|
||||
cyrf6936StartRecv();
|
||||
} else {
|
||||
setRssiDirect(0, RSSI_SOURCE_RX_PROTOCOL);
|
||||
dsmReceiver.status = DSM_RECEIVER_SYNC_A;
|
||||
dsmReceiver.timeout = DSM_SYNC_TIMEOUT_US;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
case DSM_RECEIVER_TLM:
|
||||
DEBUG_SET(DEBUG_RX_SPEKTRUM_SPI, 2, (cyrf6936ReadRegister(CYRF6936_TX_IRQ_STATUS) & CYRF6936_TXC_IRQ) == 0);
|
||||
dsmReceiverSetNextChannel();
|
||||
dsmReceiver.status = DSM_RECEIVER_RECV;
|
||||
dsmReceiver.timeout = (dsmReceiver.numChannels < 8 ? DSM_RECV_LONG_TIMEOUT_US : DSM_RECV_MID_TIMEOUT_US) - DSM_TELEMETRY_TIMEOUT_US;
|
||||
cyrf6936StartRecv();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spektrumSpiSetRcDataFromPayload(uint16_t *rcData, const uint8_t *payload)
|
||||
{
|
||||
if (rcData && payload) {
|
||||
|
@ -528,9 +562,14 @@ rx_spi_received_e spektrumReadPacket(uint8_t *payload, const uint32_t timeStamp)
|
|||
spektrumConfigMutable()->protocol = dsmReceiver.protocol;
|
||||
writeEEPROM();
|
||||
|
||||
dsmReceiverStartTransfer();
|
||||
cyrf6936SetDataCode(bindDataCode);
|
||||
|
||||
dsmReceiver.bindPackets = 0;
|
||||
dsmReceiver.status = DSM_RECEIVER_BIND2;
|
||||
dsmReceiver.timeLastPacket = timeStamp;
|
||||
dsmReceiver.timeout = DSM_BIND_TIMEOUT_US;
|
||||
dsmReceiver.bound = true;
|
||||
|
||||
result = RX_SPI_RECEIVED_BIND;
|
||||
break;
|
||||
case DSM_RECEIVER_SYNC_A:
|
||||
|
@ -548,6 +587,8 @@ rx_spi_received_e spektrumReadPacket(uint8_t *payload, const uint32_t timeStamp)
|
|||
IS_DSM2(dsmReceiver.protocol) ? dsmReceiverSetNextSyncChannel() : dsmReceiverSetNextChannel();
|
||||
resetReceiveTimeout(timeStamp);
|
||||
cyrf6936StartRecv();
|
||||
|
||||
result = RX_SPI_RECEIVED_DATA;
|
||||
}
|
||||
break;
|
||||
case DSM_RECEIVER_SYNC_B:
|
||||
|
@ -565,6 +606,8 @@ rx_spi_received_e spektrumReadPacket(uint8_t *payload, const uint32_t timeStamp)
|
|||
resetReceiveTimeout(timeStamp);
|
||||
cyrf6936StartRecv();
|
||||
}
|
||||
|
||||
result = RX_SPI_RECEIVED_DATA;
|
||||
}
|
||||
break;
|
||||
case DSM_RECEIVER_RECV:
|
||||
|
@ -614,7 +657,7 @@ rx_spi_received_e spektrumSpiDataReceived(uint8_t *payload)
|
|||
|
||||
checkTimeout();
|
||||
|
||||
dsmReceiver.bound ? rxSpiLedBlinkRxLoss(result) : rxSpiLedBlinkBind();
|
||||
dsmReceiver.bound ? (dsmReceiver.status == DSM_RECEIVER_BIND2 ? rxSpiLedBlinkRxLoss(RX_SPI_RECEIVED_DATA) : rxSpiLedBlinkRxLoss(result)) : rxSpiLedBlinkBind();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DSM_BIND_TIMEOUT_US 10000
|
||||
#define DSM_BIND_TIMEOUT_US 11000
|
||||
#define DSM_SYNC_TIMEOUT_US 20000
|
||||
#define DSM_RECV_LONG_TIMEOUT_US 18010
|
||||
#define DSM_RECV_MID_TIMEOUT_US 7000
|
||||
#define DSM_RECV_SHORT_TIMEOUT_US 4010
|
||||
#define DSM_RECV_TIMEOUT_OFFSET_US 1000
|
||||
#define DSM_RECV_LONG_TIMEOUT_US 18500
|
||||
#define DSM_RECV_MID_TIMEOUT_US 7500
|
||||
#define DSM_RECV_SHORT_TIMEOUT_US 4500
|
||||
|
||||
#define DSM_MAX_BIND_PACKETS 500
|
||||
#define DSM_MAX_MISSED_PACKETS 31
|
||||
|
||||
#define DSM_MAX_RF_CHANNEL 0x4F
|
||||
|
|
|
@ -94,19 +94,18 @@ void rxSpiLedBlink(timeMs_t blinkMs)
|
|||
|
||||
void rxSpiLedBlinkRxLoss(rx_spi_received_e result)
|
||||
{
|
||||
static uint16_t rxLossCount = 0;
|
||||
static timeMs_t rxLossMs = 0;
|
||||
|
||||
if (ledPin) {
|
||||
if (result == RX_SPI_RECEIVED_DATA) {
|
||||
rxLossCount = 0;
|
||||
rxSpiLedOn();
|
||||
} else {
|
||||
if (rxLossCount < RX_LOSS_COUNT) {
|
||||
rxLossCount++;
|
||||
} else {
|
||||
rxSpiLedBlink(INTERVAL_RX_LOSS_MS);
|
||||
if ((rxLossMs + INTERVAL_RX_LOSS_MS) > millis()) {
|
||||
return;
|
||||
}
|
||||
rxSpiLedToggle();
|
||||
}
|
||||
rxLossMs = millis();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#define INTERVAL_RX_LOSS_MS 1000
|
||||
#define INTERVAL_RX_BIND_MS 250
|
||||
#define RX_LOSS_COUNT 1000
|
||||
|
||||
void rxSpiCommonIOInit(const rxSpiConfig_t *rxSpiConfig);
|
||||
|
||||
|
|
|
@ -249,4 +249,7 @@
|
|||
#define USE_RX_FLYSKY
|
||||
#define USE_RX_FLYSKY_SPI_LED
|
||||
|
||||
#define USE_RX_SPEKTRUM
|
||||
#define USE_RX_SPEKTRUM_TELEMETRY
|
||||
|
||||
#define USE_CUSTOM_DEFAULTS
|
||||
|
|
|
@ -44,12 +44,13 @@ extern "C" {
|
|||
#define IS_DSMX(x) (!IS_DSM2(x))
|
||||
|
||||
typedef enum {
|
||||
DSM_RECEIVER_BIND = 0x0,
|
||||
DSM_RECEIVER_SYNC_A = 0x1,
|
||||
DSM_RECEIVER_SYNC_B = 0x2,
|
||||
DSM_RECEIVER_RECV = 0x3,
|
||||
DSM_RECEIVER_BIND = 0,
|
||||
DSM_RECEIVER_BIND2,
|
||||
DSM_RECEIVER_SYNC_A,
|
||||
DSM_RECEIVER_SYNC_B,
|
||||
DSM_RECEIVER_RECV,
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
DSM_RECEIVER_TLM = 0x4,
|
||||
DSM_RECEIVER_TLM,
|
||||
#endif
|
||||
} dsm_receiver_status_e;
|
||||
|
||||
|
@ -75,6 +76,8 @@ extern "C" {
|
|||
uint32_t timeout;
|
||||
uint32_t timeLastPacket;
|
||||
|
||||
uint16_t bindPackets;
|
||||
|
||||
#ifdef USE_RX_SPEKTRUM_TELEMETRY
|
||||
uint32_t timeLastTelemetry;
|
||||
bool sendTelemetry;
|
||||
|
@ -375,6 +378,7 @@ extern "C" {
|
|||
void cyrf6936SetSopCode(const uint8_t ) {}
|
||||
void cyrf6936SetDataCode(const uint8_t ) {}
|
||||
void cyrf6936StartRecv(void) {}
|
||||
void cyrf6936SendLen(uint8_t *, const uint8_t ) {}
|
||||
void cyrf6936RecvLen(uint8_t *data, const uint8_t length)
|
||||
{
|
||||
if (length == packetLen) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue