Traxxas TQ 1st gen: try 5
[DIY-Multiprotocol-TX-Module.git] / Multiprotocol / MLINK_cyrf6936.ino
blob3f0d0efcc2dbdfed4e35edbd76f49aff68f998d4
1 /*
2  This project is free software: you can redistribute it and/or modify
3  it under the terms of the GNU General Public License as published by
4  the Free Software Foundation, either version 3 of the License, or
5  (at your option) any later version.
7  Multiprotocol is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  GNU General Public License for more details.
12  You should have received a copy of the GNU General Public License
13  along with Multiprotocol.  If not, see <http://www.gnu.org/licenses/>.
14  */
16 #if defined(MLINK_CYRF6936_INO)
18 #include "iface_cyrf6936.h"
20 //#define MLINK_FORCE_ID
21 #define MLINK_BIND_COUNT        696     // around 20s
22 #define MLINK_NUM_FREQ          78
23 #define MLINK_BIND_CHANNEL      0x01
24 #define MLINK_PACKET_SIZE       8
26 enum {
27         MLINK_BIND_TX=0,
28         MLINK_BIND_PREP_RX,
29         MLINK_BIND_RX,
30         MLINK_PREP_DATA,
31         MLINK_SEND1,
32         MLINK_SEND2,
33         MLINK_SEND3,
34         MLINK_CHECK3,
35         MLINK_RX,
36         MLINK_BUILD4,
39 uint8_t MLINK_Data_Code[16], MLINK_CRC_Init, MLINK_Unk_6_2;
41 const uint8_t PROGMEM MLINK_init_vals[][2] = {
42         //Init from dump
43         { CYRF_01_TX_LENGTH,    0x08 }, // Length of packet
44         { CYRF_02_TX_CTRL,              0x40 }, // Clear TX Buffer
45         { CYRF_03_TX_CFG,               0x3C }, //0x3E in normal mode, 0x3C in bind mode: SDR 64 chip codes (=8 bytes data code used)
46         { CYRF_05_RX_CTRL,              0x00 },
47         { CYRF_06_RX_CFG,               0x93 }, // AGC enabled, overwrite enable, valid flag enable
48         { CYRF_0B_PWR_CTRL,             0x00 },
49         //{ CYRF_0C_XTAL_CTRL,  0x00 }, // Set to GPIO on reset
50         //{ CYRF_0D_IO_CFG,             0x00 }, // Set to GPIO on reset
51         //{ CYRF_0E_GPIO_CTRL,  0x00 }, // Set by the CYRF_SetTxRxMode function
52         { CYRF_0F_XACT_CFG,             0x04 }, // end state idle
53         { CYRF_10_FRAMING_CFG,  0x00 }, // SOP disabled
54         { CYRF_11_DATA32_THOLD, 0x05 }, // not used???
55         { CYRF_12_DATA64_THOLD, 0x0F }, // 64 Chip Data PN Code Correlator Threshold
56         { CYRF_14_EOP_CTRL,             0x05 }, // 5 consecutive noncorrelations symbol for EOP
57         { CYRF_15_CRC_SEED_LSB, 0x00 }, // not used???
58         { CYRF_16_CRC_SEED_MSB, 0x00 }, // not used???
59         { CYRF_1B_TX_OFFSET_LSB,0x00 },
60         { CYRF_1C_TX_OFFSET_MSB,0x00 },
61         { CYRF_1D_MODE_OVERRIDE,0x00 },
62         { CYRF_1E_RX_OVERRIDE,  0x14 }, // RX CRC16 is disabled and Force Receive Data Rate
63         { CYRF_1F_TX_OVERRIDE,  0x04 }, // TX CRC16 is disabled
64         { CYRF_26_XTAL_CFG,             0x08 },
65         { CYRF_29_RX_ABORT,             0x00 },
66         { CYRF_32_AUTO_CAL_TIME,0x3C },
67         { CYRF_35_AUTOCAL_OFFSET,0x14 },
68         { CYRF_39_ANALOG_CTRL,  0x03 }, // Receive invert and all slow
71 static void __attribute__((unused)) MLINK_cyrf_config()
73         for(uint8_t i = 0; i < sizeof(MLINK_init_vals) / 2; i++)        
74                 CYRF_WriteRegister(pgm_read_byte_near(&MLINK_init_vals[i][0]), pgm_read_byte_near(&MLINK_init_vals[i][1]));
75         CYRF_WritePreamble(0x333304);
76         CYRF_SetTxRxMode(TX_EN);
79 static void __attribute__((unused)) MLINK_send_bind_packet()
81         uint8_t p_c=packet_count>>1;
82         
83         memset(packet, p_c<0x16?0x00:0xFF, MLINK_PACKET_SIZE-1);
84         packet[0]=0x0F; // bind
85         packet[1]=p_c;
86         switch(p_c)
87         {
88                 case 0x00:
89                         packet[2]=0x40;                 //unknown but seems constant
90                         packet[4]=0x01;                 //unknown but seems constant
91                         packet[5]=0x03;                 //unknown but seems constant
92                         packet[6]=0xE3;                 //unknown but seems constant
93                         break;
94                 case 0x05:
95                         packet[6]=MLINK_CRC_Init;       //CRC init value
96                         break;
97                 case 0x06:
98                         packet[2]=MLINK_Unk_6_2;        //unknown and different
99                         //Start of hopping frequencies
100                         for(uint8_t i=0;i<4;i++)
101                                 packet[i+3]=hopping_frequency[i];
102                         break;
103                 case 0x15:
104                         packet[6]=0x51;                 //unknown but seems constant
105                         break;
106                 case 0x16:
107                         packet[2]=0x51;                 //unknown but seems constant
108                         packet[3]=0xEC;                 //unknown but seems constant
109                         packet[4]=0x05;                 //unknown but seems constant
110                         break;
111                 case 0x1A:
112                         packet[1]=0xFF;
113                         memset(&packet[2],0x00,5);
114                         break;
115         }
116         if(p_c>=0x01 && p_c<=0x04)
117         {//DATA_CODE
118                 uint8_t p_c_5=(p_c-1)*5;
119                 for(uint8_t i=0;i<5;i++)
120                         if(i+p_c_5<16)
121                                 packet[i+2]=MLINK_Data_Code[i+p_c_5];
122         }
123         else
124                 if(p_c>=0x07 && p_c<=0x15)
125                 {//Hopping frequencies
126                         uint8_t p_c_5=5*(p_c-6)-1;
127                         for(uint8_t i=0;i<5;i++)
128                                 if(i+p_c_5<MLINK_NUM_FREQ)
129                                         packet[i+2]=hopping_frequency[i+p_c_5];
130                 }
131                 else
132                         if(p_c>0x19)
133                         {
134                                 packet[1]=0xFF;
135                                 memset(&packet[2], 0x00, MLINK_PACKET_SIZE-3);
136                         }
138         //Calculate CRC
139         crc8=0xFF;      // Init = 0xFF
140         for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
141                 crc8_update(bit_reverse(packet[i]));
142         packet[7] = bit_reverse(crc8);                  // CRC reflected out
144         //Debug
145         #if 0
146                 debug("P(%02d):",p_c);
147                 for(uint8_t i=0;i<8;i++)
148                         debug(" %02X",packet[i]);
149                 debugln("");
150         #endif
152         //Send packet
153         CYRF_WriteDataPacketLen(packet, MLINK_PACKET_SIZE);
156 static void __attribute__((unused)) MLINK_send_data_packet()
158         static uint8_t tog=0;
159         uint8_t start;
160         
161 #ifdef FAILSAFE_ENABLE
162         static uint8_t fs=0;
163         if(IS_FAILSAFE_VALUES_on && phase==MLINK_SEND1)
164         {
165                 fs=10;  // Original radio is sending 70 packets
166                 FAILSAFE_VALUES_off;
167         }
168         if(fs)
169         {// Failsafe packets
170                 switch(phase)
171                 {
172                         case MLINK_SEND2:
173                                 packet[0]=0x06;
174                                 start=17;
175                                 break;
176                         case MLINK_SEND3:
177                                 packet[0]=0x84;
178                                 start=5;
179                                 fs--;
180                                 break;
181                         default: //MLINK_SEND1:
182                                 packet[0]=0x05;
183                                 start=11;
184                                 break;
185                 }
186                 //Pack 6 channels per packet
187                 for(uint8_t i=0;i<6;i++)
188                 {
189                         uint8_t val=start<16 ? convert_channel_16b_nolimit(start,426 >> 4,3448 >> 4,true) : 0x00;
190                         start--;        // switch to next channel
191                         packet[i+1]=val;
192                 }
193         }
194         else
195 #endif
196         {// Normal packets
197                 if(hopping_frequency_no==0)
198                         tog=1;
199                 //Channels to be sent
200                 if(phase==MLINK_SEND1 || ((hopping_frequency_no%5==0) && (phase==MLINK_SEND2)))
201                 {
202                         if((hopping_frequency_no&1)==0)
203                                 packet[0] = 0x09;       //10,8,6
204                         else
205                                 packet[0] = 0x01;       //11,9,7
206                 }
207                 else
208                         if(phase==MLINK_SEND2)
209                         {
210                                 if(tog)
211                                         packet[0] = 0x02;       //x,15,13
212                                 else
213                                         packet[0] = 0x0A;       //x,14,12
214                                 tog^=1;
215                         }
216                         else
217                         {//phase==MLINK_SEND3
218                                 if((hopping_frequency_no&1)==0)
219                                         packet[0] = 0x88;       //4,2,0
220                                 else
221                                         packet[0] = 0x80;       //5,3,1
222                         }
224                 //Start channel
225                 start=4+6*(packet[0]&3);
226                 if((packet[0]&0x08)==0)
227                         start++;
228                 
229                 //Channels 426..1937..3448
230                 for(uint8_t i=0;i<3;i++)
231                 {
232                         uint16_t val=start<16 ? convert_channel_16b_nolimit(start,426,3448,false) : 0x0000;
233                         start-=2;       // switch to next channel
234                         packet[i*2+1]=val>>8;
235                         packet[i*2+2]=val;
236                 }
237         }
239         //Calculate CRC
240         crc8=bit_reverse(hopping_frequency_no + MLINK_CRC_Init);        // Init = relected freq index + offset
241         for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
242                 crc8_update(bit_reverse(packet[i]));
243         packet[7] = bit_reverse(crc8);                  // CRC reflected out
245         //Send
246         CYRF_WriteDataPacketLen(packet, MLINK_PACKET_SIZE);
248         //Debug
249         #if 0
250                 debug("P(%02d):",hopping_frequency_no);
251                 for(uint8_t i=0;i<8;i++)
252                         debug(" %02X",packet[i]);
253                 debugln("");
254         #endif
257 #ifdef MLINK_HUB_TELEMETRY
258         static void __attribute__((unused)) MLINK_Send_Telemetry()
259         { // not sure how MLINK telemetry works, the 2 RXs I have are sending something completly different...
260                 telemetry_counter += 2;                         // TX LQI counter
261                 telemetry_link = 1;
263                 if(packet_in[0]==0x13)
264                 { // RX-9-DR : 13 1A C8 00 01 64 00
265                         uint8_t id;
266                         for(uint8_t i=1; i<5; i+=3)
267                         {//2 sensors per packet
268                                 id=0x00;
269                                 switch(packet_in[i]&0x0F)
270                                 {
271                                         case 1: //voltage
272                                                 if((packet_in[i]&0xF0) == 0x00)
273                                                         v_lipo1 = packet_in[i+1];               // Rx_Batt*20
274                                                 else
275                                                         v_lipo2 = packet_in[i+1];
276                                                 break;
277                                         case 2: //current
278                                                 id = 0x28;
279                                                 break;
280                                         case 3: //vario
281                                                 id = 0x30;
282                                                 break;
283                                         case 5: //rpm
284                                                 id = 0x03;
285                                                 break;
286                                         case 6: //temp
287                                                 id = 0x02;
288                                                 break;
289                                         case 10: //lqi
290                                                 RX_RSSI=RX_LQI=packet_in[i+1]>>1;
291                                                 break;
292                                 }
293                                 #if defined HUB_TELEMETRY
294                                         if(id)
295                                         {
296                                                 uint16_t val=((packet_in[i+2]&0x80)<<8)|((packet_in[i+2]&0x7F)<<7)|(packet_in[i+1]>>1); //remove the alarm LSB bit, move the sign bit to MSB
297                                                 frsky_send_user_frame(id, val, val>>8);
298                                         }
299                                 #endif
300                         }
301                 }
302                 else
303                         if(packet_in[0]==0x03)
304                         { // RX-5 :    03 15 23 00 00 01 02
305                                 //Incoming packet values
306                                 RX_RSSI = packet_in[2]<<1;      // Looks to be the RX RSSI value
307                                 RX_LQI  = packet_in[5];         // Looks to be connection lost
308                         }
309                         else
310                                 RX_RSSI = TX_LQI;
312                 // Read TX RSSI
313                 TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
315                 if(telemetry_lost)
316                 {
317                         telemetry_lost = 0;
318                         packet_count = 50;
319                         telemetry_counter = 100;
320                 }
321         }
322 #endif
324 #ifdef MLINK_FW_TELEMETRY
325         static void __attribute__((unused)) MLINK_Send_Telemetry()
326         {
327                 telemetry_counter += 2;                         // TX LQI counter
328                 telemetry_link = 4;
330                 // Read TX RSSI
331                 TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
333                 if(telemetry_lost)
334                 {
335                         telemetry_lost = 0;
336                         packet_count = 50;
337                         telemetry_counter = 100;
338                 }
339         }
340 #endif
342 uint16_t MLINK_callback()
344         uint8_t status;
345         uint16_t start;
347         switch(phase)
348         {
349                 case MLINK_BIND_RX:
350                         //debugln("RX");
351                         status=CYRF_ReadRegister(CYRF_05_RX_CTRL);
352                         if( (status&0x80) == 0 )
353                         {//Packet received
354                                 len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
355                                 debugln("L=%02X",len)
356                                 if( len==8 )
357                                 {
358                                         CYRF_ReadDataPacketLen(packet, len*2);
359                                         debug("RX=");
360                                         for(uint8_t i=0;i<8;i++)
361                                                 debug(" %02X",packet[i*2]);
362                                         debugln("");
363                                         //Check CRC
364                                         crc8=0xFF;      // Init = 0xFF
365                                         for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
366                                                 crc8_update(bit_reverse(packet[i<<1]));
367                                         if(packet[14] == bit_reverse(crc8))
368                                         {// CRC is ok
369                                                 debugln("CRC ok");
370                                                 if(packet[0]==0x7F)
371                                                         packet_count=3;                                 // Start sending bind payload
372                                                 else if(packet_count > 0x19*2)
373                                                 {
374                                                         if(packet[0] == 0x8F)
375                                                                 packet_count++;
376                                                         else if(packet[0] == 0x9F)
377                                                                 packet_count=0x80;                      // End bind
378                                                         else
379                                                                 packet_count=0;                         // Restart bind...
380                                                 }
381                                         }
382                                 }
383                         }
384                         else
385                                 packet_count=0;
386                         CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20);             // Enable RX abort
387                         CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);             // Force end state
388                         CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00);             // Disable RX abort
389                         phase=MLINK_BIND_TX;                                                    // Retry sending bind packet
390                         CYRF_SetTxRxMode(TX_EN);                                                // Transmit mode
391                         if(packet_count)
392                                 return 18136;
393                 case MLINK_BIND_TX:
394                         if(--bind_counter==0 || packet_count>=0x1B*2)
395                         { // Switch to normal mode
396                                 BIND_DONE;
397                                 phase=MLINK_PREP_DATA;
398                                 return 22720;
399                         }
400                         MLINK_send_bind_packet();
401                         if(packet_count == 0 || packet_count > 0x19*2)
402                         {
403                                 phase++;                // MLINK_BIND_PREP_RX
404                                 return 4700;    // Original is 4900
405                         }
406                         packet_count++;
407                         if(packet_count&1)
408                                 return 6000;
409                         return 22720;
410                 case MLINK_BIND_PREP_RX:
411                         start=micros();
412                         while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 200)    // Wait max 200µs for TX to finish
413                                 if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
414                                         break;                                                                          // Packet transmission complete
415                         CYRF_SetTxRxMode(RX_EN);                                                        // Receive mode
416                         CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x82);                      // Prepare to receive
417                         phase++;        //MLINK_BIND_RX
418                         if(packet_count > 0x19*2)
419                                 return 28712;                                                                   // Give more time to the RX to confirm that the bind is ok...
420                         return 28712-4700;
423                 case MLINK_PREP_DATA:
424                         CYRF_ConfigDataCode(MLINK_Data_Code);
425                         MLINK_CRC_Init += 0xED;
426                         hopping_frequency_no = 0x00;
427                         CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
428                         CYRF_SetPower(0x38);
429                         #if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
430                                 packet_count = 0;
431                                 telemetry_lost = 1;
432                         #endif
433                         phase++;
436                 case MLINK_SEND1:
437                         MLINK_send_data_packet();
438                         phase++;
439                         return 4880+1111;
440                 case MLINK_SEND2:
441                         MLINK_send_data_packet();
442                         phase++;
443                         if(hopping_frequency_no%5==0)
444                                 return 4617+1017;
445                         return 4617+1422;
446                 case MLINK_SEND3:
447                         MLINK_send_data_packet();
448                         phase++;
449                         return 4611;
450                 case MLINK_CHECK3:
451                         //Switch to next channel
452                         hopping_frequency_no++;
453                         if(hopping_frequency_no>=MLINK_NUM_FREQ)
454                                 hopping_frequency_no=0;
455                         CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
456                         
457                         //Receive telemetry
458                         if(hopping_frequency_no%5==0)
459                         {//Receive telemetry
460                                 CYRF_SetTxRxMode(RX_EN);                                                        // Receive mode
461                                 CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x82);                      // Prepare to receive
462                                 phase++;        //MLINK_RX
463                                 return 8038+2434+410-1000;
464                         }
465                         else
466                                 CYRF_SetPower(0x38);
467                         phase=MLINK_SEND1;
468                         return 4470;
469                 case MLINK_RX:
470                         #if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
471                                 //TX LQI calculation
472                                 packet_count++;
473                                 if(packet_count>=50)
474                                 {
475                                         packet_count=0;
476                                         TX_LQI=telemetry_counter;
477                                         if(telemetry_counter==0)
478                                                 telemetry_lost = 1;
479                                         telemetry_counter = 0;
480                                 }
481                         #endif
482                         status=CYRF_ReadRegister(CYRF_05_RX_CTRL);
483                         debug("T(%02X):",status);
484                         if( (status&0x80) == 0 )
485                         {//Packet received
486                                 len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
487                                 debug("(%X)",len)
488                                 if( len && len <= MLINK_PACKET_SIZE )
489                                 {
490                                         CYRF_ReadDataPacketLen(packet_in, len*2);
491                                         #if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
492                                                 if(len==MLINK_PACKET_SIZE)
493                                                 {
494                                                         for(uint8_t i=0;i<8;i++)
495                                                         //Check CRC
496                                                         crc8=bit_reverse(MLINK_CRC_Init);
497                                                         for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
498                                                         {
499                                                                 packet_in[i]=packet_in[i<<1];
500                                                                 crc8_update(bit_reverse(packet_in[i]));
501                                                                 debug(" %02X",packet_in[i]);
502                                                         }
503                                                         if(packet_in[14] == bit_reverse(crc8))  // Packet CRC is ok
504                                                                 MLINK_Send_Telemetry();
505                                                         else
506                                                                 debug(" NOK");
507                                                 }
508                                         #endif
509                                 }
510                         }
511                         debugln("");
512                         CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20);             // Enable RX abort
513                         CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);             // Force end state
514                         CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00);             // Disable RX abort
515                         CYRF_SetTxRxMode(TX_EN);                                                // Transmit mode
516                         phase=MLINK_SEND2;
517                         return 1000;
518         }
519         return 1000;
522 static void __attribute__((unused)) MLINK_shuffle_freqs(uint32_t seed, uint8_t *hop)
524         randomSeed(seed);
525         
526         for(uint8_t i=0; i < MLINK_NUM_FREQ/2; i++)
527         {
528                 uint8_t r   = random(0xfefefefe) % (MLINK_NUM_FREQ/2);
529                 uint8_t tmp = hop[r];
530                 hop[r] = hop[i];
531                 hop[i] = tmp;
532         }
535 void MLINK_init()
537         MLINK_cyrf_config();
539         //Init ID and RF freqs
540         for(uint8_t i=0; i < MLINK_NUM_FREQ/2; i++)
541         {
542                 hopping_frequency[i                 ] = (i<<1) + 3;
543                 hopping_frequency[i+MLINK_NUM_FREQ/2] = (i<<1) + 3;
544         }
545         // part1
546         memcpy(MLINK_Data_Code  ,rx_tx_addr,4);
547         MLINK_shuffle_freqs(MProtocol_id, hopping_frequency);
549         // part2
550         MProtocol_id ^= 0x6FBE3201;
551         set_rx_tx_addr(MProtocol_id);
552         memcpy(MLINK_Data_Code+4,rx_tx_addr,4);
553         MLINK_shuffle_freqs(MProtocol_id, &hopping_frequency[MLINK_NUM_FREQ/2]);
554         
555         // part3
556         MLINK_CRC_Init = rx_tx_addr[3];         //value sent during bind then used to init the CRC
557         MLINK_Unk_6_2  = 0x3A;          //unknown value sent during bind but doesn't seem to matter
558         
559         #ifdef MLINK_FORCE_ID
560                 if(RX_num)
561                 {
562                         //Cockpit SX
563                         memcpy(MLINK_Data_Code,"\x4C\x97\x9D\xBF\xB8\x3D\xB5\xBE",8);
564                         memcpy(hopping_frequency,"\x0D\x41\x09\x43\x17\x2D\x05\x31\x13\x3B\x1B\x3D\x0B\x41\x11\x45\x09\x2B\x17\x4D\x19\x3F\x03\x3F\x0F\x37\x1F\x47\x1B\x49\x07\x35\x27\x2F\x15\x33\x23\x39\x1F\x33\x19\x45\x0D\x2D\x11\x35\x0B\x47\x25\x3D\x21\x37\x1D\x3B\x05\x2F\x21\x39\x23\x4B\x03\x31\x25\x29\x07\x4F\x1D\x4B\x15\x4D\x13\x4F\x0F\x49\x29\x2B\x27\x43",MLINK_NUM_FREQ);
565                         MLINK_Unk_6_2  = 0x3A;          //unknown value sent during bind but doesn't seem to matter
566                         MLINK_CRC_Init = 0x07;          //value sent during bind then used to init the CRC
567                 }
568                 else
569                 {
570                         //HFM3
571                         memcpy(MLINK_Data_Code,"\xC0\x90\x8F\xBB\x7C\x8E\x2B\x8E",8);
572                         memcpy(hopping_frequency,"\x05\x41\x27\x4B\x17\x33\x11\x39\x0F\x3F\x05\x2F\x13\x2D\x25\x31\x1F\x2D\x25\x35\x03\x41\x1B\x43\x09\x3D\x1F\x29\x1D\x35\x0D\x3B\x19\x49\x23\x3B\x17\x47\x1D\x2B\x13\x37\x0B\x31\x23\x33\x29\x3F\x07\x37\x07\x43\x11\x2B\x1B\x39\x0B\x4B\x03\x4F\x21\x47\x0F\x4D\x15\x45\x21\x4F\x09\x3D\x19\x2F\x15\x45\x0D\x49\x27\x4D",MLINK_NUM_FREQ);
573                         MLINK_Unk_6_2  = 0x02;          //unknown value but doesn't seem to matter
574                         MLINK_CRC_Init = 0x3E;          //value sent during bind then used to init the CRC
575                 }
576                 //Other TX
577                 //MLINK_Unk_6_2  = 0x7e;                //unknown value but doesn't seem to matter
578                 //MLINK_CRC_Init = 0xA2;                //value sent during bind then used to init the CRC
579         #endif
581         for(uint8_t i=0;i<8;i++)
582                 MLINK_Data_Code[i+8]=MLINK_Data_Code[7-i];
584         debug("ID:")
585         for(uint8_t i=0;i<16;i++)
586                 debug(" %02X", MLINK_Data_Code[i]);
587         debugln("");
589         debugln("CRC init: %02X", MLINK_CRC_Init)
591         debug("RF:")
592         for(uint8_t i=0;i<MLINK_NUM_FREQ;i++)
593                 debug(" %02X", hopping_frequency[i]);
594         debugln("");
595         
596         if(IS_BIND_IN_PROGRESS)
597         {
598                 packet_count = 0;
599                 bind_counter = MLINK_BIND_COUNT;
600                 CYRF_ConfigDataCode((uint8_t*)"\x6F\xBE\x32\x01\xDB\xF1\x2B\x01\xE3\x5C\xFA\x02\x97\x93\xF9\x02"); //Bind data code
601                 CYRF_ConfigRFChannel(MLINK_BIND_CHANNEL);
602                 phase = MLINK_BIND_TX;
603         }
604         else
605                 phase = MLINK_PREP_DATA;
608 #endif