Subversion Repositories FlightCtrl

Rev

Rev 1544 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1544 Rev 1545
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) Holger Buss, Ingo Busker
2
// + Copyright (c) Holger Buss, Ingo Busker
3
// + Nur für den privaten Gebrauch
3
// + Nur für den privaten Gebrauch
4
// + www.MikroKopter.com
4
// + www.MikroKopter.com
5
// + porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
5
// + porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
7
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
8
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
8
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
9
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
9
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
10
// + bzgl. der Nutzungsbedingungen aufzunehmen.
10
// + bzgl. der Nutzungsbedingungen aufzunehmen.
11
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
11
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
12
// + Verkauf von Luftbildaufnahmen, usw.
12
// + Verkauf von Luftbildaufnahmen, usw.
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
14
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
15
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
15
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
17
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
18
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
18
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
19
// + eindeutig als Ursprung verlinkt werden
19
// + eindeutig als Ursprung verlinkt werden
20
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
21
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
22
// + Benutzung auf eigene Gefahr
22
// + Benutzung auf eigene Gefahr
23
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
23
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
24
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
25
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
26
// + mit unserer Zustimmung zulässig
26
// + mit unserer Zustimmung zulässig
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
28
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
29
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
30
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
31
// + this list of conditions and the following disclaimer.
31
// + this list of conditions and the following disclaimer.
32
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
32
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
33
// +     from this software without specific prior written permission.
33
// +     from this software without specific prior written permission.
34
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
34
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
35
// +     for non-commercial use (directly or indirectly)
35
// +     for non-commercial use (directly or indirectly)
36
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
36
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
37
// +     with our written permission
37
// +     with our written permission
38
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
38
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
39
// +     clearly linked as origin
39
// +     clearly linked as origin
40
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
40
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
41
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
42
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
45
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
46
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
47
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
48
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50
// +  POSSIBILITY OF SUCH DAMAGE.
50
// +  POSSIBILITY OF SUCH DAMAGE.
51
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
52
#include <stdlib.h>
52
#include <stdlib.h>
53
#include <avr/interrupt.h>
53
#include <avr/interrupt.h>
54
 
54
 
55
#include "rc.h"
55
#include "rc.h"
56
#include "eeprom.h"
56
#include "eeprom.h"
57
#include "main.h"
57
#include "main.h"
58
#include "fc.h"
58
#include "fc.h"
59
#include "uart0.h"
59
#include "uart0.h"
60
 
60
 
61
 
61
 
62
//#define ACT_S3D_SUMSIGNAL
62
//#define ACT_S3D_SUMSIGNAL
63
 
63
 
64
volatile uint8_t RC_Channels;   // number of received channels
64
volatile uint8_t RC_Channels;   // number of received channels
65
volatile int16_t PPM_in[MAX_CHANNELS]; //PPM24 supports 12 channels per frame
65
volatile int16_t PPM_in[MAX_CHANNELS]; //PPM24 supports 12 channels per frame
66
volatile int16_t PPM_diff[MAX_CHANNELS];
66
volatile int16_t PPM_diff[MAX_CHANNELS];
67
volatile uint8_t NewPpmData = 1;
67
volatile uint8_t NewPpmData = 1;
68
volatile uint8_t RC_Quality = 0;
68
volatile uint8_t RC_Quality = 0;
69
volatile uint8_t RC_RSSI = 0; // Received Signal Strength Indication
69
volatile uint8_t RC_RSSI = 0; // Received Signal Strength Indication
70
 
70
 
71
 
71
 
72
 
72
 
