Subversion Repositories FlightCtrl

Rev

Rev 1152 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1152 Rev 1208
1
/*
1
/*
2
    Copyright (c) 2008 Stefan Engelke <stefan@tinkerer.eu>
2
    Copyright (c) 2008 Stefan Engelke <stefan@tinkerer.eu>
3
 
3
 
4
    Permission is hereby granted, free of charge, to any person
4
    Permission is hereby granted, free of charge, to any person
5
    obtaining a copy of this software and associated documentation
5
    obtaining a copy of this software and associated documentation
6
    files (the "Software"), to deal in the Software without
6
    files (the "Software"), to deal in the Software without
7
    restriction, including without limitation the rights to use, copy,
7
    restriction, including without limitation the rights to use, copy,
8
    modify, merge, publish, distribute, sublicense, and/or sell copies
8
    modify, merge, publish, distribute, sublicense, and/or sell copies
9
    of the Software, and to permit persons to whom the Software is
9
    of the Software, and to permit persons to whom the Software is
10
    furnished to do so, subject to the following conditions:
10
    furnished to do so, subject to the following conditions:
11
 
11
 
12
    The above copyright notice and this permission notice shall be
12
    The above copyright notice and this permission notice shall be
13
    included in all copies or substantial portions of the Software.
13
    included in all copies or substantial portions of the Software.
14
 
14
 
15
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
    DEALINGS IN THE SOFTWARE.
22
    DEALINGS IN THE SOFTWARE.
23
   
23
   
24
    $Id: rcdsl.c 62 2008-08-21 16:09:07Z tensor $
24
    $Id: rcdsl.c 62 2008-08-21 16:09:07Z tensor $
25
   
25
   
26
    RCDSL.H and RCDSL.C is an INOFFICIAL implementation of the
26
    RCDSL.H and RCDSL.C is an INOFFICIAL implementation of the
27
    communication protocol used by DSL receivers of Act Europe.
27
    communication protocol used by DSL receivers of Act Europe.
28
    The DSL receivers have a serial communication port to connect
28
    The DSL receivers have a serial communication port to connect
29
    two receivers in diversity mode. Each receiver is sending the
29
    two receivers in diversity mode. Each receiver is sending the
30
    received servo signals periodically over this port. This fact
30
    received servo signals periodically over this port. This fact
31
    can be used to connect the receiver to the control unit of the
31
    can be used to connect the receiver to the control unit of the
32
    model via UART instead of evaluating the PPM signal.
32
    model via UART instead of evaluating the PPM signal.
33
    The UART parameters are
33
    The UART parameters are
34
    38400 Baud, 8-N-1
34
    38400 Baud, 8-N-1
35
   
35
   
36
    If you have any questions, feel free to send me an e-mail.
36
    If you have any questions, feel free to send me an e-mail.
-
 
37
 
-
 
38
Connection of DSL to SV1 of FC:
-
 
39
( DSL Pin1 is on side of channel 4 )
-
 
40
 
-
 
41
1. GND <--> pin 7 (GND)
-
 
42
2. TXD <--> pin 3 (RXD1 Atmega644p)
-
 
43
3. RXD <--> pin 4 (TXD1 Atmega644p) optional
-
 
44
4. 5V  <--> pin 2 (5V)
-
 
45
 
-
 
46
Do not connect the receiver via PPM-Sumsignal output the same time.
-
 
47
 
-
 
48
Data are send at 38400baud8n1
-
 
49
 
-
 
50
Data Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|10|CH0D1|CH0D0|CH1D1|CH1D0|CRC| ...etc
-
 
51
 
-
 
52
FREQALLOC = 35, 40, 72
-
 
53
RSSI = 0.. 255 // Received signal strength indicator
-
 
54
VBAT = 0...255 // supply voltage (0.0V.. 8.2V)
-
 
55
 
-
 
56
Servo Pair:   |0x1X|CHXD1|CHXD0|CHX+1D1|CHX+1D0|CRC|
-
 
57
X is channel index of 1 servo value
-
 
58
D1D0 is servo value as u16 in range of 7373 (1ms) to 14745 (2ms)
-
 
59
there are 8 channels submitted, i.e 4 servo pairs
-
 
60
 
-
 
61
 
-
 
62
Frame examples with signel received
-
 
63
 
-
 
64
FFFF 1F23F079A304AD 1036012B1E6F 122AFB2AECB2 142B4D2B4404 1636872B33CE
-
 
65
FFFF 1F23F079A304AD 1036002B1F6F 122AFE2AEBB0 142B4B2B4406 1636872B33CE
-
 
66
FFFF 1F23F079A304AD 1035FF2B226E 122AFC2AEAB3 142B4E2B4304 1636882B33CD
-
 
67
FFFF 1F23F079A304AD 1036022B1E6E 122AFB2AEEB0 142B4A2B4506 1636872B33CE
-
 
68
FFFF 1F23F079A304AD 1036022B1E6E 122AFE2AEBB0 142B4B2B4406 1636882B33CD
-
 
69
FFFF 1F23F079A304AD 1036012B1E6F 122AFD2AEAB2 142B4E2B4403 1636862B33CF
-
 
70
FFFF 1F23F079A304AD 1036032B1D6E 122AFD2AEBB1 142B4C2B4504 1636862B33CF
-
 
71
 
-
 
72
Frame examples with no signal received
-
 
73
 
-
 
74
FFFF 1F23F000A30426
-
 
75
FFFF 1F23F000A30426
-
 
76
FFFF 1F23F000A30426
-
 
77
FFFF 1F23F000A30426
-
 
78
FFFF 1F23F000A30426
-
 
79
FFFF 1F23F000A30426
37
 
80
FFFF 1F23F000A30426
38
*/
81
*/
39
 
