Subversion Repositories FlightCtrl

Rev

Rev 885 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 885 Rev 886
Line 1... Line 1...
1
/*#######################################################################################
1
/*#######################################################################################
2
Decodieren eines RC Summen Signals
2
Decodieren eines RC Summen Signals
3
#######################################################################################*/
3
#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Copyright (c) 04.2007 Holger Buss
5
// + Copyright (c) 04.2007 Holger Buss
6
// + only for non-profit use
6
// + only for non-profit use
7
// + www.MikroKopter.com
7
// + www.MikroKopter.com
8
// + see the File "License.txt" for further Informations
8
// + see the File "License.txt" for further Informations
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Line -... Line 10...
-
 
10
 
-
 
11
#include <stdlib.h>
-
 
12
#include <avr/io.h>
-
 
13
#include <avr/interrupt.h>
10
 
14
 
11
#include "rc.h"
15
#include "rc.h"
Line -... Line 16...
-
 
16
#include "main.h"
12
#include "main.h"
17
 
-
 
18
volatile int16_t PPM_in[15]; //PPM24 supports 12 channels per frame
13
 
19
volatile int16_t PPM_diff[15];
-
 
20
volatile uint8_t NewPpmData = 1;
14
volatile int PPM_in[11];
21
volatile int16_t RC_Quality = 0;
-
 
22
 
15
volatile int PPM_diff[11];  // das diffenzierte Stick-Signal
23
volatile uint8_t NewRCFrames = 0;
16
volatile unsigned char NewPpmData = 1;
24
 
17
 
25
 
18
//############################################################################
26
/***************************************************************/
19
//zum decodieren des PPM-Signals wird Timer1 mit seiner Input
27
/*  16bit timer 1 is used to decode the PPM-Signal            */
20
//Capture Funktion benutzt:
-
 
21
void rc_sum_init (void)
28
/***************************************************************/
-
 
29
void RC_Init (void)
-
 
30
{
-
 
31
        uint8_t sreg = SREG;
-
 
32
 
-
 
33
        // disable all interrupts before reconfiguration
-
 
34
        cli();
-
 
35
 
-
 
36
        // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
-
 
37
        DDRD &= ~(1<<DDD6);
-
 
38
        PORTD |= (1<<PORTD6);
-
 
39
 
-
 
40
        // Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
-
 
41
        // set as output
-
 
42
        DDRD |= (1<<DDD5)|(1<<DDD4);
-
 
43
        // low level
-
 
44
        PORTD &= ~((1<<PORTD5)|(1<<PORTD4));
-
 
45
 
-
 
46
        // PD3 can't be used in FC 1.1 if 2nd UART is activated
-
 
47
        // because TXD1 is at that port
-
 
48
        if(BoardRelease == 10)
-
 
49
        {
-
 
50
                DDRD |= (1<<PORTD3);
-
 
51
                PORTD &= ~(1<<PORTD3);
-
 
52
        }
-
 
53
 
-
 
54
        // Timer/Counter1 Control Register A, B, C
-
 
55
 
-
 
56
        // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
-
 
57
        // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
-
 
58
        // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
-
 
59
        // Enable input capture noise cancler (bit: ICNC1=1)
-
 
60
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
22
//############################################################################
61
        // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
-
 
62
    // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
-
 
63
        TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
-
 
64
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
-
 
65
        TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
-
 
66
        TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
-
 
67
 
-
 
68
        // Timer/Counter1 Interrupt Mask Register
-
 
69
 
-
 
70
        // Enable Input Capture Interrupt (bit: ICIE1=1)
-
 
71
        // Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
-
 
72
        // Enable Overflow Interrupt (bit: TOIE1=0)
Line 23... Line -...
23
{
-
 
24
        TCCR1B=(1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);//|(1 << WGM12); //timer1 prescale 64
-
 
25
 
-
 
26
// PWM
73
        TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A));
27
//TCCR1A = (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
74
    TIMSK1 |= (1<<ICIE1)|(1<<TOIE1);
28
//TCCR1B |= (1 << WGM12);
-
 
29
//OCR1B = 55;
-
 
30
   
-
 
31
    TIMSK1 |= _BV(ICIE1);
-
 
32
    AdNeutralGier = 0;
75
 
33
    AdNeutralRoll = 0;
76
    RC_Quality = 0;
Line 34... Line -...
34
    AdNeutralNick = 0;
-
 
35
    return;
-
 
36
}
-
 
37
 
-
 
Line -... Line 77...
-
 
77
 
-
 
78
    SREG = sreg;
-
 
79
}
38
//############################################################################
80
 
-
 
81
 
-
 
82
// happens every 0.209712 s.
-
 
83
// check for at least one new frame per timer overflow (timeout)
-
 
84
ISR(TIMER1_OVF_vect)
-
 
85
{
-
 
86
        if (NewRCFrames == 0) RC_Quality -= RC_Quality/8;
-
 
87
        NewRCFrames = 0;
-
 
88
}
-
 
89
 
-
 
90
 
-
 
91
/********************************************************************/
-
 
