Browse Source

Ran AStyle to make a bit more readable.

Read Error 10 years ago
commit
042a471858
4 changed files with 888 additions and 0 deletions
  1. 122
    0
      cc2500_BB_SPI.ino
  2. 632
    0
      frsky_arduino_rx_complete.ino
  3. 133
    0
      iface_cc2500.h
  4. 1
    0
      readme.txt

+ 122
- 0
cc2500_BB_SPI.ino View File

@@ -0,0 +1,122 @@
1
+//-------------------------------
2
+//-------------------------------
3
+//CC2500 SPI routines
4
+//-------------------------------
5
+//-------------------------------
6
+#include <util/delay.h>
7
+
8
+void cc2500_readFifo(uint8_t *dpbuffer, int len)
9
+{
10
+    ReadRegisterMulti(CC2500_3F_RXFIFO | CC2500_READ_BURST, dpbuffer, len);
11
+}
12
+
13
+//----------------------
14
+static void ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length)
15
+{
16
+    unsigned char i;
17
+
18
+    CS_off;
19
+    _spi_write(address);
20
+    for (i = 0; i < length; i++) {
21
+        data[i] = _spi_read();
22
+    }
23
+    CS_on;
24
+}
25
+
26
+//*********************************************
27
+
28
+void CC2500_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length)
29
+{
30
+    CS_off;
31
+    _spi_write(CC2500_WRITE_BURST | address);
32
+    for (int i = 0; i < length; i++) {
33
+        _spi_write(data[i]);
34
+    }
35
+    CS_on;
36
+}
37
+
38
+void cc2500_writeFifo(uint8_t *dpbuffer, uint8_t len)
39
+{
40
+    cc2500_strobe(CC2500_SFTX);//0x3B
41
+    CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, dpbuffer, len);
42
+    cc2500_strobe(CC2500_STX);//0x35
43
+}
44
+
45
+//--------------------------------------
46
+void _spi_write(uint8_t command)
47
+{
48
+    uint8_t n = 8;
49
+    SCK_off;//SCK start low
50
+    MO_off;
51
+    while (n--) {
52
+        if (command & 0x80)
53
+            MO_on;
54
+        else
55
+            MO_off;
56
+        SCK_on;
57
+        NOP();
58
+        SCK_off;
59
+        command = command << 1;
60
+    }
61
+    MO_on;
62
+}
63
+
64
+//----------------------------
65
+void cc2500_writeReg(uint8_t address, uint8_t data)  //same as 7105
66
+{
67
+    CS_off;
68
+    _spi_write(address);
69
+    NOP();
70
+    _spi_write(data);
71
+    CS_on;
72
+}
73
+
74
+uint8_t _spi_read(void)
75
+{
76
+    uint8_t result;
77
+    uint8_t i;
78
+    result = 0;
79
+    for (i = 0; i < 8; i++) {
80
+        if (MI_1) ///
81
+            result = (result << 1) | 0x01;
82
+        else
83
+            result = result << 1;
84
+        SCK_on;
85
+        NOP();
86
+        SCK_off;
87
+        NOP();
88
+    }
89
+    return result;
90
+}
91
+
92
+//--------------------------------------------
93
+unsigned char cc2500_readReg(unsigned char address)
94
+{
95
+    uint8_t result;
96
+    CS_off;
97
+    address |= 0x80; //bit 7 =1 for reading
98
+    _spi_write(address);
99
+    result = _spi_read();
100
+    CS_on;
101
+    return (result);
102
+}
103
+//------------------------
104
+void cc2500_strobe(uint8_t address)
105
+{
106
+    CS_off;
107
+    _spi_write(address);
108
+    CS_on;
109
+}
110
+//------------------------
111
+void cc2500_resetChip(void)
112
+{
113
+    // Toggle chip select signal
114
+    CS_on;
115
+    _delay_us(30);
116
+    CS_off;
117
+    _delay_us(30);
118
+    CS_on;
119
+    _delay_us(45);
120
+    cc2500_strobe(CC2500_SRES);
121
+    _delay_ms(100);
122
+}

+ 632
- 0
frsky_arduino_rx_complete.ino View File

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

+ 133
- 0
iface_cc2500.h View File

