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

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