@@ -33,29 +33,59 @@ Multiprotocol is distributed in the hope that it will be useful,
3333#define FX620_PAYLOAD_SIZE 7
3434#define FX620_CH_OFFSET 1
3535
36+ #define FX9630_PACKET_PERIOD 8124
37+ #define FX9630_BIND_PACKET_PERIOD 8124
38+ #define FX9630_BIND_CHANNEL 51
39+ #define FX9630_PAYLOAD_SIZE 8
40+ #define FX9630_NUM_CHANNELS 3
41+
3642// #define FORCE_FX620_ID
43+ // #define FORCE_FX9630_ID
3744
3845static void __attribute__ ((unused)) FX_send_packet()
3946{
4047 // Hopp
4148 if (IS_BIND_DONE)
4249 {
4350 XN297_Hopping (hopping_frequency_no++);
44- hopping_frequency_no &= 0x03 ;
51+ if (sub_protocol == FX9630)
52+ {
53+ XN297_SetTXAddr (rx_tx_addr, 4 );
54+ if (hopping_frequency_no > FX9630_NUM_CHANNELS)
55+ hopping_frequency_no = 0 ;
56+ }
57+ else // FX816 and FX620
58+ {
59+ hopping_frequency_no &= 0x03 ;
60+ }
4561 }
4662
4763 memset (packet,0x00 ,packet_length);
4864
4965 // Channels
50- uint8_t offset=sub_protocol == FX816 ? FX816_CH_OFFSET:FX620_CH_OFFSET;
51- uint8_t val=convert_channel_8b (AILERON);
52- if (val>127 +FX_SWITCH)
53- packet[offset] = sub_protocol == FX816 ? 1 :0xFF ;
54- else if (val<127 -FX_SWITCH)
55- packet[offset] = sub_protocol == FX816 ? 2 :0x00 ;
56- else
57- packet[offset] = sub_protocol == FX816 ? 0 :0x7F ;
58- packet[offset+1 ] = convert_channel_16b_limit (THROTTLE,0 ,100 ); // FX816:0x00..0x63, FX620:0x00..0x5E but that should work
66+ uint8_t val;
67+ if (sub_protocol == FX9630)
68+ {
69+ packet[0 ] = convert_channel_8b (THROTTLE);
70+ packet[1 ] = convert_channel_8b (AILERON);
71+ packet[2 ] = 0xFF - convert_channel_8b (ELEVATOR);
72+ packet[3 ] = convert_channel_8b (RUDDER);
73+ packet[4 ] = 0x20 ;
74+ packet[5 ] = GET_FLAG (CH5_SW, 0x01 ); // DR toggle swich: 0 small throw, 1 large throw
75+ 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
76+ }
77+ else // FX816 and FX620
78+ {
79+ uint8_t offset=sub_protocol == FX816 ? FX816_CH_OFFSET:FX620_CH_OFFSET;
80+ val=convert_channel_8b (AILERON);
81+ if (val>127 +FX_SWITCH)
82+ packet[offset] = sub_protocol == FX816 ? 1 :0xFF ;
83+ else if (val<127 -FX_SWITCH)
84+ packet[offset] = sub_protocol == FX816 ? 2 :0x00 ;
85+ else
86+ packet[offset] = sub_protocol == FX816 ? 0 :0x7F ;
87+ packet[offset+1 ] = convert_channel_16b_limit (THROTTLE,0 ,100 ); // FX816:0x00..0x63, FX620:0x00..0x5E but that should work
88+ }
5989
6090 // Bind and specifics
6191 if (sub_protocol == FX816)
@@ -67,7 +97,7 @@ static void __attribute__((unused)) FX_send_packet()
6797 packet[1 ] = rx_tx_addr[0 ];
6898 packet[2 ] = rx_tx_addr[1 ];
6999 }
70- else // FX620
100+ else if (sub_protocol == FX620)
71101 {
72102 if (IS_BIND_IN_PROGRESS)
73103 {
@@ -82,12 +112,27 @@ static void __attribute__((unused)) FX_send_packet()
82112 packet[5 ] = 0xAB ; // Is it based on ID??
83113 }
84114 }
115+ else // FX9630
116+ {
117+ if (IS_BIND_IN_PROGRESS)
118+ {
119+ memcpy (packet,rx_tx_addr, 4 );
120+ packet[4 ] = hopping_frequency[1 ];
121+ packet[5 ] = hopping_frequency[2 ];
122+ packet[7 ] = 0x55 ;
123+ }
124+ }
85125
86126 // Check
127+ uint8_t last_packet_idx = packet_length-1 ;
128+ if (sub_protocol == FX9630 && IS_BIND_IN_PROGRESS)
129+ last_packet_idx--;
87130 val=0 ;
88- for (uint8_t i=0 ;i<packet_length- 1 ;i++)
131+ for (uint8_t i=0 ;i<last_packet_idx ;i++)
89132 val+=packet[i];
90- packet[packet_length-1 ]=val;
133+ if (sub_protocol == FX9630)
134+ val = val ^ 0xFF ;
135+ packet[last_packet_idx]=val;
91136
92137 // Debug
93138 #if 0
@@ -112,13 +157,20 @@ static void __attribute__((unused)) FX_RF_init()
112157 packet_period = FX816_PACKET_PERIOD;
113158 packet_length = FX816_PAYLOAD_SIZE;
114159 }
115- else // FX620
160+ else if (sub_protocol == FX620)
116161 {
117162 XN297_SetTXAddr ((uint8_t *)" \xaa\xbb\xcc " , 3 );
118163 XN297_RFChannel (FX620_BIND_CHANNEL);
119164 packet_period = FX620_BIND_PACKET_PERIOD;
120165 packet_length = FX620_PAYLOAD_SIZE;
121166 }
167+ else // FX9630
168+ {
169+ XN297_SetTXAddr ((uint8_t *)" \x56\x78\x90\x12 " , 4 );
170+ XN297_RFChannel (FX9630_BIND_CHANNEL);
171+ packet_period = FX9630_BIND_PACKET_PERIOD;
172+ packet_length = FX9630_PAYLOAD_SIZE;
173+ }
122174}
123175
124176static void __attribute__ ((unused)) FX_initialize_txid()
@@ -133,7 +185,7 @@ static void __attribute__((unused)) FX_initialize_txid()
133185 for (uint8_t i=0 ;i<FX_NUM_CHANNELS;i++)
134186 hopping_frequency[i]+=rx_tx_addr[3 ]&0x07 ;
135187 }
136- else // FX620
188+ else if (sub_protocol == FX620)
137189 {
138190 rx_tx_addr[0 ] = rx_tx_addr[3 ];
139191 hopping_frequency[0 ] = 0x18 + rx_tx_addr[3 ]&0x07 ; // just to try something
@@ -144,6 +196,17 @@ static void __attribute__((unused)) FX_initialize_txid()
144196 for (uint8_t i=1 ;i<FX_NUM_CHANNELS;i++)
145197 hopping_frequency[i] = i*10 + hopping_frequency[0 ];
146198 }
199+ else // FX9630
200+ {
201+ #ifdef FORCE_FX9630_ID
202+ memcpy (rx_tx_addr,(uint8_t *)" \xCE\x31\x9B\x73 " , 4 );
203+ memcpy (hopping_frequency," \x13\x1A\x38 " , FX9630_NUM_CHANNELS); // Original dump=19=0x13,26=0x1A,56=0x38
204+ #else
205+ hopping_frequency[0 ] = 0x13 ; // constant
206+ hopping_frequency[1 ] = RX_num & 0x0F + 0x1A ;
207+ hopping_frequency[2 ] = rx_tx_addr[3 ] & 0x0F + 0x38 ;
208+ #endif
209+ }
147210}
148211
149212uint16_t FX_callback ()
0 commit comments