FX9630 protocol support, resolves #801 (#805)

New protocol FX9630
This commit is contained in:
richardclli 2023-01-17 03:06:27 +08:00 committed by GitHub
parent 11c01004bf
commit 0fed2486f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 18 deletions

View File

@ -33,7 +33,14 @@ Multiprotocol is distributed in the hope that it will be useful,
#define FX620_PAYLOAD_SIZE 7 #define FX620_PAYLOAD_SIZE 7
#define FX620_CH_OFFSET 1 #define FX620_CH_OFFSET 1
#define FX9630_PACKET_PERIOD 8124
#define FX9630_BIND_PACKET_PERIOD 8124
#define FX9630_BIND_CHANNEL 51
#define FX9630_PAYLOAD_SIZE 8
#define FX9630_NUM_CHANNELS 3
//#define FORCE_FX620_ID //#define FORCE_FX620_ID
//#define FORCE_FX9630_ID
static void __attribute__((unused)) FX_send_packet() static void __attribute__((unused)) FX_send_packet()
{ {
@ -41,21 +48,44 @@ static void __attribute__((unused)) FX_send_packet()
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {
XN297_Hopping(hopping_frequency_no++); XN297_Hopping(hopping_frequency_no++);
hopping_frequency_no &= 0x03; if(sub_protocol == FX9630)
{
XN297_SetTXAddr(rx_tx_addr, 4);
if (hopping_frequency_no > FX9630_NUM_CHANNELS)
hopping_frequency_no = 0;
}
else // FX816 and FX620
{
hopping_frequency_no &= 0x03;
}
} }
memset(packet,0x00,packet_length); memset(packet,0x00,packet_length);
//Channels //Channels
uint8_t offset=sub_protocol == FX816 ? FX816_CH_OFFSET:FX620_CH_OFFSET; uint8_t val;
uint8_t val=convert_channel_8b(AILERON); if (sub_protocol == FX9630)
if(val>127+FX_SWITCH) {
packet[offset] = sub_protocol == FX816 ? 1:0xFF; packet[0] = convert_channel_8b(THROTTLE);
else if(val<127-FX_SWITCH) packet[1] = convert_channel_8b(AILERON);
packet[offset] = sub_protocol == FX816 ? 2:0x00; packet[2] = 0xFF - convert_channel_8b(ELEVATOR);
else packet[3] = convert_channel_8b(RUDDER);
packet[offset] = sub_protocol == FX816 ? 0:0x7F; packet[4] = 0x20;
packet[offset+1] = convert_channel_16b_limit(THROTTLE,0,100); //FX816:0x00..0x63, FX620:0x00..0x5E but that should work packet[5] = GET_FLAG(CH5_SW, 0x01); // DR toggle swich: 0 small throw, 1 large throw
packet[5] |= (Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x02 : 0x01)) << 1; // Mode A(0) : 6D small throw, B(1) : 6D large throw, C(2) : 3D
}
else // FX816 and FX620
{
uint8_t offset=sub_protocol == FX816 ? FX816_CH_OFFSET:FX620_CH_OFFSET;
val=convert_channel_8b(AILERON);
if(val>127+FX_SWITCH)
packet[offset] = sub_protocol == FX816 ? 1:0xFF;
else if(val<127-FX_SWITCH)
packet[offset] = sub_protocol == FX816 ? 2:0x00;
else
packet[offset] = sub_protocol == FX816 ? 0:0x7F;
packet[offset+1] = convert_channel_16b_limit(THROTTLE,0,100); //FX816:0x00..0x63, FX620:0x00..0x5E but that should work
}
//Bind and specifics //Bind and specifics
if(sub_protocol == FX816) if(sub_protocol == FX816)
@ -67,7 +97,7 @@ static void __attribute__((unused)) FX_send_packet()
packet[1] = rx_tx_addr[0]; packet[1] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1]; packet[2] = rx_tx_addr[1];
} }
else //FX620 else if(sub_protocol == FX620)
{ {
if(IS_BIND_IN_PROGRESS) if(IS_BIND_IN_PROGRESS)
{ {
@ -82,12 +112,27 @@ static void __attribute__((unused)) FX_send_packet()
packet[5] = 0xAB; // Is it based on ID?? packet[5] = 0xAB; // Is it based on ID??
} }
} }
else // FX9630
{
if(IS_BIND_IN_PROGRESS)
{
memcpy(packet,rx_tx_addr, 4);
packet[4] = hopping_frequency[1];
packet[5] = hopping_frequency[2];
packet[7] = 0x55;
}
}
//Check //Check
uint8_t last_packet_idx = packet_length-1;
if (sub_protocol == FX9630 && IS_BIND_IN_PROGRESS)
last_packet_idx--;
val=0; val=0;
for(uint8_t i=0;i<packet_length-1;i++) for(uint8_t i=0;i<last_packet_idx;i++)
val+=packet[i]; val+=packet[i];
packet[packet_length-1]=val; if (sub_protocol == FX9630)
val = val ^ 0xFF;
packet[last_packet_idx]=val;
//Debug //Debug
#if 0 #if 0
@ -112,13 +157,20 @@ static void __attribute__((unused)) FX_RF_init()
packet_period = FX816_PACKET_PERIOD; packet_period = FX816_PACKET_PERIOD;
packet_length = FX816_PAYLOAD_SIZE; packet_length = FX816_PAYLOAD_SIZE;
} }
else //FX620 else if(sub_protocol == FX620)
{ {
XN297_SetTXAddr((uint8_t *)"\xaa\xbb\xcc", 3); XN297_SetTXAddr((uint8_t *)"\xaa\xbb\xcc", 3);
XN297_RFChannel(FX620_BIND_CHANNEL); XN297_RFChannel(FX620_BIND_CHANNEL);
packet_period = FX620_BIND_PACKET_PERIOD; packet_period = FX620_BIND_PACKET_PERIOD;
packet_length = FX620_PAYLOAD_SIZE; packet_length = FX620_PAYLOAD_SIZE;
} }
else // FX9630
{
XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4);
XN297_RFChannel(FX9630_BIND_CHANNEL);
packet_period = FX9630_BIND_PACKET_PERIOD;
packet_length = FX9630_PAYLOAD_SIZE;
}
} }
static void __attribute__((unused)) FX_initialize_txid() static void __attribute__((unused)) FX_initialize_txid()
@ -133,7 +185,7 @@ static void __attribute__((unused)) FX_initialize_txid()
for(uint8_t i=0;i<FX_NUM_CHANNELS;i++) for(uint8_t i=0;i<FX_NUM_CHANNELS;i++)
hopping_frequency[i]+=rx_tx_addr[3]&0x07; hopping_frequency[i]+=rx_tx_addr[3]&0x07;
} }
else//FX620 else if(sub_protocol == FX620)
{ {
rx_tx_addr[0] = rx_tx_addr[3]; rx_tx_addr[0] = rx_tx_addr[3];
hopping_frequency[0] = 0x18 + rx_tx_addr[3]&0x07; // just to try something hopping_frequency[0] = 0x18 + rx_tx_addr[3]&0x07; // just to try something
@ -144,6 +196,17 @@ static void __attribute__((unused)) FX_initialize_txid()
for(uint8_t i=1;i<FX_NUM_CHANNELS;i++) for(uint8_t i=1;i<FX_NUM_CHANNELS;i++)
hopping_frequency[i] = i*10 + hopping_frequency[0]; hopping_frequency[i] = i*10 + hopping_frequency[0];
} }
else // FX9630
{
#ifdef FORCE_FX9630_ID
memcpy(rx_tx_addr,(uint8_t*)"\xCE\x31\x9B\x73", 4);
memcpy(hopping_frequency,"\x13\x1A\x38", FX9630_NUM_CHANNELS); //Original dump=19=0x13,26=0x1A,56=0x38
#else
hopping_frequency[0] = 0x13; // constant
hopping_frequency[1] = RX_num & 0x0F + 0x1A;
hopping_frequency[2] = rx_tx_addr[3] & 0x0F + 0x38;
#endif
}
} }
uint16_t FX_callback() uint16_t FX_callback()

