Naze32 clone with Frysky receiver
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

frsky_arduino_rx_complete.ino 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. /*
  2. * Frsky RX 2-way
  3. * By Midelic
  4. * on RCGroups
  5. * an adaptation from Kyrre Aalerud(Kreature)
  6. * 2012 Frsky rx demo code
  7. * http://www.rcgroups.com/forums/showthread.php?t=1667453
  8. * Thanks also to Phracturedblue and his deviation firmware
  9. **********************************
  10. */
  11. #include <avr/interrupt.h>
  12. #include <EEPROM.h>
  13. #include "iface_cc2500.h"
  14. #define DEBUG
  15. #define DEBUG0
  16. #define DEBUG1
  17. #define DEBUG2
  18. #define DEBUG3
  19. #define DEBUG4
  20. #define DEBUG5
  21. #define FAILSAFE
  22. #define SPIBB
  23. //#define SPIHW
  24. #if defined SPIHW
  25. #include <SPI.h>
  26. #endif
  27. #define chanel_number 8 //set the number of chanels
  28. #define SEEK_CHANSKIP 13
  29. #define MAX_MISSING_PKT 20
  30. #define PPM_FrLen 22500
  31. #define PPM_PulseLen 300
  32. #define default_servo_value 1500
  33. #define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
  34. #define sigPin 10
  35. #if defined(SPIBB)
  36. #define MO_pin 5 //D5
  37. #define MI_pin 6 //D6
  38. #define SCLK_pin 4 //D4
  39. #define CS 2 //D2
  40. #define GDO_pin 3 //D3 GDO0 pin
  41. #define SCK_on PORTD |= 0x10 //D4
  42. #define SCK_off PORTD &= 0xEF //D4
  43. #define MO_on PORTD |= 0x20 //D5
  44. #define MO_off PORTD &= 0xDF //D5
  45. #define MI_1 (PIND & 0x40) == 0x40 //D6 input
  46. #define MI_0 (PIND & 0x40) == 0x00 //D6
  47. #define CS_on PORTD |= 0x04 //D2
  48. #define CS_off PORTD &= 0xFB //D2
  49. #define GDO_1 (PIND & 0x08) == 0x08 //D3 input
  50. #define GDO_0 (PIND & 0x08) == 0x00 //D3
  51. #endif
  52. #define bind_pin A0 //C0 bind plug also servo8
  53. #define Servo1_OUT 7 //Servo1(D7)
  54. #define Servo2_OUT 8 //Servo2(B0)
  55. #define Servo3_OUT 9 //Servo3(B1)
  56. #define Servo4_OUT 10 //Servo4(B2)//PPM pin
  57. #define Servo5_OUT 11 //Servo5(B3)
  58. #define Servo6_OUT 12 //Servo6(B4)
  59. #define Servo7_OUT 13 //Servo7(B5)
  60. #define Servo8_OUT A0 //Servo8(C0)
  61. #define Servo1_OUT_HIGH PORTD |= _BV(7) //Servo1(D7)
  62. #define Servo2_OUT_HIGH PORTB |= _BV(0) //Servo2(B0)
  63. #define Servo3_OUT_HIGH PORTB |= _BV(1) //Servo3(B1)
  64. #define Servo4_OUT_HIGH PORTB |= _BV(2) //Servo4(B2)
  65. #define Servo5_OUT_HIGH PORTB |= _BV(3) //Servo5(B3)
  66. #define Servo6_OUT_HIGH PORTB |= _BV(4) //Servo6(B4)
  67. #define Servo7_OUT_HIGH PORTB |= _BV(5) //Servo7(B5)
  68. #define Servo8_OUT_HIGH PORTC |= _BV(0) //Servo8(C0)
  69. #define Servo_Ports_LOW PORTD &= 0x7F ; PORTB &= 0xc0; PORTC &=0xFE //all servos low
  70. #define LED_pin A3
  71. #define LED_ON PORTC |= _BV(3)
  72. #define LED_OFF PORTC &= ~_BV(3)
  73. #define NOP() __asm__ __volatile__("nop")
  74. // Globals:
  75. static uint8_t ccData[27];
  76. static uint8_t ccLen;
  77. static boolean packet = false;
  78. //static uint16_t time;
  79. static uint8_t channr;
  80. static uint8_t missingPackets = 0;
  81. uint8_t calData[60];
  82. uint8_t hopData[60];
  83. uint8_t listLength;
  84. uint8_t txid[2];
  85. static uint8_t counter = 0;
  86. volatile uint16_t Servo_data[10] = {1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500};
  87. volatile byte scale;
  88. static byte jumper1 = 0;
  89. static byte jumper2 = 0;
  90. volatile int ppm[chanel_number];
  91. static uint16_t total_servo_time = 0;
  92. static byte cur_chan_numb = 0;
  93. boolean debug = false;
  94. int count = 0;
  95. uint16_t c[8];
  96. boolean debug2 = true;
  97. boolean debug3 = false;
  98. void setup()
  99. {
  100. #if defined(SPIBB)
  101. pinMode(MO_pin, OUTPUT); //SI
  102. pinMode(MI_pin, INPUT); //SO
  103. pinMode(SCLK_pin, OUTPUT); //SCLK
  104. pinMode(CS, OUTPUT); //CS output
  105. pinMode(GDO_pin, INPUT); //GDO0 pin
  106. SCK_off; //start sck low
  107. MO_off; //low
  108. #endif
  109. pinMode(LED_pin, OUTPUT);
  110. CS_on;
  111. #if defined(SPIHW)
  112. pinMode(CS, OUTPUT);
  113. pinMode(GDO_pin, INPUT);
  114. SPI.setClockDivider(SPI_CLOCK_DIV2);
  115. SPI.setBitOrder( MSBFIRST);
  116. SPI.begin();
  117. #endif
  118. pinMode(Servo1_OUT, OUTPUT); //Servo1
  119. pinMode(Servo2_OUT, OUTPUT); //Servo2
  120. pinMode(Servo3_OUT, OUTPUT); //Servo3
  121. pinMode(Servo4_OUT, OUTPUT); //Servo4
  122. //
  123. pinMode(Servo6_OUT, OUTPUT); //Servo6
  124. pinMode(Servo7_OUT, OUTPUT); //Servo7
  125. pinMode(Servo8_OUT, OUTPUT); //Servo8
  126. //Servo8_OUT_HIGH;//bindpin pullup
  127. #if defined DEBUG
  128. Serial.begin(115200);
  129. int8_t i;
  130. Serial.print("PartNum ");
  131. i = cc2500_readReg(CC2500_30_PARTNUM + CC2500_READ_BURST);
  132. Serial.println(i);
  133. delay(10);
  134. Serial.print("Version ");
  135. i = cc2500_readReg(CC2500_31_VERSION + CC2500_READ_BURST);
  136. Serial.println(i);
  137. #endif
  138. #if F_CPU == 16000000
  139. scale = 2;
  140. #elif F_CPU == 8000000
  141. scale = 1;
  142. #else
  143. #error // 8 or 16MHz only !
  144. #endif
  145. initialize(1); //binding
  146. binding();
  147. pinMode(Servo8_OUT, OUTPUT); //Servo8.bind pin is set to output again.
  148. initialize(0); //data
  149. jumper1 = PPM_jumper(); // Check the possible jumper positions for changing the receiver mode.
  150. if (jumper1 == 1) {
  151. //initiallize default ppm values
  152. for (int i = 0; i < chanel_number; i++) {
  153. ppm[i] = default_servo_value;
  154. }
  155. pinMode(sigPin, OUTPUT);
  156. digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)
  157. }
  158. config_timer();
  159. channr = 0;
  160. cc2500_writeReg(CC2500_0A_CHANNR, hopData[channr]);//0A-hop
  161. cc2500_writeReg(CC2500_23_FSCAL3, 0x89); //23-89
  162. cc2500_strobe(CC2500_SRX);
  163. }
  164. void loop()
  165. {
  166. unsigned long time = micros();
  167. #if defined(FAILSAFE)
  168. if (missingPackets > 170) {
  169. //**************************************
  170. //noInterrupts();//
  171. //digitalWrite(sigPin, LOW);
  172. //Servo_Ports_LOW;
  173. //**********************************************
  174. missingPackets = 0;
  175. int i;
  176. for (i = 0; i < 8; i++) {
  177. Servo_data[i] = 1500;
  178. ppm[i] = 1500;
  179. if (i == 2) {
  180. Servo_data[2] = 1000; //THROTLE ON CHN3 here it can be changed Throttle on other channel
  181. ppm[2] = 1000;
  182. }
  183. }
  184. }
  185. #endif
  186. while (1) {
  187. if ((micros() - time) > 9000) {
  188. missingPackets++;
  189. cc2500_strobe(CC2500_SIDLE);
  190. if (missingPackets > MAX_MISSING_PKT) {
  191. nextChannel(SEEK_CHANSKIP);
  192. LED_OFF;
  193. counter++;
  194. if (counter > (MAX_MISSING_PKT << 1))
  195. LED_ON;
  196. if (counter == (MAX_MISSING_PKT << 2)) counter = 0;
  197. break;
  198. } else
  199. nextChannel(1);
  200. break;
  201. }
  202. if (GDO_1) {
  203. ccLen = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
  204. if (ccLen > 20)
  205. ccLen = 20;//
  206. if (ccLen) {
  207. cc2500_readFifo((uint8_t *)ccData, ccLen);
  208. if (ccData[ccLen - 1] & 0x80) { // Only if correct CRC
  209. missingPackets = 0;
  210. if (ccData[0] == 0x11) { // Correct length
  211. if ((ccData[1] == txid[0]) && (ccData[2] == txid[1])) { // Only if correct txid
  212. packet = true;
  213. //sei(); ///////////////////////////////////////////////////////////////////////////////////////
  214. //int rssi = cc2500_readReg(CC2500_34_RSSI | CC2500_READ_BURST);//check RSSI
  215. cc2500_strobe(CC2500_SIDLE);
  216. nextChannel(1);
  217. LED_ON;
  218. break;
  219. }
  220. }
  221. }
  222. }
  223. }
  224. }
  225. if (packet == true) {
  226. packet = false;
  227. debug = true;
  228. //cli();
  229. c[0] = (uint16_t)(ccData[10] & 0x0F) << 8 | ccData[6];
  230. c[1] = (uint16_t)(ccData[10] & 0xF0) << 4 | ccData[7];
  231. c[2] = (uint16_t)(ccData[11] & 0x0F) << 8 | ccData[8];
  232. c[3] = (uint16_t)(ccData[11] & 0xF0) << 4 | ccData[9];
  233. c[4] = (uint16_t)(ccData[16] & 0x0F) << 8 | ccData[12];
  234. c[5] = (uint16_t)(ccData[16] & 0xF0) << 4 | ccData[13];
  235. c[6] = (uint16_t)(ccData[17] & 0x0F) << 8 | ccData[14];
  236. c[7] = (uint16_t)(ccData[17] & 0xF0) << 4 | ccData[15];
  237. //sei();
  238. for (int i = 0; i < 8; i++) {
  239. Servo_data[i] = 0.67 * c[i];
  240. if (Servo_data[i] < 900) { //added new
  241. Servo_data[i] = 1500; //added new
  242. Servo_data[2] = 1000;
  243. }
  244. ppm[i] = Servo_data[i];
  245. }
  246. #if defined(DEBUG5)
  247. //Serial.println(rssi);
  248. #endif
  249. #if defined(DEBUG0)
  250. for (int i = 0; i < 8; i++) {
  251. Serial.print(" ");
  252. Serial.print(Servo_data[i]);
  253. Serial.print(" ");
  254. }
  255. Serial.println(" ");
  256. #endif
  257. }
  258. cc2500_strobe(CC2500_SRX);
  259. if (debug == true) {
  260. debug = false;
  261. #if defined(DEBUG2)
  262. Serial.println(ccData[3], HEX);
  263. #endif
  264. }
  265. }
  266. void initialize(int bind)
  267. {
  268. cc2500_resetChip();
  269. cc2500_writeReg(CC2500_02_IOCFG0, 0x01); // reg 0x02: RX complete interrupt(GDO0)
  270. cc2500_writeReg(CC2500_17_MCSM1, 0x0C); // reg 0x17:
  271. cc2500_writeReg(CC2500_18_MCSM0, 0x18); // reg 0x18:
  272. cc2500_writeReg(CC2500_06_PKTLEN, 0x19); // Leave room for appended status bytes
  273. cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05); // reg 0x08:
  274. cc2500_writeReg(CC2500_3E_PATABLE, 0xFF); //
  275. cc2500_writeReg(CC2500_0B_FSCTRL1, 0x08); // reg 0x0B:
  276. cc2500_writeReg(CC2500_0C_FSCTRL0, 0x00); // reg 0x0C
  277. cc2500_writeReg(CC2500_0D_FREQ2, 0x5C); // reg 0x0D
  278. cc2500_writeReg(CC2500_0E_FREQ1, 0x76); // reg 0x0E
  279. cc2500_writeReg(CC2500_0F_FREQ0, 0x27); // reg 0x0F
  280. cc2500_writeReg(CC2500_10_MDMCFG4, 0xAA); // reg 0x10
  281. cc2500_writeReg(CC2500_11_MDMCFG3, 0x39); // reg 0x11
  282. cc2500_writeReg(CC2500_12_MDMCFG2, 0x11); // reg 0x12
  283. cc2500_writeReg(CC2500_13_MDMCFG1, 0x23); // reg 0x13
  284. cc2500_writeReg(CC2500_14_MDMCFG0, 0x7A); // reg 0x14
  285. cc2500_writeReg(CC2500_15_DEVIATN, 0x42); // reg 0x15
  286. cc2500_writeReg(CC2500_19_FOCCFG, 0x16); // reg 0x16
  287. cc2500_writeReg(CC2500_1A_BSCFG, 0x6C); // reg 0x1A
  288. cc2500_writeReg(CC2500_1B_AGCCTRL2, 0x03); // reg 0x1B
  289. cc2500_writeReg(CC2500_1C_AGCCTRL1, 0x40); // reg 0x1C
  290. cc2500_writeReg(CC2500_1D_AGCCTRL0, 0x91); // reg 0x1D
  291. cc2500_writeReg(CC2500_21_FREND1, 0x56); // reg 0x21:
  292. cc2500_writeReg(CC2500_22_FREND0, 0x10); // reg 0x22:
  293. cc2500_writeReg(CC2500_23_FSCAL3, 0xA9); // reg 0x23:
  294. cc2500_writeReg(CC2500_24_FSCAL2, 0x05); // reg 0x24:
  295. cc2500_writeReg(CC2500_25_FSCAL1, 0x00); // reg 0x25
  296. cc2500_writeReg(CC2500_26_FSCAL0, 0x11); // reg 0x26
  297. cc2500_writeReg(CC2500_29_FSTEST, 0x59); // reg 0x29
  298. cc2500_writeReg(CC2500_2C_TEST2, 0x88); // reg 0x2C
  299. cc2500_writeReg(CC2500_2D_TEST1, 0x31); // reg 0x2D
  300. cc2500_writeReg(CC2500_2E_TEST0, 0x0B); // reg 0x2E
  301. cc2500_writeReg(CC2500_03_FIFOTHR, 0x0F); // reg 0x03:
  302. cc2500_writeReg(CC2500_09_ADDR, bind ? 0x03 : txid[0]);
  303. cc2500_strobe(CC2500_SIDLE); // Go to idle...
  304. cc2500_writeReg(CC2500_07_PKTCTRL1, 0x0D); // reg 0x07 hack: Append status, filter by address, auto-flush on bad crc, PQT=0
  305. //cc2500_writeReg(CC2500_0C_FSCTRL0, 0); // Frequency offset...
  306. cc2500_writeReg(CC2500_0C_FSCTRL0, bind ? 0x00 : count); // Frequency offset hack
  307. cc2500_writeReg(CC2500_0A_CHANNR, 0x00);
  308. }
  309. // Receives complete bind setup
  310. void getBind(void)
  311. {
  312. cc2500_strobe(CC2500_SRX);//enter in rx mode
  313. listLength = 0;
  314. boolean eol = false;
  315. // len|bind |tx id|idx|h0|h1|h2|h3|h4|00|00|00|00|00|00|01
  316. // Start by getting bind packet 0 and the txid
  317. // 0 1 2 txid0(3) txid1()4 5 6 7 8 9 10 11 12 13 14 15 16 17
  318. //ccdata //11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
  319. //11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01
  320. while (1) {
  321. if (GDO_1) {
  322. ccLen = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
  323. if (ccLen) {
  324. cc2500_readFifo((uint8_t *)ccData, ccLen);
  325. if (ccData[ccLen - 1] & 0x80) {
  326. if (ccData[2] == 0x01) {
  327. if (ccData[5] == 0x00) {
  328. txid[0] = ccData[3];
  329. txid[1] = ccData[4];
  330. for (uint8_t n = 0; n < 5; n++) {
  331. hopData[ccData[5] + n] = ccData[6 + n];
  332. }
  333. break;
  334. }
  335. }
  336. }
  337. }
  338. }
  339. }
  340. #if defined(DEBUG)
  341. Serial.print(txid[0], HEX);
  342. Serial.println(txid[1], HEX);
  343. #endif
  344. for (uint8_t bindIdx = 0x05; bindIdx <= 120; bindIdx += 5) {
  345. while (1) {
  346. if (GDO_1) {
  347. ccLen = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
  348. if (ccLen) {
  349. cc2500_readFifo((uint8_t *)ccData, ccLen);
  350. if (ccData[ccLen - 1] & 0x80) {
  351. if (ccData[2] == 0x01) {
  352. if(debug2) {
  353. //Serial.print(" ccData[2] = ");
  354. //Serial.println(ccData[2]);
  355. }
  356. if ((ccData[3] == txid[0]) && (ccData[4] == txid[1])) {
  357. if(debug3)
  358. {
  359. Serial.print("ccData[5] = ");
  360. Serial.println(ccData[5]);
  361. Serial.print("bindIdx = ");
  362. Serial.println(bindIdx);
  363. }
  364. if (ccData[5] == bindIdx) {
  365. for (uint8_t n = 0; n < 5; n++) {
  366. if(debug2)
  367. {
  368. Serial.print("ccData[6 + n] = ");
  369. Serial.println(ccData[6 + n]);
  370. Serial.print("ccData[ccLen - 3] = ");
  371. Serial.println(ccData[ccLen - 3]);
  372. }
  373. //if (ccData[6 + n] == ccData[ccLen - 3]) {
  374. if (ccData[6 + n] == 3) {
  375. eol = true;
  376. #if defined(DEBUG)
  377. Serial.print("listLength: ");
  378. Serial.println(listLength);
  379. #endif
  380. listLength = ccData[5] + n;
  381. break;
  382. }
  383. hopData[ccData[5] + n] = ccData[6 + n];
  384. }
  385. break;
  386. }
  387. }
  388. }
  389. }
  390. }
  391. }
  392. }
  393. #if defined(DEBUG)
  394. Serial.println(bindIdx / 5);
  395. #endif
  396. if (eol) break; // End of list found, stop!
  397. }
  398. #if defined(DEBUG)
  399. listLength = 47;
  400. Serial.println("jumpIdx list: ");
  401. for (uint8_t jumpIdx = 0; jumpIdx < (listLength); jumpIdx++) {
  402. Serial.print(" ");
  403. Serial.print(hopData[jumpIdx], HEX);
  404. Serial.print(" ");
  405. }
  406. Serial.println(" ");
  407. #endif
  408. Store_bind();
  409. cc2500_strobe(CC2500_SIDLE); // Back to idle
  410. }
  411. ISR(TIMER1_COMPA_vect)
  412. {
  413. TCNT1 = 0;
  414. if (jumper1 == 0) {
  415. pinMode(Servo5_OUT, OUTPUT);
  416. Servo_Ports_LOW;
  417. //code for servo.
  418. cur_chan_numb++; //next servo
  419. if (cur_chan_numb < chanel_number) {
  420. total_servo_time += Servo_data[cur_chan_numb] * scale;
  421. OCR1A = Servo_data[cur_chan_numb] * scale;
  422. } else {
  423. OCR1A = PPM_FrLen * scale - total_servo_time;
  424. cur_chan_numb = 0xff;
  425. total_servo_time = 0;
  426. }
  427. switch (cur_chan_numb) {
  428. case 0:
  429. Servo1_OUT_HIGH;
  430. break;
  431. case 1:
  432. Servo2_OUT_HIGH;
  433. break;
  434. case 2:
  435. Servo3_OUT_HIGH;
  436. break;
  437. case 3:
  438. Servo4_OUT_HIGH;
  439. break;
  440. case 4:
  441. Servo5_OUT_HIGH;
  442. break;
  443. case 5:
  444. Servo6_OUT_HIGH;
  445. break;
  446. case 6:
  447. Servo7_OUT_HIGH;
  448. break;
  449. case 7:
  450. Servo8_OUT_HIGH;
  451. break;
  452. }
  453. } else {
  454. static boolean state = true;
  455. pinMode(sigPin, OUTPUT);
  456. digitalWrite(sigPin, !onState);
  457. if (state) {
  458. digitalWrite(sigPin, onState);
  459. OCR1A = PPM_PulseLen * scale;
  460. state = false;
  461. } else {
  462. static byte cur_chan_numb;
  463. static unsigned int calc_rest;
  464. // digitalWrite(sigPin, !onState);//PPM on servo4 pin10
  465. state = true;
  466. if (cur_chan_numb >= chanel_number) {
  467. cur_chan_numb = 0;
  468. calc_rest = calc_rest + PPM_PulseLen;//
  469. OCR1A = (PPM_FrLen - calc_rest) * scale;
  470. calc_rest = 0;
  471. } else {
  472. OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * scale;
  473. calc_rest = calc_rest + ppm[cur_chan_numb];
  474. cur_chan_numb++;
  475. }
  476. }
  477. }
  478. }
  479. void config_timer()
  480. {
  481. OCR1A = 50 * scale;
  482. cli();
  483. TCCR1A = 0; //
  484. TCCR1B = 0;
  485. TCCR1B |= (1 << WGM12);
  486. TCCR1B |= (1 << CS11);
  487. TIMSK1 |= (1 << OCIE1A);
  488. sei();
  489. }
  490. void nextChannel(uint8_t skip)
  491. {
  492. channr += skip;//
  493. if (channr >= listLength) channr -= listLength;
  494. cc2500_writeReg(CC2500_0A_CHANNR, hopData[channr]);
  495. cc2500_writeReg(CC2500_23_FSCAL3, 0x89);
  496. }
  497. void binding()
  498. {
  499. jumper2 = bind_jumper();
  500. while (1) {
  501. if (jumper2 == 0) { //bind complete or no bind
  502. uint8_t i;
  503. uint8_t adr = 100;
  504. for (i = 0; i < 2; i++) {
  505. txid[i] = EEPROM.read(adr + i);
  506. }
  507. for (i = 0; i < sizeof(hopData); i++) {
  508. hopData[i] = EEPROM.read(adr + 10 + i);
  509. }
  510. listLength = EEPROM.read(adr + 100);
  511. count = EEPROM.read(adr + 101);
  512. break;
  513. } else {
  514. LED_ON;
  515. tunning();
  516. //count=0xC8;//for test
  517. cc2500_writeReg(CC2500_0C_FSCTRL0, count);
  518. int adr = 100;
  519. EEPROM.write(adr + 101, count);
  520. getBind();
  521. while (1) {
  522. LED_ON;
  523. delay(500);
  524. LED_OFF;
  525. delay(500);
  526. }
  527. }
  528. }
  529. }
  530. void tunning()
  531. {
  532. cc2500_strobe(CC2500_SRX);//enter in rx mode
  533. int count1 = 0;
  534. while (1) {
  535. count1++;
  536. if (count >= 250) {
  537. count = 0;
  538. }
  539. if (count1 > 3000) {
  540. count1 = 0;
  541. cc2500_writeReg(CC2500_0C_FSCTRL0, count); // Frequency offset hack
  542. count = count + 10;
  543. //cc2500_strobe(CC2500_SRX);//enter in rx mode
  544. }
  545. if (GDO_1) {
  546. ccLen = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
  547. if (ccLen) {
  548. cc2500_readFifo((uint8_t *)ccData, ccLen);
  549. if (ccData[ccLen - 1] & 0x80) {
  550. if (ccData[2] == 0x01) {
  551. if (ccData[5] == 0x00) {
  552. break;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. }
  559. #if defined(DEBUG1)
  560. Serial.println(count, HEX);
  561. #endif
  562. }
  563. void Store_bind()
  564. {
  565. uint8_t i;
  566. int adr = 100;
  567. for (i = 0; i < 2; i++) {
  568. EEPROM.write(adr + i, txid[i]);
  569. }
  570. for (i = 0; i < sizeof(hopData); i++) {
  571. EEPROM.write(adr + 10 + i, hopData[i]);
  572. }
  573. EEPROM.write(adr + 100, listLength);
  574. }
  575. unsigned char PPM_jumper(void)
  576. {
  577. // PPM Selection (jumper between Ch1 and ch3)
  578. pinMode(Servo3_OUT, INPUT); //CH3 input
  579. digitalWrite(Servo3_OUT, HIGH); // pull up
  580. digitalWrite(Servo1_OUT, HIGH); // CH1 is HIGH
  581. delayMicroseconds(1);
  582. if ( digitalRead(Servo3_OUT) == HIGH) {
  583. digitalWrite(Servo1_OUT, LOW); // CH1 is LOW
  584. delayMicroseconds(1);
  585. if (digitalRead(Servo3_OUT) == LOW) { // OK jumper plugged
  586. pinMode(Servo3_OUT, OUTPUT);
  587. return 1;
  588. }
  589. }
  590. pinMode(Servo3_OUT, OUTPUT);
  591. return 0; // servo PWM by default
  592. }
  593. //bind jumper
  594. unsigned char bind_jumper(void)
  595. {
  596. pinMode(bind_pin, INPUT_PULLUP);//pull up
  597. if ( digitalRead(bind_pin) == LOW) {
  598. delayMicroseconds(1);
  599. return 1;
  600. }
  601. return 0;
  602. }