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 22KB

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