View File

@ -55,7 +55,7 @@
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM 55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
56,AFHDS2A_RX,Multi,CPPM 56,AFHDS2A_RX,Multi,CPPM
57,HoTT,Sync,No_Sync 57,HoTT,Sync,No_Sync
58,FX,816,620 58,FX,816,620,9630
59,Bayang_RX,Multi,CPPM 59,Bayang_RX,Multi,CPPM
60,Pelikan,Pro,Lite,SCX24 60,Pelikan,Pro,Lite,SCX24
61,Tiger 61,Tiger

View File

@ -173,7 +173,7 @@ const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0"; const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0"; const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0";
const char STR_SUBTYPE_E129[] = "\x04""E129""C186"; const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
const char STR_SUBTYPE_FX[] = "\x03""816""620"; const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630";
#define NO_SUBTYPE nullptr #define NO_SUBTYPE nullptr
#ifdef SEND_CPPM #ifdef SEND_CPPM
@ -315,7 +315,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback }, {PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
#endif #endif
#if defined(FX_NRF24L01_INO) #if defined(FX_NRF24L01_INO)
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 2, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback }, {PROTO_FX, STR_FX, STR_SUBTYPE_FX, 3, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
#endif #endif
#if defined(FY326_NRF24L01_INO) #if defined(FY326_NRF24L01_INO)
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback }, {PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },

View File

@ -461,6 +461,7 @@ enum FX
{ {
FX816 = 0, FX816 = 0,
FX620 = 1, FX620 = 1,
FX9630 = 2,
}; };
#define NONE 0 #define NONE 0

View File

@ -670,6 +670,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_FX PROTO_FX
FX816 FX816
FX620 FX620
FX9630
PROTO_FY326 PROTO_FY326
FY326 FY326
FY319 FY319