RadioLink: update

This commit is contained in:
Pascal Langer 2020-07-28 00:55:47 +02:00
parent de190f3349
commit 695264d59a
4 changed files with 108 additions and 18 deletions

View File

@ -102,6 +102,61 @@ static void __attribute__((unused)) FrSkyR9_build_packet()
packet[25] = crc >> 8; // high byte packet[25] = crc >> 8; // high byte
} }
static uint8_t __attribute__((unused)) FrSkyR9_CRC8(uint8_t *p, uint8_t l)
{
uint8_t crc = 0xFF;
for (uint8_t i = 0; i < l; i++)
{
crc = crc ^ p[i];
for ( uint8_t j = 0; j < 8; j++ )
if ( crc & 0x80 )
{
crc <<= 1;
crc ^= 0x07;
}
else
crc <<= 1;
}
return crc;
}
static void __attribute__((unused)) FrSkyR9_build_EU_packet()
{
//ID
packet[0] = rx_tx_addr[1];
packet[1] = rx_tx_addr[2];
packet[2] = rx_tx_addr[3];
//Hopping
packet[3] = FrSkyX_chanskip; // step size and last 2 channels start index
//RX number
packet[4] = RX_num; // receiver number from OpenTX
//Channels
//TODO FrSkyX_channels(5,4); // Set packet[5]=failsafe and packet[6..11]=4 channels data
//Bind
if(IS_BIND_IN_PROGRESS)
{
packet[5] = 0x01; // bind indicator
if((sub_protocol & 2) == 0)
packet[5] |= 0x10; // 16CH
// if(sub_protocol & 1)
// packet[5] |= 0x20; // 868
if(binding_idx&0x01)
packet[5] |= 0x40; // telem OFF
if(binding_idx&0x02)
packet[5] |= 0x80; // ch9-16
}
//Sequence and send SPort
packet[12] = (FrSkyX_RX_Seq << 4)|0x08; //TX=8 at startup
//CRC
packet[13] = FrSkyR9_CRC8(packet, 13);
}
uint16_t initFrSkyR9() uint16_t initFrSkyR9()
{ {
//Check frequencies //Check frequencies
@ -127,6 +182,12 @@ uint16_t initFrSkyR9()
FrSkyFormat=1; // 8 channels FrSkyFormat=1; // 8 channels
debugln("%dCH", FrSkyFormat&1 ? 8:16); debugln("%dCH", FrSkyFormat&1 ? 8:16);
//EU packet length
if( (sub_protocol & 0xFD) == R9_EU )
packet_length=14;
else
packet_length=26;
//SX1276 Init //SX1276 Init
SX1276_SetMode(true, false, SX1276_OPMODE_SLEEP); SX1276_SetMode(true, false, SX1276_OPMODE_SLEEP);
SX1276_SetMode(true, false, SX1276_OPMODE_STDBY); SX1276_SetMode(true, false, SX1276_OPMODE_STDBY);
@ -168,14 +229,17 @@ uint16_t FrSkyR9_callback()
// output_power: 2 dBm (17-(15-OutputPower) (if pa_boost_pin == true)) // output_power: 2 dBm (17-(15-OutputPower) (if pa_boost_pin == true))
SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18 SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18
//Build packet //Build packet
FrSkyR9_build_packet(); if( packet_length == 26 )
FrSkyR9_build_packet();
else
FrSkyR9_build_EU_packet();
phase++; phase++;
return 460; // Frequency settle time return 460; // Frequency settle time
case FRSKYR9_DATA: case FRSKYR9_DATA:
//Set RF switch to TX //Set RF switch to TX
SX1276_SetTxRxMode(TX_EN); SX1276_SetTxRxMode(TX_EN);
//Send packet //Send packet
SX1276_WritePayloadToFifo(packet, 26); SX1276_WritePayloadToFifo(packet, packet_length);
SX1276_SetMode(true, false, SX1276_OPMODE_TX); SX1276_SetMode(true, false, SX1276_OPMODE_TX);
#if not defined TELEMETRY #if not defined TELEMETRY
phase=FRSKYR9_FREQ; phase=FRSKYR9_FREQ;

View File

@ -125,7 +125,7 @@ const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2";
const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow"; const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow";
const char STR_SUBTYPE_POTENSIC[] = "\x03""A20"; const char STR_SUBTYPE_POTENSIC[] = "\x03""A20";
const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC"; const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC";
const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410"; const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410""FZ8xx";
const char STR_SUBTYPE_FX816[] = "\x03""P38"; const char STR_SUBTYPE_FX816[] = "\x03""P38";
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 "; const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 ";
const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch"; const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
@ -141,7 +141,7 @@ const char STR_SUBTYPE_WFLY[] = "\x06""WFR0xS";
const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync"; const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
const char STR_SUBTYPE_PELIKAN[] = "\x04""Pro\0""Lite"; const char STR_SUBTYPE_PELIKAN[] = "\x04""Pro\0""Lite";
const char STR_SUBTYPE_V761[] = "\x03""3CH""4CH"; const char STR_SUBTYPE_V761[] = "\x03""3CH""4CH";
const char STR_SUBTYPE_RLINK[] = "\x07""Surface"; const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ";
enum enum
{ {
@ -225,7 +225,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE }, {PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE },
#endif #endif
#if defined(FLYZONE_A7105_INO) #if defined(FLYZONE_A7105_INO)
{PROTO_FLYZONE, STR_FLYZONE, 1, STR_SUBTYPE_FLYZONE, OPTION_NONE }, {PROTO_FLYZONE, STR_FLYZONE, 2, STR_SUBTYPE_FLYZONE, OPTION_NONE },
#endif #endif
#if defined(FQ777_NRF24L01_INO) #if defined(FQ777_NRF24L01_INO)
{PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE }, {PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE },
@ -327,7 +327,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE }, {PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE },
#endif #endif
#if defined(RLINK_CC2500_INO) #if defined(RLINK_CC2500_INO)
{PROTO_RLINK, STR_RLINK, 1, STR_SUBTYPE_RLINK, OPTION_RFTUNE }, {PROTO_RLINK, STR_RLINK, 2, STR_SUBTYPE_RLINK, OPTION_RFTUNE },
#endif #endif
#if defined(SCANNER_CC2500_INO) #if defined(SCANNER_CC2500_INO)
// {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE }, // {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE },

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_REVISION 1 #define VERSION_REVISION 1
#define VERSION_PATCH_LEVEL 45 #define VERSION_PATCH_LEVEL 46
//****************** //******************
// Protocols // Protocols

View File

@ -23,6 +23,7 @@
#define RLINK_TX_PACKET_LEN 33 #define RLINK_TX_PACKET_LEN 33
#define RLINK_RX_PACKET_LEN 15 #define RLINK_RX_PACKET_LEN 15
#define RLINK_TX_ID_LEN 4 #define RLINK_TX_ID_LEN 4
#define RLINK_HOP 16
enum { enum {
RLINK_DATA = 0x00, RLINK_DATA = 0x00,
@ -40,15 +41,32 @@ const PROGMEM uint8_t RLINK_init_values[] = {
static void __attribute__((unused)) RLINK_init() static void __attribute__((unused)) RLINK_init()
{ {
hopping_frequency[RLINK_HOP]=16;
// channels order depend on ID and currently unknown...
#ifdef RLINK_FORCE_ID #ifdef RLINK_FORCE_ID
//surface
memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN); memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN);
memcpy(hopping_frequency,"\x1\xF\x8\x9\x2\x5\x0\x6\x4\xE\xB\xD\x3\xA\xC\x7",RLINK_HOP); //end value is value*12+6
//air
memcpy(rx_tx_addr,"\xFC\x11\x0D\x20",RLINK_TX_ID_LEN);
memcpy(hopping_frequency,"\xB\xC\xF\xE\x5\x9\x8\x4\x3\x7\xA\x1\xD\x0\x6\x2",RLINK_HOP); //end value is value*12
#endif #endif
// channels order depend on ID and currently unknown... // set channels value based on ID
memcpy(hopping_frequency,"\x12\xBA\x66\x72\x1E\x42\x06\x4E\x36\xAE\x8A\xA2\x2A\x7E\x96\x5A",16); // 1,15,8,9,2,5,0,6,4,14,11,13,3,10,12,7 : end value is value*12+6 for(uint8_t i=0;i<=RLINK_HOP;i++)
hopping_frequency[i]=3*(4*hopping_frequency[i]+(rx_tx_addr[0]&3));
rf_ch_num=(random(0xfefefefe)&0x0F)+1; // 0x01..0x10 // replace one of the channel randomely
hopping_frequency[rf_ch_num]=0xC6; rf_ch_num=random(0xfefefefe)&0x0F; // 0x00..0x0F
if(hopping_frequency[RLINK_HOP]==0xC9)
hopping_frequency[rf_ch_num]=0xC6;
else
hopping_frequency[rf_ch_num]=hopping_frequency[RLINK_HOP];
debug("Hop(%d):", rf_ch_num);
for(uint8_t i=0;i<RLINK_HOP;i++)
debug(" 0x%02X",hopping_frequency[i]);
debugln("");
} }
static void __attribute__((unused)) RLINK_rf_init() static void __attribute__((unused)) RLINK_rf_init()
@ -86,8 +104,15 @@ static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet()
// packet length // packet length
packet[0] = RLINK_TX_PACKET_LEN; packet[0] = RLINK_TX_PACKET_LEN;
// header // header
packet[1] = packet_count>3?0x03:0x01; // packet type: 0x01 normal, 0x03 request telemetry if(sub_protocol)
//if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard packet[1] = 0x21; //air 0x21 on dump but it looks to support telemetry
else
{//surface
packet[1] = 0x00;
//radiolink additionnal ID which is working only on a small set of RXs
//if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard
}
packet[1] |= packet_count>3?0x03:0x01; // packet type: 0x01 normal, 0x03 request telemetry
// ID // ID
memcpy(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN); memcpy(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN);
@ -132,7 +157,7 @@ static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet()
packet_count++; packet_count++;
if(packet_count>5) packet_count=0; if(packet_count>5) packet_count=0;
//debug("P:"); //debug("P(%02X):",hopping_frequency[pseudo & 0x0F]);
//for(uint8_t i=0;i<RLINK_TX_PACKET_LEN+1;i++) //for(uint8_t i=0;i<RLINK_TX_PACKET_LEN+1;i++)
// debug(" 0x%02X",packet[i]); // debug(" 0x%02X",packet[i]);
//debugln(""); //debugln("");
@ -154,10 +179,10 @@ uint16_t RLINK_callback()
#if not defined RLINK_HUB_TELEMETRY #if not defined RLINK_HUB_TELEMETRY
return RLINK_TIMING_PROTO; return RLINK_TIMING_PROTO;
#else #else
if(packet[1]==0x01) if(!(packet[1]&0x02))
return RLINK_TIMING_PROTO; return RLINK_TIMING_PROTO; //Normal packet
phase++; // RX1 phase++; // RX1
return RLINK_TIMING_RFSEND; return RLINK_TIMING_RFSEND; //Telemetry packet
case RLINK_RX1: case RLINK_RX1:
CC2500_Strobe(CC2500_SIDLE); CC2500_Strobe(CC2500_SIDLE);
CC2500_Strobe(CC2500_SFRX); CC2500_Strobe(CC2500_SFRX);
@ -191,8 +216,9 @@ uint16_t RLINK_callback()
//debugln(""); //debugln("");
} }
if (millis() - pps_timer >= 2000) if (millis() - pps_timer >= 2000)
{//1 packet every 20ms {//1 telemetry packet every 100ms
pps_timer = millis(); pps_timer = millis();
pps_counter*=5;
debugln("%d pps", pps_counter); debugln("%d pps", pps_counter);
TX_LQI = pps_counter; //Max=100% TX_LQI = pps_counter; //Max=100%
pps_counter = 0; pps_counter = 0;