82
 
40
#include "rcdsl.h"
83
#include "rcdsl.h"
41
 
84
 
42
#include "main.h"
85
#include "main.h"
43
 
86
 
44
volatile unsigned char data_counter   = 0;
87
volatile unsigned char data_counter   = 0;
45
volatile unsigned char last_byte      = 0;
88
volatile unsigned char last_byte      = 0;
46
unsigned char check_sum      = 0;
89
unsigned char check_sum      = 0;
47
unsigned char paket_len      = 0;
90
unsigned char paket_len      = 0;
48
 
91
 
49
#define UART1_BAUDRATE 38400
92
#define UART1_BAUDRATE 38400
50
 
93
 
51
volatile uint8_t rcdsl_RSSI = 0;
94
volatile uint8_t rcdsl_RSSI = 0;
52
uint8_t rcdsl_battery=0;
95
volatile uint8_t rcdsl_battery=0;
53
uint8_t rcdsl_allocation=0;
96
volatile uint8_t rcdsl_allocation=0;
54
uint8_t data[6];
97
volatile uint8_t data[6];
55
 
98
 
56
typedef union {
99
typedef union {
57
        uint16_t pos[2];
100
        uint16_t pos[2];
58
        uint8_t dat[4];
101
        uint8_t dat[4];
59
} servos_t;
102
} servos_t;
-
 
103
 
60
 
104
 
61
void rcdsl_init(void) {
105
void rcdsl_init(void) {
62
 
106
 
63
    // Save state of status register and disable interrupts
107
    // Save state of status register and disable interrupts
64
    uint8_t sreg = SREG;
108
    uint8_t sreg = SREG;
65
    cli();
109
    cli();
66
 
110
 
67
    // Set baud rate
111
    // Set baud rate
68
    UBRR1 = (uint16_t) ((uint32_t) F_CPU/(16*UART1_BAUDRATE) - 1);
112
    UBRR1 = (uint16_t) ((uint32_t) F_CPU/(16*UART1_BAUDRATE) - 1);
69
 
113
 
70
 
114
 
71
    // UART Receiver und Transmitter anschalten 
115
    // UART Receiver und Transmitter anschalten 
72
    // Data mode 8N1, asynchron 
116
    // Data mode 8N1, asynchron 
73
    UCSR1B = (1 << RXEN1) | (1 << TXEN0) | (1 << RXCIE1);
117
    UCSR1B = (1 << RXEN1) | (1 << TXEN0) | (1 << RXCIE1);
74
    UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);
118
    UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);
75
 
119
 
76
    // Flush Receive-Buffer
120
    // Flush Receive-Buffer
77
    do { UDR1; }
121
    do { UDR1; }
78
    while (UCSR1A & (1 << RXC1));
122
    while (UCSR1A & (1 << RXC1));
79
 
123
 
80
    // Clear rx and tx interrupt flags
124
    // Clear rx and tx interrupt flags
81
    UCSR1A = (1 << RXC1) | (1 << TXC1);
125
    UCSR1A = (1 << RXC1) | (1 << TXC1);
82
 
126
 
