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
}
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()
{
//Check frequencies
@ -127,6 +182,12 @@ uint16_t initFrSkyR9()
FrSkyFormat=1; // 8 channels
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_SetMode(true, false, SX1276_OPMODE_SLEEP);
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))
SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18
//Build packet
FrSkyR9_build_packet();
if( packet_length == 26 )
FrSkyR9_build_packet();
else
FrSkyR9_build_EU_packet();
phase++;
return 460; // Frequency settle time
case FRSKYR9_DATA:
//Set RF switch to TX
SX1276_SetTxRxMode(TX_EN);
//Send packet
SX1276_WritePayloadToFifo(packet, 26);
SX1276_WritePayloadToFifo(packet, packet_length);
SX1276_SetMode(true, false, SX1276_OPMODE_TX);
#if not defined TELEMETRY
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_POTENSIC[] = "\x03""A20";
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_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 ";
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_PELIKAN[] = "\x04""Pro\0""Lite";
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
{
@ -225,7 +225,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE },
#endif
#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
#if defined(FQ777_NRF24L01_INO)
{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 },
#endif
#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
#if defined(SCANNER_CC2500_INO)
// {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE },

View File

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

View File

@ -23,6 +23,7 @@
#define RLINK_TX_PACKET_LEN 33
#define RLINK_RX_PACKET_LEN 15
#define RLINK_TX_ID_LEN 4
#define RLINK_HOP 16
enum {
RLINK_DATA = 0x00,
@ -40,15 +41,32 @@ const PROGMEM uint8_t RLINK_init_values[] = {
static void __attribute__((unused)) RLINK_init()
{
hopping_frequency[RLINK_HOP]=16;
// channels order depend on ID and currently unknown...
#ifdef RLINK_FORCE_ID
//surface
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
// channels order depend on ID and currently unknown...
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
// set channels value based on ID
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
hopping_frequency[rf_ch_num]=0xC6;
// replace one of the channel randomely
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()
@ -86,8 +104,15 @@ static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet()
// packet length
packet[0] = RLINK_TX_PACKET_LEN;
// header
packet[1] = packet_count>3?0x03:0x01; // packet type: 0x01 normal, 0x03 request telemetry
//if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard
if(sub_protocol)
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
memcpy(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN);
@ -132,7 +157,7 @@ static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet()
packet_count++;
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++)
// debug(" 0x%02X",packet[i]);
//debugln("");
@ -154,10 +179,10 @@ uint16_t RLINK_callback()
#if not defined RLINK_HUB_TELEMETRY
return RLINK_TIMING_PROTO;
#else
if(packet[1]==0x01)
return RLINK_TIMING_PROTO;
if(!(packet[1]&0x02))
return RLINK_TIMING_PROTO; //Normal packet
phase++; // RX1
return RLINK_TIMING_RFSEND;
return RLINK_TIMING_RFSEND; //Telemetry packet
case RLINK_RX1:
CC2500_Strobe(CC2500_SIDLE);
CC2500_Strobe(CC2500_SFRX);
@ -191,8 +216,9 @@ uint16_t RLINK_callback()
//debugln("");
}
if (millis() - pps_timer >= 2000)
{//1 packet every 20ms
{//1 telemetry packet every 100ms
pps_timer = millis();
pps_counter*=5;
debugln("%d pps", pps_counter);
TX_LQI = pps_counter; //Max=100%
pps_counter = 0;