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

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