83
    // Reactive interrupts, if they were active before
127
    // Reactive interrupts, if they were active before
84
    SREG = sreg;
128
    SREG = sreg;
-
 
129
 
-
 
130
    printf("\n\rUART 1 initialized.");
85
 
131
 
86
}
132
}
87
 
133
 
88
void rcdsl_new_signal(uint8_t channel, int16_t signal)
134
void rcdsl_new_signal(uint8_t channel, int16_t signal)
89
// This function is called, when a new servo signal is properly received.
135
// This function is called, when a new servo signal is properly received.
90
// Parameters: servo  - servo number (0-9)
136
// Parameters: servo  - servo number (0-9)
91
//             signal - servo signal between 7373 (1ms) and 14745 (2ms)
137
//             signal - servo signal between 7373 (1ms) and 14745 (2ms)
92
{  
138
{
93
    volatile signed int tmp;
139
    volatile signed int tmp;
94
    uint8_t index = channel+1; // Der MK fängt bei 1 an zu zählen
140
    uint8_t index = channel+1; // Der MK fängt bei 1 an zu zählen
95
   
141
   
96
 
142
 
97
    // Signal vom  ACTDSL-Empfänger liegt zwischen
143
    // Signal vom  ACTDSL-Empfänger liegt zwischen
98
    // 7373 (1ms) und 14745 (2ms). 
144
    // 7373 (1ms) und 14745 (2ms). 
99
    signal-= 11059;     // Neutralstellung zur Null verschieben
145
    signal-= 11059;     // Neutralstellung zur Null verschieben
100
    signal/= 24;        // Auf MK Skalierung umrechnen
146
    signal/= 24;        // Auf MK Skalierung umrechnen
101
 
147
 
102
    // Stabiles Signal
148
    // Stabiles Signal
103
    //if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
149
    //if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
104
 
150
 
105
    tmp = (3 * (PPM_in[index]) + signal) / 4;  
151
    tmp = (3 * (PPM_in[index]) + signal) / 4;  
106
    if(tmp > signal+1) tmp--; else
152
    if(tmp > signal+1) tmp--; else
107
    if(tmp < signal-1) tmp++;
153
    if(tmp < signal-1) tmp++;
108
    if(SenderOkay >= 105)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
154
    if(SenderOkay >= 105)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
109
    else PPM_diff[index] = 0;
155
    else PPM_diff[index] = 0;
110
    PPM_in[index] = tmp;
156
    PPM_in[index] = tmp;
111
    //NewPpmData = 0;
157
    //NewPpmData = 0;
112
    //NewActData = 1;
158
    //NewActData = 1;
113
    if(index == 4)  {
159
    if(index == 4)  {
114
        //NewActData = 1;
160
        //NewActData = 1;
115
        NewPpmData = 0;
161
        NewPpmData = 0;
116
        //PORTC = (PORTC&(~(1<<PC4))) | ((~PORTC)&(1<<PC4));
162
        //PORTC = (PORTC&(~(1<<PC4))) | ((~PORTC)&(1<<PC4));
117
        //PINC = (1<<PC4);
163
        //PINC = (1<<PC4);
118
    }
164
    }
119
    //PPM_in[index] = signal;      
165
    //PPM_in[index] = signal;      
120
 
166
 
121
}
167
}
122
 
168
 
123
 
169
 
