New protocol FrSkyL: LR12

Model: L9R RX
2 sub protocols: LR12 and LR12_6CH
This commit is contained in:
Pascal Langer 2020-04-11 20:09:32 +02:00
parent 00aecb3ab1
commit 7e5cd9819a
11 changed files with 382 additions and 36 deletions

View File

@ -143,10 +143,10 @@ uint16_t convert_channel_frsky(uint8_t num)
// 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182
//64=860,1024=1500,1984=2140//Taranis 125%
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX( uint8_t i )
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX( uint8_t i, uint8_t num_chan=8)
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
uint16_t chan_val=convert_channel_frsky(i)-1226;
if(i>7) chan_val|=2048; // upper channels offset
if(i>=num_chan) chan_val|=2048; // upper channels offset
return chan_val;
}

View File

@ -17,7 +17,7 @@
/** FrSky D and X routines **/
/******************************/
#if defined(FRSKYX_CC2500_INO) || defined(FRSKY_RX_CC2500_INO) || defined(FRSKYR9_SX1276_INO)
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYL_CC2500_INO) || defined(FRSKY_RX_CC2500_INO) || defined(FRSKYR9_SX1276_INO)
//**CRC**
const uint16_t PROGMEM FrSkyX_CRC_Short[]={
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
@ -29,9 +29,9 @@ static uint16_t __attribute__((unused)) FrSkyX_CRCTable(uint8_t val)
val /= 16 ;
return word ^ (0x1081 * val) ;
}
uint16_t FrSkyX_crc(uint8_t *data, uint8_t len)
uint16_t FrSkyX_crc(uint8_t *data, uint8_t len, uint8_t init=0)
{
uint16_t crc = 0;
uint16_t crc = init;
for(uint8_t i=0; i < len; i++)
crc = (crc<<8) ^ FrSkyX_CRCTable((uint8_t)(crc>>8) ^ *data++);
return crc;
@ -39,7 +39,7 @@ uint16_t FrSkyX_crc(uint8_t *data, uint8_t len)
#endif
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYX_CC2500_INO)
enum {
FRSKY_BIND = 0,
FRSKY_BIND_DONE = 1000,
@ -122,7 +122,7 @@ void Frsky_init_clone(void)
/******************************/
/** FrSky V, D and X routines **/
/******************************/
#if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
#if defined(FRSKYV_CC2500_INO) || defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYL_CC2500_INO)
const PROGMEM uint8_t FRSKY_common_startreg_cc2500_conf[]= {
CC2500_02_IOCFG0 ,
CC2500_00_IOCFG2 ,
@ -190,7 +190,7 @@ void Frsky_init_clone(void)
/*15_DEVIATN*/ 0x42 };
#endif
#if defined(FRSKYX_CC2500_INO)
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYL_CC2500_INO)
const PROGMEM uint8_t FRSKYX_cc2500_conf[]= {
//FRSKYX
/*02_IOCFG0*/ 0x06 ,
@ -232,6 +232,26 @@ void Frsky_init_clone(void)
/*13_MDMCFG1*/ 0x23 ,
/*14_MDMCFG0*/ 0x7a ,
/*15_DEVIATN*/ 0x53 };
const PROGMEM uint8_t FRSKYL_cc2500_conf[]= {
/*02_IOCFG0*/ 0x02 ,
/*00_IOCFG2*/ 0x02 ,
/*17_MCSM1*/ 0x0C ,
/*18_MCSM0*/ 0x18 ,
/*06_PKTLEN*/ 0xFF ,
/*07_PKTCTRL1*/ 0x00 ,
/*08_PKTCTRL0*/ 0x02 ,
/*3E_PATABLE*/ 0xFE ,
/*0B_FSCTRL1*/ 0x0A ,
/*0C_FSCTRL0*/ 0x00 ,
/*0D_FREQ2*/ 0x5c ,
/*0E_FREQ1*/ 0x76 ,
/*0F_FREQ0*/ 0x27 ,
/*10_MDMCFG4*/ 0x5C ,
/*11_MDMCFG3*/ 0x3B ,
/*12_MDMCFG2*/ 0x00 ,
/*13_MDMCFG1*/ 0x03 ,
/*14_MDMCFG0*/ 0x7A ,
/*15_DEVIATN*/ 0x47 };
#endif
const PROGMEM uint8_t FRSKY_common_end_cc2500_conf[][2]= {
@ -276,7 +296,7 @@ void Frsky_init_clone(void)
}
#endif
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYX2_CC2500_INO)
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYL_CC2500_INO)
uint8_t FrSkyX_chanskip;
uint8_t FrSkyX_TX_Seq, FrSkyX_TX_IN_Seq;
uint8_t FrSkyX_RX_Seq ;
@ -302,7 +322,10 @@ static void __attribute__((unused)) FrSkyX_set_start(uint8_t ch )
static void __attribute__((unused)) FrSkyX_init()
{
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
if(protocol==PROTO_FRSKYL)
FRSKY_init_cc2500(FRSKYL_cc2500_conf);
else
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
if(protocol==PROTO_FRSKYX2)
{
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // Enable CRC

View File

@ -0,0 +1,262 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(FRSKYL_CC2500_INO)
#include "iface_cc2500.h"
#define FRSKYL_FORCE_ID
#define FRSKYL_PACKET_LEN 256
#define FRSKYL_PERIOD 18000
uint8_t FrSkyL_buffer[FRSKYL_PACKET_LEN];
static void __attribute__((unused)) FrSkyL_build_bind_packet()
{
//Header
packet[0] = 0x4E; // Unknown but constant
//Bind packet
memset(&packet[1],0x00,3);
//ID
packet[4 ] = rx_tx_addr[3]; // ID
packet[5 ] = rx_tx_addr[2]; // ID
int idx = ((state -FRSKY_BIND) % 10) * 5;
packet[6 ] = idx;
packet[7 ] = hopping_frequency[idx++];
packet[8 ] = hopping_frequency[idx++];
packet[9 ] = hopping_frequency[idx++];
packet[10] = hopping_frequency[idx++];
packet[11] = hopping_frequency[idx++];
packet[12] = rx_tx_addr[1]; // ID or hw ver?
packet[13] = RX_num;
packet[14] = 0x00; // Unknown but constant
//CRC
uint16_t lcrc = FrSkyX_crc(&packet[1], 14);
packet[15] = lcrc >> 8;
packet[16] = lcrc;
//Debug
/* debug("Bind:");
for(uint8_t i=0;i<17;i++)
debug(" %02X",packet[i]);
debugln("");*/
}
static void __attribute__((unused)) FrSkyL_build_packet()
{
static uint8_t chan_offset=0;
uint16_t chan_0,chan_1;
//Header
packet[0 ] = 0x4E; // Unknown but constant
//ID
packet[1 ] = rx_tx_addr[3]; // ID
packet[2 ] = rx_tx_addr[2]; // ID
packet[3 ] = rx_tx_addr[1]; // ID or hw ver?
//skip_hop
packet[4 ] = (FrSkyX_chanskip<<6)|hopping_frequency_no;
packet[5 ] = FrSkyX_chanskip>>2;
//Channels
uint8_t startChan = chan_offset;
for(uint8_t i = 0; i <9 ; i+=3)
{//9 bytes of channel data
chan_0 = FrSkyX_scaleForPXX(startChan,6);
startChan++;
//
chan_1 = FrSkyX_scaleForPXX(startChan,6);
startChan++;
//
packet[6+i] = lowByte(chan_0); //3 bytes*4
packet[6+i+1]=(((chan_0>>8) & 0x0F)|(chan_1 << 4));
packet[6+i+2]=chan_1>>4;
}
if(sub_protocol & 0x01 ) //6ch mode only??
chan_offset = 0 ;
else
chan_offset^=0x06;
//CRC
uint16_t lcrc = FrSkyX_crc(&packet[1], 14, RX_num);
packet[15] = lcrc >> 8;
packet[16] = lcrc;
//Debug
/*debug("Norm:");
for(uint8_t i=0;i<17;i++)
debug(" %02X",packet[i]);
debugln("");*/
}
static void __attribute__((unused)) FrSkyL_encode_packet(bool type)
{
#define FRSKYL_BIT0 0xED
#define FRSKYL_BIT1 0x712
uint32_t bits = 0;
uint8_t bitsavailable = 0;
uint8_t idx = 0,len=6;
if(type)
{//just replace packet content
idx=66;
len=17;
}
//debugln("Encode:");
for (uint8_t i = 0; i < len; i++)
{
uint8_t tmp=packet[i];
//debug("%02X =",tmp);
for(uint8_t j=0;j<8;j++)
{
bits <<= 11;
if(tmp&0x01)
bits |= FRSKYL_BIT1;
else
bits |= FRSKYL_BIT0;
tmp >>=1;
bitsavailable += 11;
while (bitsavailable >= 8) {
uint32_t bits_tmp=bits>>(bitsavailable-8);
bitsavailable -= 8;
FrSkyL_buffer[idx] = bits_tmp;
//debug(" %02X",FrSkyL_buffer[idx]);
idx++;
}
}
//debugln("");
}
}
uint16_t ReadFrSkyL()
{
static uint8_t written=0, send=0;
switch(send)
{
case 1:
CC2500_Strobe(CC2500_SIDLE);
CC2500_Strobe(CC2500_SFTX);
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, FrSkyL_buffer, 64);
CC2500_Strobe(CC2500_STX);
CC2500_Strobe(CC2500_SIDLE); // This cancels the current transmission???
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, FrSkyL_buffer, 64);
CC2500_Strobe(CC2500_SFTX); // This just clears what we've written???
CC2500_Strobe(CC2500_STX);
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, FrSkyL_buffer, 64);
written=64;
send++;
return 2623;
case 2:
len=FRSKYL_PACKET_LEN-written;
if(len>31)
len=31;
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, FrSkyL_buffer+written, len);
written+=len;
if(len!=31) //everything has been sent
{
send=0;
return 2936;
}
return 1984;
}
switch(state)
{
default:
//Bind
#ifdef MULTI_SYNC
telemetry_set_input_sync(9000);
#endif
FrSkyX_set_start(47);
CC2500_SetPower();
CC2500_Strobe(CC2500_SFRX);
//
FrSkyL_build_bind_packet();
FrSkyL_encode_packet(true);
CC2500_Strobe(CC2500_SIDLE);
if(IS_BIND_DONE)
state = FRSKY_BIND_DONE;
else
{
state++;
send=1;
}
return 537;
case FRSKY_BIND_DONE:
FrSkyX_initialize_data(0);
hopping_frequency_no=0;
BIND_DONE;
state++; //FRSKY_DATA1
break;
case FRSKY_DATA1:
if ( prev_option != option )
{
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); //Frequency offset hack
prev_option = option ;
}
FrSkyX_set_start(hopping_frequency_no);
FrSkyL_build_packet();
FrSkyL_encode_packet(true);
CC2500_SetPower();
hopping_frequency_no = (hopping_frequency_no+FrSkyX_chanskip)%47;
send=1;
return 537;
}
return 1;
}
uint16_t initFrSkyL()
{
set_rx_tx_addr(MProtocol_id_master);
rx_tx_addr[1]=0x02; // ID related, hw version?
#ifdef FRSKYL_FORCE_ID
rx_tx_addr[3]=0x0E;
rx_tx_addr[2]=0x1C;
rx_tx_addr[1]=0x02;
#endif
FrSkyX2_init_hop();
while(!FrSkyX_chanskip)
FrSkyX_chanskip=random(0xfefefefe)%47;
FrSkyX_init();
//Prepare frame
memset(FrSkyL_buffer,0x00,FRSKYL_PACKET_LEN-3);
memset(&FrSkyL_buffer[FRSKYL_PACKET_LEN-3],0x55,3);
memset(packet,0xAA,6);
FrSkyL_encode_packet(false);
/*debugln("Frame:");
for(uint16_t i=0;i<FRSKYL_PACKET_LEN;i++)
{
debug(" %02X",FrSkyL_buffer[i]);
if(i%11==10)
debugln("");
}
debugln("");*/
if(IS_BIND_IN_PROGRESS)
{
state = FRSKY_BIND;
FrSkyX_initialize_data(1);
}
else
{
state = FRSKY_DATA1;
FrSkyX_initialize_data(0);
}
return 10000;
}
#endif