73
/***************************************************************/
73
/***************************************************************/
74
/*  16bit timer 1 is used to decode the PPM-Signal            */
74
/*  16bit timer 1 is used to decode the PPM-Signal            */
75
/***************************************************************/
75
/***************************************************************/
76
void RC_Init (void)
76
void RC_Init (void)
77
{
77
{
78
        uint8_t sreg = SREG;
78
        uint8_t sreg = SREG;
79
 
79
 
80
        // disable all interrupts before reconfiguration
80
        // disable all interrupts before reconfiguration
81
        cli();
81
        cli();
-
 
82
 
82
 
83
        #ifndef USE_RC_JENNIC // LPD: FC_JN_Receiver support added
83
        // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
84
                // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
84
        DDRD &= ~(1<<DDD6);
85
                DDRD &= ~(1<<DDD6);
-
 
86
                PORTD |= (1<<PORTD6);
85
        PORTD |= (1<<PORTD6);
87
        #endif
86
 
88
 
87
        // Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
89
        // Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
88
        // set as output
90
        // set as output
89
        DDRD |= (1<<DDD5)|(1<<DDD4);
91
        DDRD |= (1<<DDD5)|(1<<DDD4);
90
        // low level
92
        // low level
91
        PORTD &= ~((1<<PORTD5)|(1<<PORTD4));
93
        PORTD &= ~((1<<PORTD5)|(1<<PORTD4));
92
 
94
 
93
        // PD3 can't be used if 2nd UART is activated
95
        // PD3 can't be used if 2nd UART is activated
94
        // because TXD1 is at that port
96
        // because TXD1 is at that port
95
        if(CPUType != ATMEGA644P)
97
        if(CPUType != ATMEGA644P)
96
        {
98
        {
97
                DDRD |= (1<<PORTD3);
99
                DDRD |= (1<<PORTD3);
98
                PORTD &= ~(1<<PORTD3);
100
                PORTD &= ~(1<<PORTD3);
99
        }
101
        }
100
 
102
 
101
        // Timer/Counter1 Control Register A, B, C
103
        // Timer/Counter1 Control Register A, B, C
102
 
104
 
103
        // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
105
        // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
104
        // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
106
        // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
105
        TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
107
        TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
106
#ifndef ACT_S3D_SUMSIGNAL
108
#ifndef ACT_S3D_SUMSIGNAL
107
        // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
109
        // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
108
        // Enable input capture noise cancler (bit: ICNC1=1)
110
        // Enable input capture noise cancler (bit: ICNC1=1)
109
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
111
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
110
        // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
112
        // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
111
        // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
113
        // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
112
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
114
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
113
        TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
115
        TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
114
#else
116
#else
115
        // Set clock source to SYSCLK/8 (bit: CS12=0, CS11=1, CS10=0)
117
        // Set clock source to SYSCLK/8 (bit: CS12=0, CS11=1, CS10=0)
116
        // Enable input capture noise cancler (bit: ICNC1=1)
118
        // Enable input capture noise cancler (bit: ICNC1=1)
117
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
119
        // Trigger on positive edge of the input capture pin (bit: ICES1=1),
118
        // Therefore the counter incremets at a clock of 20 MHz/8 = 2.5 MHz or 0.4µs
120
        // Therefore the counter incremets at a clock of 20 MHz/8 = 2.5 MHz or 0.4µs
119
    // The longest period is 0xFFFF / 2.5 MHz = 0.026214 s.
121
    // The longest period is 0xFFFF / 2.5 MHz = 0.026214 s.
120
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10));
122
        TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10));
121
        TCCR1B |= (1<<CS11)|(1<<ICES1)|(1<<ICNC1);
123
        TCCR1B |= (1<<CS11)|(1<<ICES1)|(1<<ICNC1);
122
#endif
124
#endif
123
        TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
125
        TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
124
 
126
 
125
        // Timer/Counter1 Interrupt Mask Register
127
        // Timer/Counter1 Interrupt Mask Register
126
 
128
 
127
        // Enable Input Capture Interrupt (bit: ICIE1=1)
129
        // Enable Input Capture Interrupt (bit: ICIE1=1)
128
        // Disable Output Compare A & B Match Interrupts and Overflow Interrupt (bit: OCIE1B=0, OICIE1A=0, TOIE1=0)
130
        // Disable Output Compare A & B Match Interrupts and Overflow Interrupt (bit: OCIE1B=0, OICIE1A=0, TOIE1=0)
129
        TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1));
131
        TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1));
130
 
132
 
131
    PPM_INPUT_ON; //enabled by default
133
    PPM_INPUT_ON; //enabled by default
132
 
134
 
133
    SREG = sreg;
135
    SREG = sreg;
134
}
136
}
135
 
137
 
136
 
138
 
