Traxxas TQ 1st gen: try 5
[DIY-Multiprotocol-TX-Module.git] / Multiprotocol / XN297_EMU.ino
blobe1a1de97d7d6022e5aa6fd741f8896a2b5b616bb
1 #if defined(CC2500_INSTALLED) || defined(NRF24L01_INSTALLED)
3 #include "iface_xn297.h"
5 bool xn297_scramble_enabled, xn297_crc, xn297_bitrate, xn297_rf;
6 uint8_t xn297_addr_len, xn297_rx_packet_len;
7 uint8_t xn297_tx_addr[5], xn297_rx_addr[5];
9 // xn297 address / pcf / payload scramble table
10 const uint8_t xn297_scramble[] = {
11     0xE3, 0xB1, 0x4B, 0xEA, 0x85, 0xBC, 0xE5, 0x66,
12     0x0D, 0xAE, 0x8C, 0x88, 0x12, 0x69, 0xEE, 0x1F,
13     0xC7, 0x62, 0x97, 0xD5, 0x0B, 0x79, 0xCA, 0xCC,
14     0x1B, 0x5D, 0x19, 0x10, 0x24, 0xD3, 0xDC, 0x3F,
15     0x8E, 0xC5, 0x2F, 0xAA, 0x16, 0xF3, 0x95 };
17 // scrambled, standard mode crc xorout table
18 const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
19     0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
20     0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
21     0xD461, 0xF494, 0x2503, 0x691D, 0xFE8B, 0x9BA7,
22     0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
23     0x2138, 0x129F, 0xB3A0, 0x2988, 0x23CA, 0xC0CB,
24     0x0C6C, 0xB329, 0xA0A1, 0x0A16, 0xA9D0 };
26 // unscrambled, standard mode crc xorout table
27 const uint16_t PROGMEM xn297_crc_xorout[] = {
28     0x0000, 0x3D5F, 0xA6F1, 0x3A23, 0xAA16, 0x1CAF,
29     0x62B2, 0xE0EB, 0x0821, 0xBE07, 0x5F1A, 0xAF15,
30     0x4F0A, 0xAD24, 0x5E48, 0xED34, 0x068C, 0xF2C9,
31     0x1852, 0xDF36, 0x129D, 0xB17C, 0xD5F5, 0x70D7,
32     0xB798, 0x5133, 0x67DB, 0xD94E, 0x0A5B, 0xE445,
33     0xE6A5, 0x26E7, 0xBDAB, 0xC379, 0x8E20 };
35 // scrambled enhanced mode crc xorout table
36 const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[] = {
37     0x0000, 0x7EBF, 0x3ECE, 0x07A4, 0xCA52, 0x343B,
38     0x53F8, 0x8CD0, 0x9EAC, 0xD0C0, 0x150D, 0x5186,
39     0xD251, 0xA46F, 0x8435, 0xFA2E, 0x7EBD, 0x3C7D,
40     0x94E0, 0x3D5F, 0xA685, 0x4E47, 0xF045, 0xB483,
41     0x7A1F, 0xDEA2, 0x9642, 0xBF4B, 0x032F, 0x01D2,
42     0xDC86, 0x92A5, 0x183A, 0xB760, 0xA953 };
44 // unscrambled enhanced mode crc xorout table
45 // unused so far
46 #ifdef XN297DUMP_NRF24L01_INO
47 const uint16_t xn297_crc_xorout_enhanced[] = {
48     0x0000, 0x8BE6, 0xD8EC, 0xB87A, 0x42DC, 0xAA89,
49     0x83AF, 0x10E4, 0xE83E, 0x5C29, 0xAC76, 0x1C69,
50     0xA4B2, 0x5961, 0xB4D3, 0x2A50, 0xCB27, 0x5128,
51     0x7CDB, 0x7A14, 0xD5D2, 0x57D7, 0xE31D, 0xCE42,
52     0x648D, 0xBF2D, 0x653B, 0x190C, 0x9117, 0x9A97,
53     0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 };
54 #endif
56 static bool __attribute__((unused)) XN297_Configure(bool crc_en, bool scramble_en, bool bitrate, bool force_nrf)
58         xn297_crc = crc_en;
59         xn297_scramble_enabled = scramble_en;
60         xn297_bitrate = bitrate;
61         xn297_rf = XN297_NRF;
62         
63         #if defined(NRF24L01_INSTALLED) and defined(CC2500_INSTALLED)
64                 if(bitrate == XN297_1M || force_nrf)
65                         xn297_rf = XN297_NRF;           // Use NRF24L01
66                 else
67                         xn297_rf = XN297_CC2500;        // Use CC2500
68         #elif defined(NRF24L01_INSTALLED) and not defined(CC2500_INSTALLED)
69                 xn297_rf = XN297_NRF;                   // Use NRF24L01
70         #else //CC2500 only
71                 xn297_rf = XN297_CC2500;                // Use CC2500
72                 if(bitrate == XN297_1M)
73                 {
74                         xn297_rf = XN297_NRF;           // Use NRF24L01 which does not exist, nothing will happen...
75                         SUB_PROTO_INVALID;
76                         return false;                           // Can't do...
77                 }
78         #endif
80         #if defined(NRF24L01_INSTALLED)
81                 if(xn297_rf == XN297_NRF)
82                 {
83                         debugln("Using NRF");
84                         rf_switch(SW_NRF);
85                         NRF24L01_Initialize();
86                         if(bitrate == XN297_250K)
87                                 NRF24L01_SetBitrate(NRF24L01_BR_250K);                  // 250Kbps
88                 }
89         #endif
90         #if defined(CC2500_INSTALLED)
91                 if(xn297_rf == XN297_CC2500)
92                 {
93                         debugln("Using CC2500");
94                         rf_switch(SW_CC2500);
95                         CC2500_250K_Init();
96                         option_override = 2;    // OPTION_RFTUNE
97                 }
98         #endif
99         return true;
102 static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t* addr, uint8_t len)
104         if (len > 5) len = 5;
105         if (len < 3) len = 3;
106         xn297_addr_len = len;
107         memcpy(xn297_tx_addr, addr, len);
108         #ifdef NRF24L01_INSTALLED
109                 if(xn297_rf == XN297_NRF)
110                 {
111                         uint8_t buf[] = { 0x55, 0x0F, 0x71, 0x0C, 0x00 };                       // bytes for XN297 preamble 0xC710F55 (28 bit)
112                         NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
113                         NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, xn297_addr_len == 3 ? buf+1 : buf, 5);
114                 }
115         #endif
118 static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t* addr, uint8_t rx_packet_len)
120         //Scramble address
121         for (uint8_t i = 0; i < xn297_addr_len; ++i)
122         {
123                 xn297_rx_addr[i] = addr[i];
124                 if(xn297_scramble_enabled)
125                         xn297_rx_addr[i] ^= xn297_scramble[xn297_addr_len-i-1];
126         }
128         if(xn297_crc)
129                 rx_packet_len += 2;                                                                                                                     // Include CRC
130         rx_packet_len += 2;                                                                                                                             // Include pcf, will this be a problem timing wise even if not enhanced?
132         #ifdef NRF24L01_INSTALLED
133                 if(xn297_rf == XN297_NRF)
134                 {
135                         NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, xn297_rx_addr, xn297_addr_len);
136                         if(rx_packet_len > 32)
137                                 rx_packet_len = 32;
138                         NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, rx_packet_len);
139                 }
140         #endif
141         #ifdef CC2500_INSTALLED
142                 if(xn297_rf == XN297_CC2500)
143                 {// TX: Sync1, Sync0, Address
144                         CC2500_WriteReg(CC2500_04_SYNC1, xn297_rx_addr[xn297_addr_len-1]);              // Sync word, high byte
145                         CC2500_WriteReg(CC2500_05_SYNC0, xn297_rx_addr[xn297_addr_len-2]);              // Sync word, low byte
146                         CC2500_WriteReg(CC2500_09_ADDR,  xn297_rx_addr[xn297_addr_len-3]);              // Address
147                         rx_packet_len += 1 + xn297_addr_len - 3;                                                                // The Address field above will be in the payload then the end of the XN297 address
148                 }
149         #endif
150         xn297_rx_packet_len = rx_packet_len;
153 static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State mode)
155         static enum TXRX_State cur_mode=TXRX_OFF;
156         #ifdef NRF24L01_INSTALLED
157                 if(xn297_rf == XN297_NRF)
158                 {
159                         
160                         NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR)                  //reset the flag(s)
161                                                                                                 | (1 << NRF24L01_07_TX_DS)
162                                                                                                 | (1 << NRF24L01_07_MAX_RT));
163                         if(mode==TXRX_OFF)
164                         {
165                                 NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0);                                                       //PowerDown
166                                 NRF_CE_off;
167                                 return;
168                         }
169                         NRF_CE_off;
170                         if(mode == TX_EN)
171                         {
172                                 NRF24L01_FlushTx();
173                                 NRF24L01_WriteReg(NRF24L01_00_CONFIG, 1 << NRF24L01_00_PWR_UP);
174                         }
175                         else
176                         {
177                                 NRF24L01_FlushRx();
178                                 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP)
179                                                                                                         | (1 << NRF24L01_00_PRIM_RX));  // RX
180                         }
181                         if(mode != cur_mode)
182                         {
183                                 //delayMicroseconds(130);
184                                 cur_mode=mode;
185                         }                       
186                         NRF_CE_on;
187                 }
188         #endif
189         #ifdef CC2500_INSTALLED
190                 if(xn297_rf == XN297_CC2500)
191                 {
192                         if(mode != cur_mode)
193                         {
194                                 CC2500_SetTxRxMode(mode);
195                                 if(mode == RX_EN)
196                                 {
197                                         CC2500_WriteReg(CC2500_12_MDMCFG2,  0x12);                                              // Modem Configuration, GFSK, 16/16 Sync Word TX&RX
198                                         CC2500_WriteReg(CC2500_06_PKTLEN, xn297_rx_packet_len);                         // Packet len
199                                         CC2500_Strobe(CC2500_SFRX);
200                                         CC2500_Strobe(CC2500_SRX);
201                                 }
202                                 else
203                                         CC2500_WriteReg(CC2500_12_MDMCFG2,      0x10);                                                  // Modem Configuration, GFSK, no preambule and no sync word
204                                 cur_mode=mode;
205                         }
206                 }
207         #endif
210 static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len)
212         #ifdef NRF24L01_INSTALLED
213                 if(xn297_rf == XN297_NRF)
214                 {
215                         NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
216                         NRF24L01_FlushTx();
217                         NRF24L01_WritePayload(msg, len);
218                 }
219         #endif
220         #ifdef CC2500_INSTALLED
221                 if(xn297_rf == XN297_CC2500)
222                 {
223                         // stop TX/RX
224                         CC2500_Strobe(CC2500_SIDLE);
225                         // flush tx FIFO
226                         CC2500_Strobe(CC2500_SFTX);
227                         // packet length
228                         CC2500_WriteReg(CC2500_06_PKTLEN, len + 4);  // Packet len, fix packet len
229                         // xn297L preamble
230                         CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4);
231                         // xn297 packet
232                         CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, msg, len);
233                         // transmit
234                         CC2500_Strobe(CC2500_STX);
235                 }
236         #endif
239 static void __attribute__((unused)) XN297_WritePayload(uint8_t* msg, uint8_t len)
241         uint8_t buf[32];
242         uint8_t last = 0;
244         if (xn297_rf == XN297_NRF && xn297_addr_len < 4 && xn297_rf == XN297_NRF)
245         { // If address length (which is defined by receiver address length) is less than 4 the TX address can't fit the preamble, so the last byte goes here
246                 buf[last++] = 0x55;
247         }
249         // address
250         for (uint8_t i = 0; i < xn297_addr_len; ++i)
251         {
252                 buf[last] = xn297_tx_addr[xn297_addr_len-i-1];
253                 if(xn297_scramble_enabled)
254                         buf[last] ^=  xn297_scramble[i];
255                 last++;
256         }
258         // payload
259         for (uint8_t i = 0; i < len; ++i)
260         {
261                 // bit-reverse bytes in packet
262                 buf[last] = bit_reverse(msg[i]);
263                 if(xn297_scramble_enabled)
264                         buf[last] ^= xn297_scramble[xn297_addr_len+i];
265                 last++;
266         }
268         // crc
269         if (xn297_crc)
270         {
271                 uint8_t offset = (xn297_addr_len < 4  && xn297_rf == XN297_NRF) ? 1 : 0;
272                 crc = 0xb5d2;
273                 for (uint8_t i = offset; i < last; ++i)
274                         crc16_update( buf[i], 8);
275                 if(xn297_scramble_enabled)
276                         crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
277                 else
278                         crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
279                 buf[last++] = crc >> 8;
280                 buf[last++] = crc & 0xff;
281         }
283         // send packet
284         XN297_SendPayload(buf, last);
287 static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
289         uint8_t buf[32];
290         uint8_t scramble_index=0;
291         uint8_t last = 0;
292         static uint8_t pid=0;
294         if (xn297_rf == XN297_NRF && xn297_addr_len < 4)
295         { // If address length (which is defined by receiver address length) is less than 4 the TX address can't fit the preamble, so the last byte goes here
296                 buf[last++] = 0x55;
297         }
299         // address
300         for (uint8_t i = 0; i < xn297_addr_len; ++i)
301         {
302                 buf[last] = xn297_tx_addr[xn297_addr_len-i-1];
303                 if(xn297_scramble_enabled)
304                         buf[last] ^= xn297_scramble[scramble_index++];
305                 last++;
306         }
308         // pcf
309         buf[last] = (len << 1) | (pid>>1);
310         if(xn297_scramble_enabled)
311                 buf[last] ^= xn297_scramble[scramble_index++];
312         last++;
313         buf[last] = (pid << 7) | (noack << 6);
315         // payload
316         if(len)
317         {
318                 buf[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload
319                 if(xn297_scramble_enabled)
320                         buf[last] ^= xn297_scramble[scramble_index++];
322                 for (uint8_t i = 0; i < len-1; ++i)
323                 {
324                         last++;
325                         buf[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2);
326                         if(xn297_scramble_enabled)
327                                 buf[last] ^= xn297_scramble[scramble_index++];
328                 }
330                 last++;
331                 buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
332                 if(xn297_scramble_enabled)
333                         buf[last] ^= xn297_scramble[scramble_index++] & 0xc0;
334         }
336         // crc
337         if (xn297_crc)
338         {
339                 uint8_t offset = (xn297_addr_len < 4 && xn297_rf == XN297_NRF) ? 1 : 0;
340                 crc = 0xb5d2;
341                 for (uint8_t i = offset; i < last; ++i)
342                         crc16_update( buf[i], 8);
343                 crc16_update( buf[last] & 0xc0, 2);
344                 if (xn297_scramble_enabled)
345                         crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
346                 //else
347                 //      crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
349                 buf[last++] |= (crc >> 8) >> 2;
350                 buf[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
351                 buf[last++] = (crc & 0xff) << 6;
352         }
353         pid++;
354         if(pid>3)
355                 pid=0;
357         // send packet
358         XN297_SendPayload(buf, last);
361 static bool __attribute__((unused)) XN297_IsRX()
363         #ifdef NRF24L01_INSTALLED
364                 if(xn297_rf == XN297_NRF)
365                         return (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR));
366         #endif
367         #ifdef CC2500_INSTALLED
368                 if(xn297_rf == XN297_CC2500)
369                 {
370                         if((CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F) != xn297_rx_packet_len + 2) // 2 = RSSI + LQI
371                                 return false;                                                                           // Buffer does not contain the expected number of bytes
372                         // Check the address
373                         uint8_t buf[3];
374                         CC2500_ReadData(buf, xn297_addr_len-3 + 1);
375                         for(uint8_t i=0; i < xn297_addr_len-3 + 1; i++)
376                                 if(buf[i] != xn297_rx_addr[xn297_addr_len-3 - i])
377                                         return false;                                                                   // Bad address
378                         return true;                                                                                    // Address is correct
379                 }
380         #endif
381         return false;
384 static void __attribute__((unused)) XN297_ReceivePayload(uint8_t* msg, uint8_t len)
386         if (xn297_crc)
387                 len += 2;                                                                       // Include CRC 
388         #ifdef NRF24L01_INSTALLED
389                 if(xn297_rf == XN297_NRF)
390                         NRF24L01_ReadPayload(msg, len);                 // Read payload and CRC 
391         #endif
392         #ifdef CC2500_INSTALLED
393                 if(xn297_rf == XN297_CC2500)
394                         CC2500_ReadData(msg, len);
395         #endif
398 static bool __attribute__((unused)) XN297_ReadPayload(uint8_t* msg, uint8_t len)
399 { //!!! Don't forget if using CRC to do a +2 on the received packet length (NRF24L01_11_RX_PW_Px !!! or CC2500_06_PKTLEN)
400         uint8_t buf[32];
402         // Read payload
403         XN297_ReceivePayload(buf, len);
405         // Decode payload
406         for(uint8_t i=0; i<len; i++)
407         {
408                 uint8_t b_in=buf[i];
409                 if(xn297_scramble_enabled)
410                         b_in ^= xn297_scramble[i+xn297_addr_len];
411                 msg[i] = bit_reverse(b_in);
412         }
414         if (!xn297_crc)
415                 return true;    // No CRC so OK by default...
417         // Calculate CRC
418         crc = 0xb5d2;
419         //process address
420         for (uint8_t i = 0; i < xn297_addr_len; ++i)
421                 crc16_update( xn297_rx_addr[xn297_addr_len-i-1], 8);
422         //process payload
423         for (uint8_t i = 0; i < len; ++i)
424                 crc16_update( buf[i], 8);
425         //xorout
426         if(xn297_scramble_enabled)
427                 crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
428         else
429                 crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
430         //test
431         if( (crc >> 8) == buf[len] && (crc & 0xff) == buf[len+1])
432                 return true;    // CRC  OK
433         return false;           // CRC NOK
436 static uint8_t __attribute__((unused)) XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
437 { //!!! Don't forget do a +2 and if using CRC add +4 on any of the used NRF24L01_11_RX_PW_Px !!!
438         uint8_t buffer[32];
439         uint8_t pcf_size;                                                       // pcf payload size
441         // Read payload
442         XN297_ReceivePayload(buffer, len+2);            // Read pcf + payload + CRC
444         // Decode payload
445         pcf_size = buffer[0];
446         if(xn297_scramble_enabled)
447                 pcf_size ^= xn297_scramble[xn297_addr_len];
448         pcf_size = pcf_size >> 1;
449         if(pcf_size>32)
450                 return 255;                                                             // Error
451         for(uint8_t i=0; i< pcf_size; i++)
452         {
453                 msg[i] = bit_reverse((buffer[i+1] << 2) | (buffer[i+2] >> 6));
454                 if(xn297_scramble_enabled)
455                         msg[i] ^= bit_reverse((xn297_scramble[xn297_addr_len+i+1] << 2) | 
456                                                                         (xn297_scramble[xn297_addr_len+i+2] >> 6));
457         }
459         if (!xn297_crc)
460                 return pcf_size;                                                // No CRC so OK by default...
462         // Calculate CRC
463         crc = 0xb5d2;
464         //process address
465         for (uint8_t i = 0; i < xn297_addr_len; ++i)
466                 crc16_update( xn297_rx_addr[xn297_addr_len-i-1], 8);
467         //process payload
468         for (uint8_t i = 0; i < pcf_size+1; ++i)
469                 crc16_update( buffer[i], 8);
470         crc16_update( buffer[pcf_size+1] & 0xc0, 2);
471         //xorout
472         if (xn297_scramble_enabled)
473                 crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+pcf_size]);
474 #ifdef XN297DUMP_NRF24L01_INO
475         else
476                 crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + pcf_size]);
477 #endif
478         uint16_t crcxored=(buffer[pcf_size+1]<<10)|(buffer[pcf_size+2]<<2)|(buffer[pcf_size+3]>>6) ;
479         if( crc == crcxored)
480                 return pcf_size;                                        // CRC  OK
481         return 255;                                                             // CRC NOK
484 static bool __attribute__((unused)) XN297_IsPacketSent()
486         #ifdef NRF24L01_INSTALLED
487                 if(xn297_rf == XN297_NRF)
488                         return (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS));
489         #endif
490         #ifdef CC2500_INSTALLED
491                 if(xn297_rf == XN297_CC2500)
492                         return (CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13);
493         #endif
494         return true;    // packet sent to not block
497 static void __attribute__((unused)) XN297_HoppingCalib(uint8_t num_freq)
498 {       //calibrate hopping frequencies
499         #ifdef NRF24L01_INSTALLED
500                 (void)num_freq;
501         #endif
502         #ifdef CC2500_INSTALLED
503                 if(xn297_rf == XN297_CC2500)
504                         CC2500_250K_HoppingCalib(num_freq);
505         #endif
508 static void __attribute__((unused)) XN297_Hopping(uint8_t index)
510         #ifdef NRF24L01_INSTALLED
511                 if(xn297_rf == XN297_NRF)
512                         NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
513         #endif
514         #ifdef CC2500_INSTALLED
515                 if(xn297_rf == XN297_CC2500)
516                         CC2500_250K_Hopping(index);
517         #endif
520 static void __attribute__((unused)) XN297_RFChannel(uint8_t number)
521 {       //change channel
522         #ifdef NRF24L01_INSTALLED
523                 if(xn297_rf == XN297_NRF)
524                         NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
525         #endif
526         #ifdef CC2500_INSTALLED
527                 if(xn297_rf == XN297_CC2500)
528                         CC2500_250K_RFChannel(number);
529         #endif
532 static void __attribute__((unused)) XN297_SetPower()
534         #ifdef NRF24L01_INSTALLED
535                 if(xn297_rf == XN297_NRF)
536                         NRF24L01_SetPower();
537         #endif
538         #ifdef CC2500_INSTALLED
539                 if(xn297_rf == XN297_CC2500)
540                         CC2500_SetPower();
541         #endif
544 static void __attribute__((unused)) XN297_SetFreqOffset()
545 {       // Frequency offset
546         #ifdef CC2500_INSTALLED
547                 if(xn297_rf == XN297_CC2500)
548                         CC2500_SetFreqOffset();
549         #endif
552  // End of XN297 emulation
554 #endif