92
/*         Every time a positive edge is detected at PD6            */
-
 
93
/********************************************************************/
-
 
94
/*                               t-Frame
-
 
95
       <----------------------------------------------------------------------->
-
 
96
         ____   ______   _____   ________                ______    sync gap      ____
-
 
97
        |    | |      | |     | |        |              |      |                |
39
//Diese Routine startet und inizialisiert den Timer für RC
98
        |    | |      | |     | |        |              |      |                |
-
 
99
     ___|    |_|      |_|     |_|        |_.............|      |________________|
-
 
100
        <-----><-------><------><-------->              <------>                <---
-
 
101
          t0       t1      t2       t4                     tn                     t0
-
 
102
 
-
 
103
The PPM-Frame length is 22.5 ms.
-
 
104
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
-
 
105
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
-
 
106
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
-
 
107
The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
-
 
108
The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
40
SIGNAL(SIG_INPUT_CAPTURE1)
109
The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
41
//############################################################################
110
the syncronization gap.
-
 
111
*/
-
 
112
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
-
 
113
{
-
 
114
    int16_t signal = 0, tmp;
42
 
115
        static int16_t index;
-
 
116
        static uint16_t oldICR1 = 0;
-
 
117
 
-
 
118
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
43
{
119
        // at the time the edge was detected
44
        static unsigned int AltICR=0;
120
 
-
 
121
        // calculate the time delay to the previous event time which is stored in oldICR1
45
    signed int signal = 0,tmp;
122
        // calculatiing the difference of the two uint16_t and converting the result to an int16_t
46
        static int index;              
123
        // implicit handles a timer overflow 65535 -> 0 the right way.
-
 
124
        signal = (uint16_t) ICR1 - oldICR1;
47
               
125
        oldICR1 = ICR1;
-
 
126
 
48
        signal = (unsigned int) ICR1 - AltICR;         
127
    //sync gap? (3.52 ms < signal < 25.6 ms)
-
 
128
        if((signal > 1100) && (signal < 8000))
49
        AltICR = ICR1; 
129
        {
-
 
130
                // if a sync gap happens and there where at least 4 channels decoded before
-
 
131
                // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
-
 
132
                if(index >= 4)
50
    //Syncronisationspause?
133
                {
51
//      if((signal > (int) Parameter_UserParam2 * 10) && (signal < 8000))        
134
                        NewPpmData = 0;  // Null means NewData for the first 4 channels
-
 
135
                        NewRCFrames++;
52
        if((signal > 1100) && (signal < 8000))   
136
                }
-
 
137
                // synchronize channel index
53
        {
138
                index = 1;
-
 
139
        }
-
 
140
        else // within the PPM frame
54
        if(index >= 4)  NewPpmData = 0;  // Null bedeutet: Neue Daten
141
    {
55
        index = 1;             
142
        if(index < 14) // PPM24 supports 12 channels
56
        }
143
        {
-
 
144
                        // check for valid signal length (0.8 ms < signal < 2.1984 ms)
57
        else
145
                        // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
58
        {
146
            if((signal > 250) && (signal < 687))
59
        if(index < 10)
147
            {
60
            {
148
                                // shift signal to zero symmetric range  -154 to 159
-
 
149
                signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
61
            if((signal > 250) && (signal < 687))
150
                // check for stable signal
62
                {
151
                if(abs(signal-PPM_in[index]) < 6)
63
                signal -= 466;
152
                {
64
                // Stabiles Signal
153
                                        if(RC_Quality < 200) RC_Quality +=10;
-
 
154
                                }
65
                if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
155
                                // calculate exponential history for signal
66
//                tmp = (7 * (PPM_in[index]) + signal) / 8;   
156
                tmp = (3 * (PPM_in[index]) + signal) / 4;
67
                tmp = (3 * (PPM_in[index]) + signal) / 4;  
157
                if(tmp > signal+1) tmp--; else
68
                if(tmp > signal+1) tmp--; else
158
                if(tmp < signal-1) tmp++;
69
                if(tmp < signal-1) tmp++;
159
                // calculate signal difference on good signal level
-
 
160
                if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
70
                if(SenderOkay >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
161
                else PPM_diff[index] = 0;
71
                else PPM_diff[index] = 0;
162
                PPM_in[index] = tmp; // update channel value
-
 
163
            }
-
 
164
            index++; // next channel
72
                PPM_in[index] = tmp;
165
            // demux sum signal for channels 5 to 7 to J3, J4, J5
-
 
166
                if(index == 5) PORTD |= (1<<PORTD5); else PORTD &= ~(1<<PORTD5);
73
                }
167
                if(index == 6) PORTD |= (1<<PORTD4); else PORTD &= ~(1<<PORTD4);
74
            index++;  
168
                if(BoardRelease == 10)
-
 
169
                {
75
         if(index == 5) PORTD |= 0x20; else PORTD &= ~0x20;  // Servosignal an J3 anlegen
170
                                if(index == 7) PORTD |= (1<<PORTD3); else PORTD &= ~(1<<PORTD3);