View File

@ -1,19 +1,17 @@
/* **************************
* By Midelic on RCGroups *
**************************
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(FRSKYX_CC2500_INO)

View File

@ -64,3 +64,4 @@
64,FrskyX2,CH_16,CH_8,EU_16,EU_8
65,FrSkyR9,915MHz,868MHz,915_8ch,868_8ch
66,PROPEL,74-Z
67,LR12,LR12,LR12_6ch

View File

@ -29,6 +29,7 @@ const char STR_SLT[] ="SLT";
const char STR_CX10[] ="CX10";
const char STR_CG023[] ="CG023";
const char STR_BAYANG[] ="Bayang";
const char STR_FRSKYL[] ="FrSky L";
const char STR_FRSKYX[] ="FrSky X";
const char STR_FRSKYX2[] ="FrSkyX2";
const char STR_ESKY[] ="ESky";
@ -124,6 +125,7 @@ const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8c
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
const char STR_SUBTYPE_FRSKY_RX[] = "\x07""RX\0 ""CloneTX";
const char STR_SUBTYPE_FRSKYL[] = "\x08""LR12\0 ""LR12 6ch";
enum
{
@ -334,6 +336,9 @@ const mm_protocol_definition multi_protocols[] = {
#endif
#if defined(PROPEL_NRF24L01_INO)
{PROTO_PROPEL, STR_PROPEL, 4, STR_SUBTYPE_PROPEL, OPTION_NONE },
#endif
#if defined(FRSKYL_CC2500_INO)
{PROTO_FRSKYL, STR_FRSKYL, 2, STR_SUBTYPE_FRSKYL, OPTION_RFTUNE },
#endif
{0x00, nullptr, 0, nullptr, 0 }
};

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 85
#define VERSION_PATCH_LEVEL 86
//******************
// Protocols
@ -93,6 +93,7 @@ enum PROTOCOLS
PROTO_FRSKYX2 = 64, // =>CC2500
PROTO_FRSKY_R9 = 65, // =>SX1276
PROTO_PROPEL = 66, // =>NRF24L01
PROTO_FRSKYL = 67, // =>CC2500
};
enum Flysky
@ -340,6 +341,12 @@ enum FRSKY_RX
FRSKY_CLONE = 1,
};
enum FRSKYL
{
LR12 = 0,
LR12_6CH = 1,
};
#define NONE 0
#define P_HIGH 1
#define P_LOW 0
@ -894,8 +901,11 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
ESKY_STD 0
ESKY_ET4 1
sub_protocol==FRSKY_RX
FRSKY_RX = 0,
FRSKY_CLONE = 1,
FRSKY_RX 0
FRSKY_CLONE 1
sub_protocol==FRSKYL
LR12 0
LR12_6CH 1
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;

View File

@ -504,6 +504,11 @@ void setup()
option = FORCE_FRSKYD_TUNING; // Use config-defined tuning value for FrSkyD
else
#endif
#if defined(FORCE_FRSKYL_TUNING) && defined(FRSKYL_CC2500_INO)
if(protocol==PROTO_FRSKYL)
option = FORCE_FRSKYL_TUNING; // Use config-defined tuning value for FrSkyL
else
#endif
#if defined(FORCE_FRSKYV_TUNING) && defined(FRSKYV_CC2500_INO)
if(protocol==PROTO_FRSKYV)
option = FORCE_FRSKYV_TUNING; // Use config-defined tuning value for FrSkyV
@ -753,8 +758,8 @@ bool Update_All()
{ // Autobind is on and BIND_CH went down
BIND_CH_PREV_off;
//Request protocol to terminate bind
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYL_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYL || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
BIND_DONE;
else
#endif
@ -1112,6 +1117,14 @@ static void protocol_init()
remote_callback = ReadFrSky_2way;
break;
#endif
#if defined(FRSKYL_CC2500_INO)
case PROTO_FRSKYL:
PE1_off; //antenna RF2
PE2_on;
next_callback = initFrSkyL();
remote_callback = ReadFrSkyL;
break;
#endif
#if defined(FRSKYV_CC2500_INO)
case PROTO_FRSKYV:
PE1_off; //antenna RF2
@ -1604,10 +1617,15 @@ void update_serial_data()
//Forced frequency tuning values for CC2500 protocols
#if defined(FORCE_FRSKYD_TUNING) && defined(FRSKYD_CC2500_INO)
if(protocol==PROTO_FRSKYD)
if(protocol==PROTO_FRSKYD)
option=FORCE_FRSKYD_TUNING; // Use config-defined tuning value for FrSkyD
else
#endif
#if defined(FORCE_FRSKYL_TUNING) && defined(FRSKYL_CC2500_INO)
if(protocol==PROTO_FRSKYL)
option=FORCE_FRSKYL_TUNING; // Use config-defined tuning value for FrSkyL
else
#endif
#if defined(FORCE_FRSKYV_TUNING) && defined(FRSKYV_CC2500_INO)
if(protocol==PROTO_FRSKYV)
option=FORCE_FRSKYV_TUNING; // Use config-defined tuning value for FrSkyV
@ -1720,8 +1738,8 @@ void update_serial_data()
else
if( ((rx_ok_buff[1]&0x80)==0) && ((cur_protocol[1]&0x80)!=0) ) // Bind flag has been reset
{ // Request protocol to end bind
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO)
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9 )
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYL_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO)
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYL || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9 )
BIND_DONE;
else
#endif

View File

@ -202,6 +202,7 @@
#endif
#ifndef CC2500_INSTALLED
#undef FRSKYD_CC2500_INO
#undef FRSKYL_CC2500_INO
#undef FRSKYV_CC2500_INO
#undef FRSKYX_CC2500_INO
#undef SFHSS_CC2500_INO

View File

@ -92,6 +92,7 @@
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
//#define FORCE_CORONA_TUNING 0
//#define FORCE_FRSKYD_TUNING 0
//#define FORCE_FRSKYL_TUNING 0
//#define FORCE_FRSKYV_TUNING 0
//#define FORCE_FRSKYX_TUNING 0
//#define FORCE_SFHSS_TUNING 0
@ -176,6 +177,7 @@
//The protocols below need a CC2500 to be installed
#define CORONA_CC2500_INO
#define FRSKYD_CC2500_INO
#define FRSKYL_CC2500_INO
#define FRSKYV_CC2500_INO
#define FRSKYX_CC2500_INO
#define FRSKY_RX_CC2500_INO
@ -563,6 +565,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FRSKY_CLONE
PROTO_FRSKYD
NONE
PROTO_FRSKYL
LR12
LR12_6CH
PROTO_FRSKYR9
R9_915
R9_868

View File

@ -86,8 +86,9 @@ CFlie|38|CFlie||||||||NRF24L01|
[Flysky AFHDS2A](Protocols_Details.md#FLYSKY-AFHDS2A---28)|28|PWM_IBUS|PPM_IBUS|PWM_SBUS|PPM_SBUS|||||A7105|
[Flysky AFHDS2A RX](Protocols_Details.md#FLYSKY-AFHDS2A-RX---56)|56|||||||||A7105|
[Flyzone](Protocols_Details.md#FLYZONE---53)|53|FZ410||||||||A7105|
[FQ777](Protocols_Details.md#FQ777---23)|23|FQ777||||||||NRF24L01|SSV7241
[FrskyD](Protocols_Details.md#FRSKYD---3)|3|FrskyD||||||||CC2500|
[FQ777](Protocols_Details.md#FQ777---23)|23|||||||||NRF24L01|SSV7241
[FrskyD](Protocols_Details.md#FRSKYD---3)|3|||||||||CC2500|
[FrskyL](Protocols_Details.md#FRSKYL---67)|67|LR12|LR12 6CH|||||||CC2500|
[FrskyR9](Protocols_Details.md#FRSKYR9---65)|65|FrskyR9|R9_915|R9_868||||||SX1276|
[FrskyV](Protocols_Details.md#FRSKYV---25)|25|FrskyV||||||||CC2500|
[FrskyX](Protocols_Details.md#FRSKYX---15)|15|CH_16|CH_8|EU_16|EU_8|||||CC2500|
@ -335,6 +336,28 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
## FRSKYL - *67*
Models: FrSky receivers L9R. Also known as LR12.
Extended limits supported
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
### Sub_protocol LR12 - *0*
Refresh rate: 36ms
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
---|---|---|---|---|---|---|---|---|----|----|----
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
### Sub_protocol LR12 6ch - *1*
Refresh rate: 18ms
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
CH1|CH2|CH3|CH4|CH5|CH6
## FRSKYX - *15*
Models: FrSky v1.xxx receivers X4R, X6R and X8R. Protocol also known as D16.