diff --git a/src/main/rx/cyrf6936_spektrum.c b/src/main/rx/cyrf6936_spektrum.c index 081f2aa985..f0dd5677fa 100644 --- a/src/main/rx/cyrf6936_spektrum.c +++ b/src/main/rx/cyrf6936_spektrum.c @@ -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; } diff --git a/src/main/rx/cyrf6936_spektrum.h b/src/main/rx/cyrf6936_spektrum.h index f1b7651a5c..3625117181 100644 --- a/src/main/rx/cyrf6936_spektrum.h +++ b/src/main/rx/cyrf6936_spektrum.h @@ -23,13 +23,13 @@ #include #include -#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 diff --git a/src/main/rx/rx_spi_common.c b/src/main/rx/rx_spi_common.c index 425dc7199e..7a89e63b97 100644 --- a/src/main/rx/rx_spi_common.c +++ b/src/main/rx/rx_spi_common.c @@ -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(); } } diff --git a/src/main/rx/rx_spi_common.h b/src/main/rx/rx_spi_common.h index 1a5dc586c8..f3f3cb2877 100644 --- a/src/main/rx/rx_spi_common.h +++ b/src/main/rx/rx_spi_common.h @@ -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); diff --git a/src/main/target/STM32_UNIFIED/target.h b/src/main/target/STM32_UNIFIED/target.h index 9ed96b0efa..02d3dc69f7 100644 --- a/src/main/target/STM32_UNIFIED/target.h +++ b/src/main/target/STM32_UNIFIED/target.h @@ -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 diff --git a/src/test/unit/rx_spi_spektrum_unittest.cc b/src/test/unit/rx_spi_spektrum_unittest.cc index a2b4ac43ea..4e7f6ca727 100644 --- a/src/test/unit/rx_spi_spektrum_unittest.cc +++ b/src/test/unit/rx_spi_spektrum_unittest.cc @@ -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) {