@@ -0,0 +1,133 @@
1
+#ifndef _IFACE_CC2500_H_
2
+#define _IFACE_CC2500_H_
3
+
4
+enum {
5
+    CC2500_00_IOCFG2           = 0x00,        // GDO2 output pin configuration
6
+    CC2500_01_IOCFG1           = 0x01,        // GDO1 output pin configuration
7
+    CC2500_02_IOCFG0           = 0x02,        // GDO0 output pin configuration
8
+    CC2500_03_FIFOTHR          = 0x03,        // RX FIFO and TX FIFO thresholds
9
+    CC2500_04_SYNC1            = 0x04,        // Sync word, high byte
10
+    CC2500_05_SYNC0            = 0x05,        // Sync word, low byte
11
+    CC2500_06_PKTLEN           = 0x06,        // Packet length
12
+    CC2500_07_PKTCTRL1         = 0x07,        // Packet automation control
13
+    CC2500_08_PKTCTRL0         = 0x08,        // Packet automation control
14
+    CC2500_09_ADDR             = 0x09,        // Device address
15
+    CC2500_0A_CHANNR           = 0x0A,        // Channel number
16
+    CC2500_0B_FSCTRL1          = 0x0B,        // Frequency synthesizer control
17
+    CC2500_0C_FSCTRL0          = 0x0C,        // Frequency synthesizer control
18
+    CC2500_0D_FREQ2            = 0x0D,        // Frequency control word, high byte
19
+    CC2500_0E_FREQ1            = 0x0E,        // Frequency control word, middle byte
20
+    CC2500_0F_FREQ0            = 0x0F,        // Frequency control word, low byte
21
+    CC2500_10_MDMCFG4          = 0x10,        // Modem configuration
22
+    CC2500_11_MDMCFG3          = 0x11,        // Modem configuration
23
+    CC2500_12_MDMCFG2          = 0x12,        // Modem configuration
24
+    CC2500_13_MDMCFG1          = 0x13,        // Modem configuration
25
+    CC2500_14_MDMCFG0          = 0x14,        // Modem configuration
26
+    CC2500_15_DEVIATN          = 0x15,        // Modem deviation setting
27
+    CC2500_16_MCSM2            = 0x16,        // Main Radio Cntrl State Machine config
28
+    CC2500_17_MCSM1            = 0x17,        // Main Radio Cntrl State Machine config
29
+    CC2500_18_MCSM0            = 0x18,        // Main Radio Cntrl State Machine config
30
+    CC2500_19_FOCCFG           = 0x19,        // Frequency Offset Compensation config
31
+    CC2500_1A_BSCFG            = 0x1A,        // Bit Synchronization configuration
32
+    CC2500_1B_AGCCTRL2         = 0x1B,        // AGC control
33
+    CC2500_1C_AGCCTRL1         = 0x1C,        // AGC control
34
+    CC2500_1D_AGCCTRL0         = 0x1D,        // AGC control
35
+    CC2500_1E_WOREVT1          = 0x1E,        // High byte Event 0 timeout
36
+    CC2500_1F_WOREVT0          = 0x1F,        // Low byte Event 0 timeout
37
+    CC2500_20_WORCTRL          = 0x20,        // Wake On Radio control
38
+    CC2500_21_FREND1           = 0x21,        // Front end RX configuration
39
+    CC2500_22_FREND0           = 0x22,        // Front end TX configuration
40
+    CC2500_23_FSCAL3           = 0x23,        // Frequency synthesizer calibration
41
+    CC2500_24_FSCAL2           = 0x24,        // Frequency synthesizer calibration
42
+    CC2500_25_FSCAL1           = 0x25,        // Frequency synthesizer calibration
43
+    CC2500_26_FSCAL0           = 0x26,        // Frequency synthesizer calibration
44
+    CC2500_27_RCCTRL1          = 0x27,        // RC oscillator configuration
45
+    CC2500_28_RCCTRL0          = 0x28,        // RC oscillator configuration
46
+    CC2500_29_FSTEST           = 0x29,        // Frequency synthesizer cal control
47
+    CC2500_2A_PTEST            = 0x2A,        // Production test
48
+    CC2500_2B_AGCTEST          = 0x2B,        // AGC test
49
+    CC2500_2C_TEST2            = 0x2C,        // Various test settings
50
+    CC2500_2D_TEST1            = 0x2D,        // Various test settings
51
+    CC2500_2E_TEST0            = 0x2E,        // Various test settings
52
+
53
+// Status registers
54
+    CC2500_30_PARTNUM          = 0x30,        // Part number
55
+    CC2500_31_VERSION          = 0x31,        // Current version number
56
+    CC2500_32_FREQEST          = 0x32,        // Frequency offset estimate
57
+    CC2500_33_LQI              = 0x33,        // Demodulator estimate for link quality
58
+    CC2500_34_RSSI             = 0x34,        // Received signal strength indication
59
+    CC2500_35_MARCSTATE        = 0x35,        // Control state machine state
60
+    CC2500_36_WORTIME1         = 0x36,        // High byte of WOR timer
61
+    CC2500_37_WORTIME0         = 0x37,        // Low byte of WOR timer
62
+    CC2500_38_PKTSTATUS        = 0x38,        // Current GDOx status and packet status
63
+    CC2500_39_VCO_VC_DAC       = 0x39,        // Current setting from PLL cal module
64
+    CC2500_3A_TXBYTES          = 0x3A,        // Underflow and # of bytes in TXFIFO
65
+    CC2500_3B_RXBYTES          = 0x3B,        // Overflow and # of bytes in RXFIFO
66
+
67
+// Multi byte memory locations
68
+    CC2500_3E_PATABLE          = 0x3E,
69
+    CC2500_3F_TXFIFO           = 0x3F,
70
+    CC2500_3F_RXFIFO           = 0x3F,
71
+};
72
+
73
+// Definitions for burst/single access to registers
74
+#define CC2500_WRITE_SINGLE     0x00
75
+#define CC2500_WRITE_BURST      0x40
76
+#define CC2500_READ_SINGLE      0x80
77
+#define CC2500_READ_BURST       0xC0
78
+
79
+// Strobe commands
80
+#define CC2500_SRES             0x30        // Reset chip.
81
+#define CC2500_SFSTXON          0x31        // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
82
+                                            // If in RX/TX: Go to a wait state where only the synthesizer is
83
+                                            // running (for quick RX / TX turnaround).
84
+#define CC2500_SXOFF            0x32        // Turn off crystal oscillator.
85
+#define CC2500_SCAL             0x33        // Calibrate frequency synthesizer and turn it off
86
+                                            // (enables quick start).
87
+#define CC2500_SRX              0x34        // Enable RX. Perform calibration first if coming from IDLE and
88
+                                            // MCSM0.FS_AUTOCAL=1.
89
+#define CC2500_STX              0x35        // In IDLE state: Enable TX. Perform calibration first if
90
+                                            // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
91
+                                            // Only go to TX if channel is clear.
92
+#define CC2500_SIDLE            0x36        // Exit RX / TX, turn off frequency synthesizer and exit
93
+                                            // Wake-On-Radio mode if applicable.
94
+#define CC2500_SAFC             0x37        // Perform AFC adjustment of the frequency synthesizer
95
+#define CC2500_SWOR             0x38        // Start automatic RX polling sequence (Wake-on-Radio)
96
+#define CC2500_SPWD             0x39        // Enter power down mode when CSn goes high.
97
+#define CC2500_SFRX             0x3A        // Flush the RX FIFO buffer.
98
+#define CC2500_SFTX             0x3B        // Flush the TX FIFO buffer.
99
+#define CC2500_SWORRST          0x3C        // Reset real time clock.
100
+#define CC2500_SNOP             0x3D        // No operation. May be used to pad strobe commands to two
101
+                                            // bytes for simpler software.
102
+//----------------------------------------------------------------------------------
103
+// Chip Status Byte
104
+//----------------------------------------------------------------------------------
105
+
106
+// Bit fields in the chip status byte
107
+#define CC2500_STATUS_CHIP_RDYn_BM             0x80
108
+#define CC2500_STATUS_STATE_BM                 0x70
109
+#define CC2500_STATUS_FIFO_BYTES_AVAILABLE_BM  0x0F
110
+
111
+// Chip states
112
+#define CC2500_STATE_IDLE                      0x00
113
+#define CC2500_STATE_RX                        0x10
114
+#define CC2500_STATE_TX                        0x20
115
+#define CC2500_STATE_FSTXON                    0x30
116
+#define CC2500_STATE_CALIBRATE                 0x40
117
+#define CC2500_STATE_SETTLING                  0x50
118
+#define CC2500_STATE_RX_OVERFLOW               0x60
119
+#define CC2500_STATE_TX_UNDERFLOW              0x70
120
+
121
+//----------------------------------------------------------------------------------
122
+// Other register bit fields
123
+//----------------------------------------------------------------------------------
124
+#define CC2500_LQI_CRC_OK_BM                   0x80
125
+#define CC2500_LQI_EST_BM                      0x7F
126
+
127
+//void CC2500_WriteReg(u8 addr, u8 data);
128
+//u8 CC2500_ReadReg(u8 addr);
129
+//void CC2500_Reset();
130
+//void CC2500_Strobe(u8 cmd);
131
+//void CC2500_WriteData(u8 *packet, u8 length);
132
+//void CC2500_ReadData(u8 *dpbuffer, int len);
133
+#endif

+ 1
- 0
readme.txt View File

@@ -0,0 +1 @@
1
+ with autotuning complete with 8 channels servo and PPM out

Loading…
Cancel
Save