137
/********************************************************************/
139
/********************************************************************/
138
/*         Every time a positive edge is detected at PD6            */
140
/*         Every time a positive edge is detected at PD6            */
139
/********************************************************************/
141
/********************************************************************/
140
/*                               t-Frame
142
/*                               t-Frame
141
       <----------------------------------------------------------------------->
143
       <----------------------------------------------------------------------->
142
         ____   ______   _____   ________                ___   ________________   ____
144
         ____   ______   _____   ________                ___   ________________   ____
143
        |    | |      | |     | |        |              |   | |                | |
145
        |    | |      | |     | |        |              |   | |                | |
144
        |    | |      | |     | |        |              |   | |    sync gap    | |
146
        |    | |      | |     | |        |              |   | |    sync gap    | |
145
     ___|    |_|      |_|     |_|        |_............_|   |_|                |_|
147
     ___|    |_|      |_|     |_|        |_............_|   |_|                |_|
146
        <-----><-------><------><-------->              <----->                   <---
148
        <-----><-------><------><-------->              <----->                   <---
147
          t0       t1      t2       t4                     tn                       t0
149
          t0       t1      t2       t4                     tn                       t0
148
 
150
 
149
The PPM-Frame length is 22.5 ms.
151
The PPM-Frame length is 22.5 ms.
150
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
152
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
151
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
153
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
152
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
154
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
153
The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
155
The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
154
The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
156
The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
155
The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
157
The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
156
the syncronization gap.
158
the syncronization gap.
157
*/
159
*/
-
 
160
 
158
 
161
#ifndef USE_RC_JENNIC // LPD: FC_JN_Receiver support added   
159
#ifndef ACT_S3D_SUMSIGNAL
162
#ifndef ACT_S3D_SUMSIGNAL
160
 
163
 
