diff --git a/Multiprotocol/Convert.ino b/Multiprotocol/Convert.ino
index 944c3a0..5f58218 100644
--- a/Multiprotocol/Convert.ino
+++ b/Multiprotocol/Convert.ino
@@ -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;
}
diff --git a/Multiprotocol/FrSkyDVX_common.ino b/Multiprotocol/FrSkyDVX_common.ino
index 38fbf85..0a07ad7 100644
--- a/Multiprotocol/FrSkyDVX_common.ino
+++ b/Multiprotocol/FrSkyDVX_common.ino
@@ -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
diff --git a/Multiprotocol/FrSkyL_cc2500.ino b/Multiprotocol/FrSkyL_cc2500.ino
new file mode 100644
index 0000000..986fc73
--- /dev/null
+++ b/Multiprotocol/FrSkyL_cc2500.ino
@@ -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 .
+ */
+
+
+#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.
-*/
+/*
+ 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 .
+ */
#if defined(FRSKYX_CC2500_INO)
diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt
index c132526..9aa150a 100644
--- a/Multiprotocol/Multi.txt
+++ b/Multiprotocol/Multi.txt
@@ -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
diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino
index 00a5b65..60cf6e8 100644
--- a/Multiprotocol/Multi_Names.ino
+++ b/Multiprotocol/Multi_Names.ino
@@ -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 }
};
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index 41ef5c5..a94a37f 100644
--- a/Multiprotocol/Multiprotocol.h
+++ b/Multiprotocol/Multiprotocol.h
@@ -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;
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index 3e8da97..330eb0c 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -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
diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h
index 383baec..d30152b 100644
--- a/Multiprotocol/Validate.h
+++ b/Multiprotocol/Validate.h
@@ -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
diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h
index 83e535d..3fdaa67 100644
--- a/Multiprotocol/_Config.h
+++ b/Multiprotocol/_Config.h
@@ -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
diff --git a/Protocols_Details.md b/Protocols_Details.md
index 960f813..80cd98b 100644
--- a/Protocols_Details.md
+++ b/Protocols_Details.md
@@ -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.