Subversion Repositories FlightCtrl

Rev

Rev 687 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
/*#######################################################################################
685 killagreg 2
Decodieren eines RC Summen Signals
1 ingob 3
#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Copyright (c) 04.2007 Holger Buss
6
// + only for non-profit use
7
// + www.MikroKopter.com
8
// + see the File "License.txt" for further Informations
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
 
687 killagreg 11
#include <stdlib.h>
685 killagreg 12
#include <avr/io.h>
13
#include <avr/interrupt.h>
14
 
1 ingob 15
#include "rc.h"
685 killagreg 16
#include "fc.h"
1 ingob 17
 
687 killagreg 18
volatile int16_t PPM_in[11];
688 killagreg 19
volatile int16_t PPM_diff[11];
687 killagreg 20
volatile uint8_t NewPpmData = 1;
688 killagreg 21
volatile uint8_t SenderOkay = 0;
1 ingob 22
 
687 killagreg 23
/***************************************************************/
688 killagreg 24
/*  16bit timer 1 is used to decode the PPM-Signal            */
687 killagreg 25
/***************************************************************/
1 ingob 26
void rc_sum_init (void)
27
{
688 killagreg 28
        uint8_t sreg = SREG;
1 ingob 29
 
688 killagreg 30
        // disable all interrupts before reconfiguration
31
        cli();
685 killagreg 32
 
688 killagreg 33
        // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
34
        DDRD &= ~(1<<DDD6);
35
        PORTD |= (1<<PORTD6);
36
 
37
        // Timer/Counter1 Control Register A, B, C
38
 
39
        // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
40
        // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
41
        // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
42
        // Enable input capture noise cancler (bit: ICNC1=1)
43
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
44
        // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
45
    // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
46
        TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
47
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
48
        TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
49
        TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
50
 
51
        // Timer/Counter1 Interrupt Mask Register
52
 
53
        // Enable Input Capture Interrupt (bit: ICIE1=1)
54
        // Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
55
        // Disable Overflow Interrupt (bit: TOIE1=0)
56
        TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1));
57
    TIMSK1 |= (1<<ICIE1);
58
 
1 ingob 59
    AdNeutralGier = 0;
60
    AdNeutralRoll = 0;
61
    AdNeutralNick = 0;
688 killagreg 62
 
63
    SREG = sreg;
1 ingob 64
}
65
 
66
 
688 killagreg 67
/********************************************************************/
68
/*         Every time a positive edge is detected at PD6            */
69
/********************************************************************/
70
/*
71
The PPM-Frame length is 22.5 ms.
72
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
73
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
74
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
75
The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
76
The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
77
The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
78
the syncronization gap.
79
*/
80
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
1 ingob 81
{
688 killagreg 82
        static uint16_t oldICR1 = 0;
83
    int16_t signal = 0, tmp;
84
        static int16_t index;
685 killagreg 85
 
688 killagreg 86
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
87
        // at the time the edge was detected
685 killagreg 88
 
688 killagreg 89
        // calculate the time delay to the previous event time which is stored in oldICR1
90
        signal = (uint16_t) ICR1 - oldICR1;
91
        oldICR1 = ICR1;
92
 
93
 
94
    //sync gap? (3.52 ms < signal < 25.6 ms)
685 killagreg 95
        if((signal > 1100) && (signal < 8000))
688 killagreg 96
        {
97
                // if a sync gap happens and there where at least 4 channels decoded before
98
                // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
99
                if(index >= 4)  NewPpmData = 0;  // Null means NewData
100
                // synchronize channel index
101
                index = 1;
102
        }
103
        else // within the PPM frame
1 ingob 104
        {
688 killagreg 105
        if(index < 10) // channel limit is 9 because of the frame length of 22.5 ms
1 ingob 106
        {
688 killagreg 107
                        // check for valid signal length (0.8 ms < signal < 2.1984 ms)
108
            if((signal > 250) && (signal < 687))
1 ingob 109
            {
688 killagreg 110
                signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
111
                // check for stable signal
112
                // the deviation of the current signal level from the average must be less than 6 (aprox. 1%)
113
                if(abs(signal - PPM_in[index]) < 6)
685 killagreg 114
                {
688 killagreg 115
                                        // a good signal condition increases SenderOkay by 10
116
                                        // SignalOkay is decremented every 2 ms in timer0.c
117
                                        // this variable is a level for the average rate of noiseless signal
118
                                        if(SenderOkay < 200) SenderOkay += 10;
119
                                }
120
                                // calculate exponential history for signal
685 killagreg 121
                tmp = (3 * (PPM_in[index]) + signal) / 4;
604 hbuss 122
                if(tmp > signal+1) tmp--; else
685 killagreg 123
                if(tmp < signal-1) tmp++;
688 killagreg 124
                // calculate signal difference on good signal level
125
                if(SenderOkay >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
604 hbuss 126
                else PPM_diff[index] = 0;
688 killagreg 127
                PPM_in[index] = tmp; // update channel value
128
            }
129
            index++; // next channel
130
            // demux sum signal fpr channels 5 to 7
131
                if(index == 5) PORTD |= 0x20; else PORTD &= ~0x20;  // Servosignal an J3 anlegen
132
                if(index == 6) PORTD |= 0x10; else PORTD &= ~0x10;  // Servosignal an J4 anlegen
133
                if(index == 7) PORTD |= 0x08; else PORTD &= ~0x08;  // Servosignal an J5 anlegen
1 ingob 134
        }
135
        }
136
}
137
 
138
 
139
 
140
 
141