161
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
164
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
162
{
165
{
163
    int16_t signal = 0, tmp;
166
    int16_t signal = 0, tmp;
164
    uint8_t i;
167
    uint8_t i;
165
        static uint8_t index = 1;
168
        static uint8_t index = 1;
166
        static uint16_t oldICR1 = 0;
169
        static uint16_t oldICR1 = 0;
167
 
170
 
168
 
171
 
169
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
172
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
170
        // at the time the edge was detected
173
        // at the time the edge was detected
171
 
174
 
172
        // calculate the time delay to the previous event time which is stored in oldICR1
175
        // calculate the time delay to the previous event time which is stored in oldICR1
173
        // calculatiing the difference of the two uint16_t and converting the result to an int16_t
176
        // calculatiing the difference of the two uint16_t and converting the result to an int16_t
174
        // implicit handles a timer overflow 65535 -> 0 the right way.
177
        // implicit handles a timer overflow 65535 -> 0 the right way.
175
        signal = (uint16_t) ICR1 - oldICR1;
178
        signal = (uint16_t) ICR1 - oldICR1;
176
        oldICR1 = ICR1;
179
        oldICR1 = ICR1;
177
 
180
 
178
        if(ParamSet.Config2 & CFG2_SENSITIVE_RC)
181
        if(ParamSet.Config2 & CFG2_SENSITIVE_RC)
179
        {
182
        {
180
                static int16_t old_ppm_in[MAX_CHANNELS];
183
                static int16_t old_ppm_in[MAX_CHANNELS];
181
                static int16_t ppm_in[MAX_CHANNELS];
184
                static int16_t ppm_in[MAX_CHANNELS];
182
                static int16_t ppm_diff[MAX_CHANNELS];
185
                static int16_t ppm_diff[MAX_CHANNELS];
183
                static uint8_t okay_cnt = 0;
186
                static uint8_t okay_cnt = 0;
184
 
187
 
185
                //sync gap? (3.52 ms < signal < 25.6 ms)
188
                //sync gap? (3.52 ms < signal < 25.6 ms)
186
                if((signal > 1100) && (signal < 8000))
189
                if((signal > 1100) && (signal < 8000))
187
                {
190
                {
188
                        // if a sync gap happens and there where at least 4 channels decoded
191
                        // if a sync gap happens and there where at least 4 channels decoded
189
                        // and the number of channes decoded since the last sync gap matches the expectation
192
                        // and the number of channes decoded since the last sync gap matches the expectation
190
                        // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
193
                        // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
191
                        index--; // no next channel because the sync gap was detected
194
                        index--; // no next channel because the sync gap was detected
192
                        if(index >= 4 && index == RC_Channels)
195
                        if(index >= 4 && index == RC_Channels)
193
                        {
196
                        {
194
                                if(okay_cnt > 10) // at least 10 frames in line ok
197
                                if(okay_cnt > 10) // at least 10 frames in line ok
195
                                {
198
                                {
196
 
199
 
197
                                        for(i=0; i < MAX_CHANNELS; i++)
200
                                        for(i=0; i < MAX_CHANNELS; i++)
198
                                        {
201
                                        {
199
                                                if(okay_cnt > 30) // at least 30 frames ok
202
                                                if(okay_cnt > 30) // at least 30 frames ok
200
                                                {
203
                                                {
201
                                                        old_ppm_in[i] = PPM_in[i]; // backup data
204
                                                        old_ppm_in[i] = PPM_in[i]; // backup data
202
                                                }
205
                                                }
203
                                                PPM_in[i] = ppm_in[i];
206
                                                PPM_in[i] = ppm_in[i];
204
                                                PPM_diff[i] = ppm_diff[i];
207
                                                PPM_diff[i] = ppm_diff[i];
205
                                        }
208
                                        }
206
                                        NewPpmData = 0;  // Null means NewData for at least the first 4 channels
209
                                        NewPpmData = 0;  // Null means NewData for at least the first 4 channels
207
                                }
210
                                }
208
                                if(okay_cnt < 255) okay_cnt++;
211
                                if(okay_cnt < 255) okay_cnt++;
209
                        } // eof if(index >= 4 && index == RC_Channels)
212
                        } // eof if(index >= 4 && index == RC_Channels)
210
                        else
213
                        else
211
                        {
214
                        {
212
                                if(okay_cnt > 100) okay_cnt = 10;
215
                                if(okay_cnt > 100) okay_cnt = 10;
213
                                else okay_cnt = 0;
216
                                else okay_cnt = 0;
214
                                RED_ON;
217
                                RED_ON;
215
                        }
218
                        }
216
                        // store max channels transmitted
219
                        // store max channels transmitted
217
                        if(!(MKFlags & MKFLAG_MOTOR_RUN)) RC_Channels = index;
220
                        if(!(MKFlags & MKFLAG_MOTOR_RUN)) RC_Channels = index;
218
                        // reset channel index
221
                        // reset channel index
219
                        index = 1;
222
                        index = 1;
220
                }
223
                }
221
                else // assuming within the PPM frame
224
                else // assuming within the PPM frame
222
                {
225
                {
223
                        if(index < MAX_CHANNELS)
226
                        if(index < MAX_CHANNELS)
224
                        {
227
                        {
225
                                // check for valid signal length (0.8 ms < signal < 2.1984 ms)
228
                                // check for valid signal length (0.8 ms < signal < 2.1984 ms)
226
                                // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
229
                                // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
227
                                if((signal > 250) && (signal < 687))
230
                                if((signal > 250) && (signal < 687))
228
                                {
231
                                {
229
                                        // shift signal to zero symmetric range  -154 to 159
232
                                        // shift signal to zero symmetric range  -154 to 159
230
                                        signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
233
                                        signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
231
                                        // check for stable signal
234
                                        // check for stable signal
232
                                        if(abs(signal - ppm_in[index]) < 6)
235
                                        if(abs(signal - ppm_in[index]) < 6)
233
                                        {
236
                                        {
234
                                                if(okay_cnt > 25) RC_Quality +=10;
237
                                                if(okay_cnt > 25) RC_Quality +=10;
235
                                                else if(okay_cnt > 10) RC_Quality += 2;
238
                                                else if(okay_cnt > 10) RC_Quality += 2;
236
                                                if(RC_Quality > 200) RC_Quality = 200;
239
                                                if(RC_Quality > 200) RC_Quality = 200;
237
                                        }
240
                                        }
238
                                        // calculate exponential history for signal
241
                                        // calculate exponential history for signal
239
                                        tmp = (3 * (ppm_in[index]) + signal) / 4;
242
                                        tmp = (3 * (ppm_in[index]) + signal) / 4;
240
                                        if(tmp > signal+1) tmp--; else
243
                                        if(tmp > signal+1) tmp--; else
241
                                        if(tmp < signal-1) tmp++;
244
                                        if(tmp < signal-1) tmp++;
242
                                        // calculate signal difference on good signal level
245
                                        // calculate signal difference on good signal level
243
                                        if(RC_Quality >= 190)  ppm_diff[index] = ((tmp - ppm_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
246
                                        if(RC_Quality >= 190)  ppm_diff[index] = ((tmp - ppm_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
244
                                        else ppm_diff[index] = 0;
247
                                        else ppm_diff[index] = 0;
245
                                        ppm_in[index] = tmp; // update channel value
248
                                        ppm_in[index] = tmp; // update channel value
246
                                }
249
                                }
247
                                else // invalid signal lenght
250
                                else // invalid signal lenght
248
                                {
251
                                {
249
                                        RED_ON;
252
                                        RED_ON;
250
                                }
253
                                }
251
                                // demux sum signal for channels 5 to 7 to J3, J4, J5
254
                                // demux sum signal for channels 5 to 7 to J3, J4, J5
252
                                if(index == 5) J3HIGH; else J3LOW;
255
                                if(index == 5) J3HIGH; else J3LOW;
253
                                if(index == 6) J4HIGH; else J4LOW;
256
                                if(index == 6) J4HIGH; else J4LOW;
254
                                if(CPUType != ATMEGA644P) // not used as TXD1
257
                                if(CPUType != ATMEGA644P) // not used as TXD1
255
                                {
258
                                {
256
                                        if(index == 7) J5HIGH; else J5LOW;
259
                                        if(index == 7) J5HIGH; else J5LOW;
257
                                }
260
                                }
258
                                index++; // next channel
261
                                index++; // next channel
259
                        }
262
                        }
260
                        else // (index >= MAX_CHANNELS)
263
                        else // (index >= MAX_CHANNELS)
261
                        {
264
                        {
262
                                RED_ON;
265
                                RED_ON;
263
                                if(index == MAX_CHANNELS)
266
                                if(index == MAX_CHANNELS)
264
                                {
267
                                {
265
                                        for(i = 0; i < MAX_CHANNELS; i++)
268
                                        for(i = 0; i < MAX_CHANNELS; i++)
266
                                        {
269
                                        {
267
                                                PPM_in[i] = old_ppm_in[i]; // restore old valid values
270
                                                PPM_in[i] = old_ppm_in[i]; // restore old valid values
268
                                                PPM_diff[i] = 0;
271
                                                PPM_diff[i] = 0;
269
                                        }
272
                                        }
270
                                        index++;
273
                                        index++;
271
                                }
274
                                }
272
                        } // eof (index >= MAX_CHANNELS)
275
                        } // eof (index >= MAX_CHANNELS)
273
                } // eof within the PPM frame
276
                } // eof within the PPM frame
274
        } // eof sensitive rc
277
        } // eof sensitive rc
275
        else // old more tolerant version
278
        else // old more tolerant version
276
        {
279
        {
277
                //sync gap? (3.52 ms < signal < 25.6 ms)
280
                //sync gap? (3.52 ms < signal < 25.6 ms)
278
                if((signal > 1100) && (signal < 8000))
281
                if((signal > 1100) && (signal < 8000))
279
                {
282
                {
280
                        // if a sync gap happens and there where at least 4 channels decoded before
283
                        // if a sync gap happens and there where at least 4 channels decoded before
281
                        // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
284
                        // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
282
                        index--; // no next channel because the sync gap was detected
285
                        index--; // no next channel because the sync gap was detected
283
                        RC_Channels = index;
286
                        RC_Channels = index;
284
                        if(index >= 4)
287
                        if(index >= 4)
285
                        {
288
                        {
286
                                NewPpmData = 0;  // Null means NewData for the first 4 channels
289
                                NewPpmData = 0;  // Null means NewData for the first 4 channels
287
                        }
290
                        }
288
                        // synchronize channel index
291
                        // synchronize channel index
289
                        index = 1;
292
                        index = 1;
290
                }
293
                }
291
                else // within the PPM frame
294
                else // within the PPM frame
292
                {
295
                {
293
                        if(index < MAX_CHANNELS)
296
                        if(index < MAX_CHANNELS)
294
                        {
297
                        {
295
                                // check for valid signal length (0.8 ms < signal < 2.1984 ms)
298
                                // check for valid signal length (0.8 ms < signal < 2.1984 ms)
296
                                // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
299
                                // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
297
                                if((signal > 250) && (signal < 687))
300
                                if((signal > 250) && (signal < 687))
298
                                {
301
                                {
299
                                        // shift signal to zero symmetric range  -154 to 159
302
                                        // shift signal to zero symmetric range  -154 to 159
300
                                        signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
303
                                        signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
301
                                        // check for stable signal
304
                                        // check for stable signal
302
                                        if(abs(signal - PPM_in[index]) < 6)
305
                                        if(abs(signal - PPM_in[index]) < 6)
303
                                        {
306
                                        {
304
                                                if(RC_Quality < 200) RC_Quality +=10;
307
                                                if(RC_Quality < 200) RC_Quality +=10;
305
                                                else RC_Quality = 200;
308
                                                else RC_Quality = 200;
306
                                        }
309
                                        }
307
                                        // calculate exponential history for signal
310
                                        // calculate exponential history for signal
308
                                        tmp = (3 * (PPM_in[index]) + signal) / 4;
311
                                        tmp = (3 * (PPM_in[index]) + signal) / 4;
309
                                        if(tmp > signal+1) tmp--; else
312
                                        if(tmp > signal+1) tmp--; else
310
                                        if(tmp < signal-1) tmp++;
313
                                        if(tmp < signal-1) tmp++;
311
                                        // calculate signal difference on good signal level
314
                                        // calculate signal difference on good signal level
312
                                        if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
315
                                        if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
313
                                        else PPM_diff[index] = 0;
316
                                        else PPM_diff[index] = 0;
314
                                        PPM_in[index] = tmp; // update channel value
317
                                        PPM_in[index] = tmp; // update channel value
315
                                }
318
                                }
316
                                index++; // next channel
319
                                index++; // next channel
317
                                // demux sum signal for channels 5 to 7 to J3, J4, J5
320
                                // demux sum signal for channels 5 to 7 to J3, J4, J5
318
                                if(index == 5) J3HIGH; else J3LOW;
321
                                if(index == 5) J3HIGH; else J3LOW;
319
                                if(index == 6) J4HIGH; else J4LOW;
322
                                if(index == 6) J4HIGH; else J4LOW;
320
                                if(CPUType != ATMEGA644P) // not used as TXD1
323
                                if(CPUType != ATMEGA644P) // not used as TXD1
321
                                {
324
                                {
322
                                        if(index == 7) J5HIGH; else J5LOW;
325
                                        if(index == 7) J5HIGH; else J5LOW;
323
                                }
326
                                }
324
                        } // eof (index < MAX_CHANNELS)
327
                        } // eof (index < MAX_CHANNELS)
325
                } // eof within the PPM frame
328
                } // eof within the PPM frame
326
        } // eof old more tolerant version
329
        } // eof old more tolerant version
327
}
330
}
328
 
331
 
329
#else // ACT_S3D_SUMSIGNAL
332
#else // ACT_S3D_SUMSIGNAL
330
 
333
 
331
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
334
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
332
{
335
{
333
        int16_t signal = 0, tmp;
336
        int16_t signal = 0, tmp;
334
        uint8_t i;
337
        uint8_t i;
335
        static uint8_t index = 1;
338
        static uint8_t index = 1;
336
        static uint16_t oldICR1 = 0;
339
        static uint16_t oldICR1 = 0;
337
 
340
 
338
 
341
 
339
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
342
        // 16bit Input Capture Register ICR1 contains the timer value TCNT1
340
        // at the time the edge was detected
343
        // at the time the edge was detected
341
 
344
 
342
        // calculate the time delay to the previous event time which is stored in oldICR1
345
        // calculate the time delay to the previous event time which is stored in oldICR1
343
        // calculatiing the difference of the two uint16_t and converting the result to an int16_t
346
        // calculatiing the difference of the two uint16_t and converting the result to an int16_t
344
        // implicit handles a timer overflow 65535 -> 0 the right way.
347
        // implicit handles a timer overflow 65535 -> 0 the right way.
345
        signal = (uint16_t) ICR1 - oldICR1;
348
        signal = (uint16_t) ICR1 - oldICR1;
346
        signal /= 2;
349
        signal /= 2;
347
        oldICR1 = ICR1;
350
        oldICR1 = ICR1;
348
        //sync gap? (3.52 ms < signal < 25.6 ms)
351
        //sync gap? (3.52 ms < signal < 25.6 ms)
349
        if((signal > 1100*2) && (signal < 8000*2))
352
        if((signal > 1100*2) && (signal < 8000*2))
350
        {
353
        {
351
                // if a sync gap happens and there where at least 4 channels decoded before
354
                // if a sync gap happens and there where at least 4 channels decoded before
352
                // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
355
                // then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
353
                index--; // no next channel because the sync gap was detected
356
                index--; // no next channel because the sync gap was detected
354
                RC_Channels = index;
357
                RC_Channels = index;
355
                if(index >= 4)
358
                if(index >= 4)
356
                {
359
                {
357
                        NewPpmData = 0;  // Null means NewData for the first 4 channels
360
                        NewPpmData = 0;  // Null means NewData for the first 4 channels
358
                }
361
                }
359
                // synchronize channel index
362
                // synchronize channel index
360
                index = 1;
363
                index = 1;
361
        }
364
        }
362
        else // within the PPM frame
365
        else // within the PPM frame
363
        {
366
        {
364
                if(index < MAX_CHANNELS)
367
                if(index < MAX_CHANNELS)
365
                {
368
                {
366
                        // check for valid signal length (0.8 ms < signal < 2.1984 ms)
369
                        // check for valid signal length (0.8 ms < signal < 2.1984 ms)
367
                        // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
370
                        // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
368
                        if((signal > 250) && (signal < 687*2))
371
                        if((signal > 250) && (signal < 687*2))
369
                        {
372
                        {
370
                                // shift signal to zero symmetric range  -154 to 159
373
                                // shift signal to zero symmetric range  -154 to 159
371
                                signal -= 962; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
374
                                signal -= 962; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
372
                                // check for stable signal
375
                                // check for stable signal
373
                                if(abs(signal - PPM_in[index]) < 6)
376
                                if(abs(signal - PPM_in[index]) < 6)
374
                                {
377
                                {
375
                                        if(RC_Quality < 200) RC_Quality +=10;
378
                                        if(RC_Quality < 200) RC_Quality +=10;
376
                                        else RC_Quality = 200;
379
                                        else RC_Quality = 200;
377
                                }
380
                                }
378
                                // calculate exponential history for signal
381
                                // calculate exponential history for signal
379
                                tmp = (3 * (PPM_in[index]) + signal) / 4;
382
                                tmp = (3 * (PPM_in[index]) + signal) / 4;
380
                                if(tmp > signal+1) tmp--; else
383
                                if(tmp > signal+1) tmp--; else
381
                                if(tmp < signal-1) tmp++;
384
                                if(tmp < signal-1) tmp++;
382
                                // calculate signal difference on good signal level
385
                                // calculate signal difference on good signal level
383
                                if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
386
                                if(RC_Quality >= 195)  PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
384
                                else PPM_diff[index] = 0;
387
                                else PPM_diff[index] = 0;
385
                                PPM_in[index] = tmp; // update channel value
388
                                PPM_in[index] = tmp; // update channel value
386
                        }
389
                        }
387
                        index++; // next channel
390
                        index++; // next channel
388
                } // eof (index < MAX_CHANNELS)
391
                } // eof (index < MAX_CHANNELS)
389
        } // eof within the PPM frame
392
        } // eof within the PPM frame
390
}
393
}
391
#endif
394
#endif
392
 
395
#endif
393
 
396
 
394
 
397
 
395
 
398
 
396
 
399