124
void rcdsl_incoming_paket(void)
170
void rcdsl_incoming_paket(void)
125
// This function is called within rcdsl_parse_data(), when a complete 
171
// This function is called within rcdsl_parse_data(), when a complete 
126
// data paket with matching checksum has been received.
172
// data paket with matching checksum has been received.
127
{
173
{
128
   
174
   
129
    uint8_t  i;
175
    uint8_t  i;
130
    static servos_t servos;
176
    static servos_t servos;
131
    // Look for status headers
177
    // Look for status headers
132
    if ((data[0])==0x1F) {
178
    if ((data[0])==0x1F) {
133
        // Get frequency allocation
179
        // Get frequency allocation
134
        rcdsl_allocation = data[0+1];
180
        rcdsl_allocation = data[0+1];
135
        // Get signal quality
181
        // Get signal quality 
136
        rcdsl_RSSI = data[2+1];
182
        rcdsl_RSSI = data[2+1];
-
 
183
        SenderOkay = (212 * (uint16_t) rcdsl_RSSI) / 128; // have to be scaled approx. by a factor of 1.66 to get 200 at full level
-
 
184
        if(SenderOkay > 255) SenderOkay = 255;
137
        // Get voltage of battery supply
185
        // Get voltage of battery supply
138
        rcdsl_battery = data[3+1];
186
        rcdsl_battery = data[3+1];
139
    }
187
    }
140
 
188
 
141
    // Look for signal headers
189
    // Look for signal headers
142
    if ((data[0]&0xF0)==0x10) {
190
    if ((data[0]&0xF0)==0x10) {
143
   
191
   
144
        i = data[0]&0x0F;   // Last 4 bits of the header indicates servo pair
192
        i = data[0]&0x0F;   // Last 4 bits of the header indicates servo pair
145
 
193
 
146
        if (i<10) {
194
        if (i<10) {
147
            // Convert byte array to two uint16
195
            // Convert byte array to two uint16
148
            servos.dat[1] = data[1];
196
            servos.dat[1] = data[1];
149
            servos.dat[0] = data[2];
197
            servos.dat[0] = data[2];
150
            servos.dat[3] = data[3];
198
            servos.dat[3] = data[3];
151
            servos.dat[2] = data[4];
199
            servos.dat[2] = data[4];
152
           
200
           
153
            rcdsl_new_signal(i  ,  (int16_t)servos.pos[0]);
201
            rcdsl_new_signal(i  ,  (int16_t)servos.pos[0]);
154
            rcdsl_new_signal(i+1,  (int16_t)servos.pos[1]);
202
            rcdsl_new_signal(i+1,  (int16_t)servos.pos[1]);
155
        }
203
        }
156
    }
204
    }
157
}
205
}
158
 
206
 
159
 
207
 
160
void rcdsl_parse_data(uint8_t b)
208
void rcdsl_parse_data(uint8_t b)
161
// This function should be called externaly, when a new data byte has 
209
// This function should be called externaly, when a new data byte has 
162
// been received over uart.
210
// been received over uart.
163
{
211
{
164
 
212
 
165
    // Check for sync condition
213
    // Check for sync condition
166
    if ((b==0xFF) && (last_byte==0xFF)) {
214
    if ((b==0xFF) && (last_byte==0xFF)) {
167
        data_counter = 0;
215
        data_counter = 0;
168
        check_sum = 0;
216
        check_sum = 0;
169
        return;
217
        return;
170
    }
218
    }
171
   
219
   
172
    // First byte is cmd
220
    // First byte is cmd
173
    if (data_counter == 0) {
221
    if (data_counter == 0) {
174
        if (b==0x1F) paket_len = 5; else paket_len=4;
222
        if (b==0x1F) paket_len = 5; else paket_len=4;
175
    }
223
    }
176
 
224
 
177
    // Last byte is checksum
225
    // Last byte is checksum
178
    if (data_counter > paket_len) {
226
    if (data_counter > paket_len) {
179
       
227
       
180
        // Calculate checksum
228
        // Calculate checksum
181
        check_sum = ~check_sum;
229
        check_sum = ~check_sum;
182
        if (check_sum==0xFF) check_sum=0xFE;
230
        if (check_sum==0xFF) check_sum=0xFE;
183
 
231
 
184
        // If it match the received one, then apply data
232
        // If it match the received one, then apply data
185
        if (b==check_sum) rcdsl_incoming_paket();
233
        if (b==check_sum) rcdsl_incoming_paket();
186
 
234
 
187
        // Prepare for a new data paket
235
        // Prepare for a new data paket
188
        data_counter = 0;
236
        data_counter = 0;
189
        check_sum = 0;
237
        check_sum = 0;
190
 
238
 
191
 
239
 
192
    // New byte within a paket
240
    // New byte within a paket
193
    } else {
241
    } else {
194
 
242
 
195
        data[data_counter]  = b;
243
        data[data_counter]  = b;
196
        check_sum          += b;
244
        check_sum          += b;
197
        data_counter++;
245
        data_counter++;
198
 
246
 
199
    }
247
    }
200
           
248
           
201
    // Remember last byte received for detection of sync condition
249
    // Remember last byte received for detection of sync condition
202
    last_byte = b;
250
    last_byte = b;
203
}
251
}
204
 
252
 
205
 
253
 
206
ISR (USART1_RX_vect)
254
ISR (USART1_RX_vect)
207
{
255
{
208
    rcdsl_parse_data(UDR1);
256
    rcdsl_parse_data(UDR1);
209
}
257
}
210
 
258