Traxxas TQ 1st gen: try 5
[DIY-Multiprotocol-TX-Module.git] / Multiprotocol / A7105_SPI.ino
blobb6fe373557558b5e7de3892cfe4396634ca3ed1b
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  */
15 /********************/
16 /** A7105 routines **/
17 /********************/
18 #ifdef A7105_INSTALLED
19 #include "iface_a7105.h"
21 void A7105_WriteData(uint8_t len, uint8_t channel)
23         uint8_t i;
24         A7105_CSN_off;
25         SPI_Write(A7105_RST_WRPTR);
26         SPI_Write(A7105_05_FIFO_DATA);
27         for (i = 0; i < len; i++)
28                 SPI_Write(packet[i]);
29         A7105_CSN_on;
30         if(protocol!=PROTO_WFLY2)
31         {
32                 if(!(protocol==PROTO_FLYSKY || (protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_HYPE)))
33                 {
34                         A7105_Strobe(A7105_STANDBY);    //Force standby mode, ie cancel any TX or RX...
35                         A7105_SetTxRxMode(TX_EN);               //Switch to PA
36                 }
37                 A7105_WriteReg(A7105_0F_PLL_I, channel);
38                 A7105_Strobe(A7105_TX);
39         }
42 void A7105_ReadData(uint8_t len)
44         uint8_t i;
45         A7105_Strobe(A7105_RST_RDPTR);
46         A7105_CSN_off;
47         SPI_Write(0x40 | A7105_05_FIFO_DATA);   //bit 6 =1 for reading
48         for (i=0;i<len;i++)
49                 packet[i]=SPI_SDI_Read();
50         A7105_CSN_on;
53 void A7105_WriteReg(uint8_t address, uint8_t data) {
54         A7105_CSN_off;
55         SPI_Write(address); 
56         NOP();
57         SPI_Write(data);  
58         A7105_CSN_on;
59
61 uint8_t A7105_ReadReg(uint8_t address)
62
63         uint8_t result;
64         A7105_CSN_off;
65         SPI_Write(address |=0x40);                              //bit 6 =1 for reading
66         result = SPI_SDI_Read();  
67         A7105_CSN_on;
68         return(result); 
69
71 //------------------------
72 void A7105_SetTxRxMode(uint8_t mode)
74         if(mode == TX_EN)
75         {
76                 A7105_WriteReg(A7105_0B_GPIO1_PIN1, 0x33);
77                 A7105_WriteReg(A7105_0C_GPIO2_PIN_II, 0x31);
78         }
79         else
80                 if (mode == RX_EN)
81                 {
82                         A7105_WriteReg(A7105_0B_GPIO1_PIN1, 0x31);
83                         A7105_WriteReg(A7105_0C_GPIO2_PIN_II, 0x33);
84                 }
85                 else
86                 {
87                         //The A7105 seems to some with a cross-wired power-amp (A7700)
88                         //On the XL7105-D03, TX_EN -> RXSW and RX_EN -> TXSW
89                         //This means that sleep mode is wired as RX_EN = 1 and TX_EN = 1
90                         //If there are other amps in use, we'll need to fix this
91                         A7105_WriteReg(A7105_0B_GPIO1_PIN1, 0x33);
92                         A7105_WriteReg(A7105_0C_GPIO2_PIN_II, 0x33);
93                 }
96 //------------------------
97 uint8_t A7105_Reset()
99         uint8_t result;
100         
101         A7105_WriteReg(A7105_00_MODE, 0x00);
102         delayMilliseconds(1);
103         A7105_SetTxRxMode(TXRX_OFF);                    //Set both GPIO as output and low
104         result=A7105_ReadReg(A7105_10_PLL_II) == 0x9E;  //check if is reset.
105         A7105_Strobe(A7105_STANDBY);
106         return result;
109 void A7105_WriteID(uint32_t ida)
111         A7105_CSN_off;
112         SPI_Write(A7105_06_ID_DATA);                    //ex id=0x5475c52a ;txid3txid2txid1txid0
113         SPI_Write((ida>>24)&0xff);                              //54 
114         SPI_Write((ida>>16)&0xff);                              //75
115         SPI_Write((ida>>8)&0xff);                               //c5
116         SPI_Write((ida>>0)&0xff);                               //2a
117         A7105_CSN_on;
121 static void A7105_SetPower_Value(int power)
123         //Power amp is ~+16dBm so:
124         //TXPOWER_100uW  = -23dBm == PAC=0 TBG=0
125         //TXPOWER_300uW  = -20dBm == PAC=0 TBG=1
126         //TXPOWER_1mW    = -16dBm == PAC=0 TBG=2
127         //TXPOWER_3mW    = -11dBm == PAC=0 TBG=4
128         //TXPOWER_10mW   = -6dBm  == PAC=1 TBG=5
129         //TXPOWER_30mW   = 0dBm   == PAC=2 TBG=7
130         //TXPOWER_100mW  = 1dBm   == PAC=3 TBG=7
131         //TXPOWER_150mW  = 1dBm   == PAC=3 TBG=7
132         uint8_t pac, tbg;
133         switch(power) {
134                 case 0: pac = 0; tbg = 0; break;
135                 case 1: pac = 0; tbg = 1; break;
136                 case 2: pac = 0; tbg = 2; break;
137                 case 3: pac = 0; tbg = 4; break;
138                 case 4: pac = 1; tbg = 5; break;
139                 case 5: pac = 2; tbg = 7; break;
140                 case 6: pac = 3; tbg = 7; break;
141                 case 7: pac = 3; tbg = 7; break;
142                 default: pac = 0; tbg = 0; break;
143         };
144         A7105_WriteReg(0x28, (pac << 3) | tbg);
148 void A7105_SetPower()
150         uint8_t power=A7105_BIND_POWER;
151         if(IS_BIND_DONE)
152                 #ifdef A7105_ENABLE_LOW_POWER
153                         power=IS_POWER_FLAG_on?A7105_HIGH_POWER:A7105_LOW_POWER;
154                 #else
155                         power=A7105_HIGH_POWER;
156                 #endif
157         if(IS_RANGE_FLAG_on)
158                 power=A7105_RANGE_POWER;
159         if(prev_power != power)
160         {
161                 A7105_WriteReg(A7105_28_TX_TEST, power);
162                 prev_power=power;
163         }
166 void A7105_Strobe(uint8_t address) {
167         A7105_CSN_off;
168         SPI_Write(address);
169         A7105_CSN_on;
172 // Fine tune A7105 LO base frequency
173 // this is required for some A7105 modules and/or RXs with inaccurate crystal oscillator
174 void A7105_AdjustLOBaseFreq(uint8_t cmd)
176         static int16_t old_offset=2048;
177         int16_t offset=1024;
178         if(cmd==0)
179         {       // Called at init of the A7105
180                 old_offset=2048;
181                 switch(protocol)
182                 {
183                         case PROTO_HUBSAN:
184                                 #ifdef FORCE_HUBSAN_TUNING
185                                         offset=(int16_t)FORCE_HUBSAN_TUNING;
186                                 #endif
187                                 break;
188                         case PROTO_BUGS:
189                                 #ifdef FORCE_BUGS_TUNING
190                                         offset=(int16_t)FORCE_BUGS_TUNING;
191                                 #endif
192                                 break;
193                         case PROTO_FLYSKY:
194                                 #ifdef FORCE_FLYSKY_TUNING
195                                         offset=(int16_t)FORCE_FLYSKY_TUNING;
196                                 #endif
197                                 break;
198                         case PROTO_HEIGHT:
199                                 #ifdef FORCE_HEIGHT_TUNING
200                                         offset=(int16_t)FORCE_HEIGHT_TUNING;
201                                 #endif
202                                 break;
203                         case PROTO_PELIKAN:
204                                 #ifdef FORCE_PELIKAN_TUNING
205                                         offset=(int16_t)FORCE_PELIKAN_TUNING;
206                                 #endif
207                                 break;
208                         case PROTO_KYOSHO:
209                                 #ifdef FORCE_KYOSHO_TUNING
210                                         offset=(int16_t)FORCE_KYOSHO_TUNING;
211                                 #endif
212                                 break;
213                         case PROTO_JOYSWAY:
214                                 #ifdef FORCE_JOYSWAY_TUNING
215                                         offset=(int16_t)FORCE_JOYSWAY_TUNING;
216                                 #endif
217                                 break;
218                         case PROTO_WFLY2:
219                                 #ifdef FORCE_WFLY2_TUNING
220                                         offset=(int16_t)FORCE_WFLY2_TUNING;
221                                 #endif
222                                 break;
223                         case PROTO_AFHDS2A:
224                         case PROTO_AFHDS2A_RX:
225                                 #ifdef FORCE_AFHDS2A_TUNING
226                                         offset=(int16_t)FORCE_AFHDS2A_TUNING;
227                                 #endif
228                                 break;
229                 }
230         }
231         if(offset==1024)        // Use channel 15 as an input
232                 offset=convert_channel_16b_nolimit(CH15,-300,300,false);
234         if(old_offset==offset)  // offset is the same as before...
235                         return;
236         old_offset=offset;
238         // LO base frequency = 32e6*(bip+(bfp/(2^16)))
239         uint8_t bip;    // LO base frequency integer part
240         uint16_t bfp;   // LO base frequency fractional part
241         offset++;               // as per datasheet, not sure why recommended, but that's a +1kHz drift only ...
242         offset<<=1;
243         if(offset < 0)
244         {
245                 bip = 0x4a;     // 2368 MHz
246                 bfp = 0xffff + offset;
247         }
248         else
249         {
250                 bip = 0x4b;     // 2400 MHz (default)
251                 bfp = offset;
252         }
253         A7105_WriteReg( A7105_11_PLL_III, bip);
254         A7105_WriteReg( A7105_12_PLL_IV, (bfp >> 8) & 0xff);
255         A7105_WriteReg( A7105_13_PLL_V, bfp & 0xff);
256         //debugln("Channel: %d, offset: %d, bip: %2x, bfp: %4x", Channel_data[14], offset, bip, bfp);
259 static void __attribute__((unused)) A7105_SetVCOBand(uint8_t vb1, uint8_t vb2)
260 {       // Set calibration band value to best match
261         uint8_t diff1, diff2;
263         if (vb1 >= 4)
264                 diff1 = vb1 - 4;
265         else
266                 diff1 = 4 - vb1;
268         if (vb2 >= 4)
269                 diff2 = vb2 - 4;
270         else
271                 diff2 = 4 - vb2;
273         if (diff1 == diff2 || diff1 > diff2)
274                 A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb1 | 0x08);
275         else
276                 A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb2 | 0x08);
279 #if defined(AFHDS2A_A7105_INO) || defined(AFHDS2A_RX_A7105_INO)
280 const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
281         0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50,        // 00 - 0f
282         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, 0xFF, 0xFF, 0x2a, 0x32, 0xc3, 0x1f,                         // 10 - 1f
283         0x1e, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,                         // 20 - 2f
284         0x01, 0x0f // 30 - 31
286 #endif
287 #ifdef BUGS_A7105_INO
288 const uint8_t PROGMEM BUGS_A7105_regs[] = {
289         0xFF, 0x42, 0x00, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0x01, 0x50, // 00 - 0f
290         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x40, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
291         0x16, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3b, 0x00, 0x0b, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
292         0x01, 0x0f // 30 - 31
294 #endif
295 #ifdef FLYSKY_A7105_INO
296 const uint8_t PROGMEM FLYSKY_A7105_regs[] = {
297         0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, // 00 - 0f
298         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, // 10 - 1f
299         0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
300         0x01, 0x0f // 30 - 31
302 #endif
303 #ifdef HEIGHT_A7105_INO
304 const uint8_t PROGMEM HEIGHT_A7105_regs[] = {
305         0xff, 0x42, 0x00, 0x07, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x01, 0x50, // 00 - 0f
306         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x1f, // 10 - 1f
307         0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3a, 0x00, 0x3f, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
308         0x01, 0x0f // 30 - 31
310 #endif
311 #ifdef HUBSAN_A7105_INO
312 const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
313         0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF, // 00 - 0f
314         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07, // 10 - 1f
315         0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 20 - 2f
316         0xFF, 0xFF // 30 - 31
318 #endif
319 #ifdef PELIKAN_A7105_INO
320 const uint8_t PROGMEM PELIKAN_A7105_regs[] = {
321         0xff, 0x42, 0x00, 0x0F, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x01, 0x50, // 00 - 0f
322         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x07, // 10 - 1f
323         0x16, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x1f, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
324         0x01, 0x0f // 30 - 31
326 #endif
327 #ifdef KYOSHO_A7105_INO
328 const uint8_t PROGMEM KYOSHO_A7105_regs[] = {
329         0xff, 0x42, 0xff, 0x25, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, // 00 - 0f
330         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x40, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0x03, 0x1f, // 10 - 1f
331         0x1e, 0x00, 0x00, 0xff, 0x00, 0x00, 0x23, 0x70, 0x1F, 0x47, 0x80, 0x57, 0x01, 0x45, 0x19, 0x00, // 20 - 2f
332         0x01, 0x0f // 30 - 31
334 const uint8_t PROGMEM KYOSHO_HYPE_A7105_regs[] = {
335         0xff, 0x42, 0x00, 0x10, 0xC0, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x05, 0x01, 0x04, // 00 - 0f
336         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x96, 0xc2, 0x1f, // 10 - 1f
337         0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3a, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
338         0x01, 0x0f // 30 - 31
340 #endif
341 #ifdef WFLY2_A7105_INO //A7106 values
342 const uint8_t PROGMEM WFLY2_A7105_regs[] = {
343         0xff, 0x62, 0xff, 0x1F, 0x40, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00, 0x64, // 00 - 0f Changes: 0B:19->33, 0C:01,33
344         0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x40, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0x03, 0x0f, // 10 - 1f 1C:4A->0A
345         0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x23, 0x70, 0x15, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f 2B:77->03, 2E:19->18
346         0x01, 0x0f // 30 - 31
348 #endif
349 #ifdef JOYSWAY_A7105_INO
350 const uint8_t PROGMEM JOYSWAY_A7105_regs[] = {
351         0xff, 0x62, 0xff, 0x0F, 0x00, 0xff, 0xff ,0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xF5, 0x00, 0x15, // 00 - 0f
352         0x9E, 0x4B, 0x00, 0x03, 0x56, 0x2B, 0x12, 0x4A, 0x02, 0x80, 0x80, 0x00, 0x0E, 0x91, 0x03, 0x0F, // 10 - 1f
353         0x16, 0x2A, 0x00, 0xff, 0xff, 0xff, 0x3A, 0x06, 0x1F, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00, // 20 - 2f
354         0x01, 0x0f // 30 - 31
356 #endif
358 #define ID_NORMAL 0x55201041
359 #define ID_PLUS   0xAA201041
360 void A7105_Init(void)
362         uint8_t *A7105_Regs=0;
363     uint8_t vco_calibration0, vco_calibration1;
364         
365         #ifdef JOYSWAY_A7105_INO
366                 if(protocol==PROTO_JOYSWAY)
367                 {
368                         A7105_Regs=(uint8_t*)JOYSWAY_A7105_regs;
369                 }
370                 else
371         #endif
372         #ifdef WFLY2_A7105_INO
373                 if(protocol==PROTO_WFLY2)
374                 {
375                         A7105_Regs=(uint8_t*)WFLY2_A7105_regs;
376                 }
377                 else
378         #endif
379         #ifdef HEIGHT_A7105_INO
380                 if(protocol==PROTO_HEIGHT)
381                 {
382                         A7105_Regs=(uint8_t*)HEIGHT_A7105_regs;
383                         A7105_WriteID(0x25A53C45);
384                 }
385                 else
386         #endif
387         #ifdef PELIKAN_A7105_INO
388                 if(protocol==PROTO_PELIKAN)
389                 {
390                         A7105_Regs=(uint8_t*)PELIKAN_A7105_regs;
391                         A7105_WriteID(0x06230623);
392                 }
393                 else
394         #endif
395         #ifdef BUGS_A7105_INO
396                 if(protocol==PROTO_BUGS)
397                         A7105_Regs=(uint8_t*)BUGS_A7105_regs;
398                 else
399         #endif
400         #ifdef HUBSAN_A7105_INO
401                 if(protocol==PROTO_HUBSAN)
402                 {
403                         A7105_WriteID(ID_NORMAL);
404                         A7105_Regs=(uint8_t*)HUBSAN_A7105_regs;
405                 }
406                 else
407         #endif
408                 {
409                         A7105_WriteID(0x5475c52A);//0x2Ac57554
410                         #ifdef FLYSKY_A7105_INO
411                                 if(protocol==PROTO_FLYSKY)
412                                         A7105_Regs=(uint8_t*)FLYSKY_A7105_regs;
413                         #endif
414                         #if defined(AFHDS2A_A7105_INO) || defined(AFHDS2A_RX_A7105_INO)
415                                 if(protocol==PROTO_AFHDS2A || protocol==PROTO_AFHDS2A_RX)
416                                         A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs;
417                         #endif
418                         #ifdef KYOSHO_A7105_INO
419                                 if(protocol==PROTO_KYOSHO)
420                                 {
421                                         if(sub_protocol==KYOSHO_HYPE)
422                                                 A7105_Regs=(uint8_t*)KYOSHO_HYPE_A7105_regs;
423                                         else //FHSS && SYNCRO
424                                                 A7105_Regs=(uint8_t*)KYOSHO_A7105_regs;
425                                 }
426                         #endif
427                 }
429         for (uint8_t i = 0; i < 0x32; i++)
430         {
431                 uint8_t val=pgm_read_byte_near(&A7105_Regs[i]);
432                 #ifdef FLYSKY_A7105_INO
433                         if(protocol==PROTO_FLYSKY && sub_protocol==CX20)
434                         {
435                                 if(i==0x0E) val=0x01;
436                                 if(i==0x1F) val=0x1F;
437                                 if(i==0x20) val=0x1E;
438                         }
439                 #endif
440                 #ifdef HEIGHT_A7105_INO
441                         if(protocol==PROTO_HEIGHT && sub_protocol==HEIGHT_8CH)
442                                 if(i==0x03) val=0x0A;
443                 #endif
444                 if( val != 0xff)
445                         A7105_WriteReg(i, val);
446         }
447         A7105_Strobe(A7105_STANDBY);
449         if(protocol==PROTO_KYOSHO && sub_protocol!=KYOSHO_HYPE)
450         {//strange calibration...
451                 //IF Filter Bank Calibration
452                 A7105_WriteReg(A7105_02_CALC,0x0F);
453                 while(A7105_ReadReg(A7105_02_CALC));                    // Wait for calibration to end
454         //      A7105_ReadReg(A7105_22_IF_CALIB_I);
455         //      A7105_ReadReg(A7105_24_VCO_CURCAL);
456         //      A7105_ReadReg(25_VCO_SBCAL_I);
457         //      A7105_ReadReg(1A_RX_GAIN_II);
458         //      A7105_ReadReg(1B_RX_GAIN_III);
459         }
460         else
461         {
462                 //IF Filter Bank Calibration
463                 A7105_WriteReg(A7105_02_CALC,1);
464                 while(A7105_ReadReg(A7105_02_CALC));                    // Wait for calibration to end
465         //      A7105_ReadReg(A7105_22_IF_CALIB_I);
466         //      A7105_ReadReg(A7105_24_VCO_CURCAL);
468                 if(protocol!=PROTO_HUBSAN)
469                 {
470                         //VCO Current Calibration
471                         A7105_WriteReg(A7105_24_VCO_CURCAL,0x13);       //Recommended calibration from A7105 Datasheet
472                         //VCO Bank Calibration
473                         A7105_WriteReg(A7105_26_VCO_SBCAL_II,0x3b);     //Recommended calibration from A7105 Datasheet
474                 }
476                 //VCO Bank Calibrate channel 0
477                 A7105_WriteReg(A7105_0F_CHANNEL, 0);
478                 A7105_WriteReg(A7105_02_CALC,2);
479                 while(A7105_ReadReg(A7105_02_CALC));                    // Wait for calibration to end
480                 vco_calibration0 = A7105_ReadReg(A7105_25_VCO_SBCAL_I);
481                 
482                 //VCO Bank Calibrate channel A0
483                 A7105_WriteReg(A7105_0F_CHANNEL, 0xa0);
484                 A7105_WriteReg(A7105_02_CALC, 2);
485                 while(A7105_ReadReg(A7105_02_CALC));                    // Wait for calibration to end
486                 vco_calibration1 = A7105_ReadReg(A7105_25_VCO_SBCAL_I);
488                 if(protocol==PROTO_BUGS || protocol==PROTO_WFLY2)
489                         A7105_SetVCOBand(vco_calibration0 & 0x07, vco_calibration1 & 0x07);     // Set calibration band value to best match
490                 else
491                         if(protocol!=PROTO_HUBSAN)
492                         {
493                                 switch(protocol)
494                                 {
495                                         case PROTO_FLYSKY:
496                                                 vco_calibration1=0x08;
497                                                 break;
498                                         case PROTO_HEIGHT:
499                                                 vco_calibration1=0x02;
500                                                 break;
501                                         case PROTO_PELIKAN:
502                                                 if(sub_protocol == PELIKAN_SCX24)
503                                                 {
504                                                         vco_calibration1=0x0A;
505                                                         break;
506                                                 }
507                                         case PROTO_KYOSHO: //sub_protocol Hype
508                                                 vco_calibration1=0x0C;
509                                                 break;
510                                         case PROTO_JOYSWAY:
511                                                 vco_calibration1=0x09;
512                                                 break;
513                                         default:
514                                                 vco_calibration1=0x0A;
515                                                 break;
516                                 }
517                                 A7105_WriteReg(A7105_25_VCO_SBCAL_I,vco_calibration1);  //Reset VCO Band calibration
518                         }
519         }
520         A7105_SetTxRxMode(TX_EN);
521         A7105_SetPower();
523         #ifdef USE_A7105_CH15_TUNING
524                 A7105_AdjustLOBaseFreq(0);
525         #endif
526         
527         A7105_Strobe(A7105_STANDBY);
529 #endif