Subversion Repositories FlightCtrl

Rev

Rev 2248 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2248 - 1
/**************************************************************************************************************************************
2
* File:                 main.c
3
*
4
* Purpose:              main function fot Flight Ctrl
5
*
6
* Functions:    void CalMk3Mag(void)
7
*                               void LipoDetection(unsigned char print)
8
*                               int main(void)
9
*
10
* hardware:             Flight Ctrl V1.3
11
*
12
* Created:              Feb 2013
13
*
14
* Revisions:    1.00    experimental subversion for a balancekopter
15
*                               Achtung: nicht flugfähige Experimentalversion für eine Balenwaage mit Flight-CTRL
16
*                               siehe: http://forum.mikrokopter.de/topic-39231.html
17
*
18
* Copyright:    (c)2013 www.mikrokopter.de
19
*                               All rights reserved. This software is available only for non-commercial or educational applications.  
20
*                               Other uses are prohibited. This software may be modified only if
21
*                               the resulting code be made available publicly and the original author(s) given credit.
22
*
23
************************************************************************************************************************************/
24
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25
// + Copyright (c) Holger Buss, Ingo Busker
26
// + Nur für den privaten Gebrauch / NON-COMMERCIAL USE ONLY
27
// + www.MikroKopter.com
28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
30
// + dass eine Nutzung (auch auszugsweise) nur für den privaten und nicht-kommerziellen Gebrauch zulässig ist.
31
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
32
// + bzgl. der Nutzungsbedingungen aufzunehmen.
33
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
34
// + Verkauf von Luftbildaufnahmen, usw.
35
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
36
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
37
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
38
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
40
// + auf anderen Webseiten oder Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
41
// + eindeutig als Ursprung verlinkt und genannt werden
42
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
44
// + Benutzung auf eigene Gefahr
45
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
46
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47
// + Die Portierung oder Nutzung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
48
// + mit unserer Zustimmung zulässig
49
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
51
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
52
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
53
// + this list of conditions and the following disclaimer.
54
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
55
// +     from this software without specific prior written permission.
56
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
57
// +     for non-commercial use (directly or indirectly)
58
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
59
// +     with our written permission
60
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
61
// +     clearly linked as origin
62
// +   * porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
63
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
64
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
67
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
68
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
69
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
70
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
71
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
72
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
73
// +  POSSIBILITY OF SUCH DAMAGE.
74
// *****************************************************************************************************************************************
75
#include "main.h"
76
 
77
 
78
unsigned char PlatinenVersion = 13;
79
unsigned char SendVersionToNavi = 1;
80
unsigned char BattLowVoltageWarning = 94;
81
unsigned int  FlugMinuten = 0,FlugMinutenGesamt = 0;
82
 
83
 
84
 
85
//-----------------------------------------------------------------------------------------------------
86
// calibrate magnetic compass
87
//-----------------------------------------------------------------------------------------------------
88
void CalMk3Mag(void)
89
{
90
        static unsigned char stick = 1;
91
 
92
        if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -20) stick = 0;
93
 
94
        if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -70) && !stick)
95
        {
96
                stick = 1;
97
                WinkelOut.CalcState++;
98
 
99
                if(WinkelOut.CalcState > 4)
100
                {
101
                        beeptime = 1000;
102
                }
103
                else Piep(WinkelOut.CalcState,150);
104
        }
105
        DebugOut.Analog[19] = WinkelOut.CalcState;
106
}
107
//-----------------------------------------------------------------------------------------------------
108
 
109
 
110
 
111
//-----------------------------------------------------------------------------------------------------
112
// recognize the LiPo accumulators
113
// char print can be 0 or 1
114
//-----------------------------------------------------------------------------------------------------
115
void LipoDetection(unsigned char print)
116
{
117
        unsigned int timer;
118
 
119
        if(print) printf("\n\rBatt:");
120
 
121
        if(EE_Parameter.UnterspannungsWarnung < 50)                     // automatic recognition of lipo cells -> default = 33
122
        {
123
                timer = SetDelay(500);                                                          // 
124
                if(print) while (!CheckDelay(timer));
125
 
126
                if(UBat < 130)
127
                {
128
                        BattLowVoltageWarning = 3 * EE_Parameter.UnterspannungsWarnung;
129
                        if(print)
130
                        {
131
                                Piep(3,200);
132
                                printf(" 3 Cells  ");
133
                        }
134
                }
135
                else
136
                {
137
                        BattLowVoltageWarning = 4 * EE_Parameter.UnterspannungsWarnung;
138
                        if(print)
139
                        {
140
                                Piep(4,200);
141
                                printf(" 4 Cells  ");
142
                        }
143
                }
144
        }
145
        else BattLowVoltageWarning = EE_Parameter.UnterspannungsWarnung;
146
 
147
        if(print) printf(" Low warning level: %d.%d",BattLowVoltageWarning/10,BattLowVoltageWarning%10);
148
}
149
//-----------------------------------------------------------------------------------------------------
150
 
151
 
152
 
153
// --------------------------------------------------------------------------------------------------------------------------
154
// main program starting here 
155
//
156
// INPUT:       None
157
// OUTPUT:      None
158
// RETURN:      1
159
// --------------------------------------------------------------------------------------------------------------------------
160
int main(void)
161
{
162
        unsigned int timer,i,timer2 = 0;
163
        DDRB  = 0x00;
164
        PORTB = 0x00;
165
        for(timer = 0; timer < 1000; timer++);  // verzögern
166
 
167
        PlatinenVersion = 13;
168
 
169
        DDRC  = 0x81;                                   // SCL
170
        PORTC = 0xFF;                                   // Pullup SDA
171
        DDRB  = 0x1B;                                   // LEDs und Druckoffset
172
        PORTB = 0x01;                                   // LED_Rot
173
        DDRD  = 0x3E;                                   // Speaker & TXD & J3 J4 J5
174
        PORTD = 0x47;                                   // LED
175
        HEF4017R_OFF;                                   // #define HEF4017R_OFF    PORTC &= ~(1<<PORTC6)
176
 
177
        MCUSR &=~(1<<WDRF);                     // MCUSR – MCU Status Register provides information on which reset source caused an MCU reset
178
        WDTCSR |= (1<<WDCE)|(1<<WDE);   // WDTCSR – Watchdog Timer Control Register
179
        WDTCSR = 0;                            
180
 
181
        beeptime = 2000;
182
        StickGier = 0; PPM_in[K_GAS] = 0; StickRoll = 0; StickNick = 0;
183
 
184
        GIER_GRAD_FAKTOR = 1291;
185
 
186
        ROT_OFF;                                                                        // rote LED aus // PORTB |= 0x01;
187
 
188
        Timer_Init();           // goto timer0.c Zeile 40
189
        TIMER2_Init();          // goto timer0.c Zeile 170
190
        UART_Init();            // goto uart.c Zeile 488
191
        rc_sum_init();          // goto rc.c line 17
192
        ADC_Init();                     // goto analog.c Zeile 26
193
        i2c_init();                     // goto twimaster.c Zeile 16
194
 
195
 
196
        //---------------------------------------------------------------------------------------------------------------------------------
197
        // passes one time through the following code before arriving at the forever loop
198
        //---------------------------------------------------------------------------------------------------------------------------------
199
 
200
        sei();
201
 
202
        printf("\n\r===================================");
203
        printf("\n\rFlightControl\n\rHardware:%d.%d\n\rSoftware:V%d.%d%c ",PlatinenVersion/10,PlatinenVersion%10, VERSION_MAJOR, VERSION_MINOR,VERSION_PATCH + 'a');
204
        printf("\n\rexperimental version");
205
        printf("\n\r===================================");
206
 
207
 
208
        GRN_ON;                                                                                                                                                         // switch green LED on  // PORTB &=~0x02;
209
 
210
        ReadParameterSet(3, (unsigned char *) &EE_Parameter.Kanalbelegung[0], 9);                       // read first 9 Bytes = chanal setup of radio control
211
 
212
 
213
        // ---------------------------------------------------------------------------------------------------------------------------
214
        // setup of mixer
215
        // ---------------------------------------------------------------------------------------------------------------------------
216
 
217
        // check MIXER-Revision at first EEPROM Byte = 1000                                                                     // #define EEPROM_ADR_MIXER_TABLE     1000
218
 
219
        // if((eeprom_read_byte(&EEPromArray[EEPROM_ADR_MIXER_TABLE]) == MIXER_REVISION) && (eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != 0xff))  
220
        if((eeprom_read_byte(&EEPromArray[1000]) == 1) && (eeprom_read_byte(&EEPromArray[1]) != 0xFF))                          // aufgelöst
221
        {
222
                unsigned char i;                                                                                                                                // Settings via Koptertool zurücksetzen
223
                RequiredMotors = 0;
224
                eeprom_read_block(&Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer));
225
                for(i=0; i<16;i++) { if(Mixer.Motor[i][0] > 0) RequiredMotors++;}
226
        }
227
        else // default
228
        {
229
                unsigned char i;
230
                printf("\n\rerzeugt default Mixer Table");
231
                for(i=0; i<16;i++) { Mixer.Motor[i][0] = 0;Mixer.Motor[i][1] = 0;Mixer.Motor[i][2] = 0;Mixer.Motor[i][3] = 0;};
232
 
233
                // default = Quadro             
234
                // number 64 is equivalent to 100%
235
                // GasMischanteil               pd_ergebnis_nick                        pd_ergebnis_roll                GierMischanteil
236
                Mixer.Motor[0][0] = 64; Mixer.Motor[0][1] = +64; Mixer.Motor[0][2] =   0; Mixer.Motor[0][3] = +64;      // vorne
237
                Mixer.Motor[1][0] = 64; Mixer.Motor[1][1] = -64; Mixer.Motor[1][2] =   0; Mixer.Motor[1][3] = +64;      // hinten
238
                Mixer.Motor[2][0] = 64; Mixer.Motor[2][1] =   0; Mixer.Motor[2][2] = -64; Mixer.Motor[2][3] = -64;      // rechts
239
                Mixer.Motor[3][0] = 64; Mixer.Motor[3][1] =   0; Mixer.Motor[3][2] = +64; Mixer.Motor[3][3] = -64;      // links
240
                Mixer.Revision = MIXER_REVISION;                        // #define MIXER_REVISION    1 
241
                memcpy(Mixer.Name, "Quadro\0", 11);
242
                eeprom_write_block(&Mixer, &EEPromArray[EEPROM_ADR_MIXER_TABLE], sizeof(Mixer));        // sizeof(Mixer) = 77
243
        }
244
 
245
        printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name,RequiredMotors);
246
 
247
 
248
        // ---------------------------------------------------------------------------------------------------------------------------
249
        // how many BL-Ctrls are connected ?
250
        // ---------------------------------------------------------------------------------------------------------------------------
251
        printf("\n\r...BL-Ctrl....");                                                                                                                          
252
 
253
        motorread = 0;  
254
        UpdateMotor = 0;  
255
        SendMotorData();
256
        while(!UpdateMotor);
257
        motorread = 0;                                                                                                          // read the first I2C-Datasets
258
        timer = SetDelay(2000);                                                                                         // sets
259
 
260
        for(i=0; i < MAX_MOTORS; i++)                                                                           // #define MAX_MOTORS      4
261
        {
262
                UpdateMotor = 0;
263
                SendMotorData();                                                                                                // goto fc.c line 460
264
                while(!UpdateMotor);
265
 
266
                if(Mixer.Motor[i][0] > 0)                                                                               // wait maximum 2 sec to wake up the BL-Ctrls
267
                {
268
                        while(!CheckDelay(timer) && !MotorPresent[i])
269
                        {
270
                                UpdateMotor = 0;
271
                                SendMotorData();
272
                                while(!UpdateMotor);
273
                        }
274
                }
275
                if(MotorPresent[i]) printf("%d ",i+1);
276
        }
277
 
278
        for(i=0; i < MAX_MOTORS; i++)
279
        {
280
                if(!MotorPresent[i] && Mixer.Motor[i][0] > 0)                                   // #define MAX_MOTORS      4
281
                {
282
                        printf("\n\r\n\r!! missing BL-CTRL: %d !!",i+1);
283
                        ServoActive = 1;                                                                                        // just in case the FlightCtrl would be used as camera-stabilizer
284
                }      
285
                MotorError[i] = 0;
286
        }
287
        printf("\n\r===================================");
288
        SendMotorData();
289
 
290
 
291
        // ---------------------------------------------------------------------------------------------------------------------------
292
        // check, that the revision in EEPROM fits to actual software
293
        // ---------------------------------------------------------------------------------------------------------------------------
294
        if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION)                // #define EEPROM_ADR_VALID  1
295
        {                                                                                                                                                               // #define EE_DATENREVISION 80
296
 
297
                DefaultKonstanten1();                                                                                                           // Funktion aus eeprom.c
298
                printf("\n\rInit. EEPROM");
299
 
300
                for (unsigned char i=1;i<6;i++)                                                                                 // es gibt 5 verschiedene Settings
301
                {
302
                        if(i==2) DefaultKonstanten2();                                                                          // Kamera
303
                        if(i==3) DefaultKonstanten3();                                                                          // Anfänger
304
                        if(i>3)  DefaultKonstanten2();                                                                          // Kamera
305
 
306
                        // ---------------------------------------------------------------------------------------------------------------------------
307
                        // valid Setting ?
308
                        // ---------------------------------------------------------------------------------------------------------------------------
309
                        if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+1]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+2]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+3]) < 12)
310
                        {
311
                                EE_Parameter.Kanalbelegung[0] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+0]);          // Nick // #define EEPROM_ADR_CHANNELS  80
312
                                EE_Parameter.Kanalbelegung[1] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+1]);          // Roll
313
                                EE_Parameter.Kanalbelegung[2] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+2]);          // Gas
314
                                EE_Parameter.Kanalbelegung[3] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+3]);          // Gier
315
                                EE_Parameter.Kanalbelegung[4] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+4]);          // Poti 1
316
                                EE_Parameter.Kanalbelegung[5] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+5]);          // Poti 2
317
                                EE_Parameter.Kanalbelegung[6] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+6]);          // Poti 3
318
                                EE_Parameter.Kanalbelegung[7] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+7]);          // Poti 4
319
                                if(i==1) printf(": Generating Default-Parameter using old Stick Settings");
320
                        } else DefaultStickMapping();
321
 
322
                        WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);            // #define  STRUCT_PARAM_LAENGE  sizeof(EE_Parameter)
323
                        // WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], 101));
324
                }
325
                SetActiveParamSetNumber(3);                                                                                                                                                     // default Setting ist Beginner
326
                eeprom_write_byte(&EEPromArray[EEPROM_ADR_VALID], EE_DATENREVISION);                                                                    // #define EE_DATENREVISION 80
327
                // eeprom_write_byte(&EEPromArray[1], 80);                                                                                                                              // aufgelöst
328
 
329
        } // EOF : check existing revision at EEPROM
330
 
331
        FlugMinuten = (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_MINUTES2]) * 256 + (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_MINUTES2+1]);
332
        FlugMinutenGesamt = (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_MINUTES]) * 256 + (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_MINUTES+1]);
333
 
334
        if(FlugMinutenGesamt == 0xFFFF || FlugMinuten == 0xFFFF)                                        // Flugminuten sind am überlaufen - zurücksetzen
335
        {
336
                FlugMinuten = 0;
337
                FlugMinutenGesamt = 0;
338
        }
339
 
340
        printf("\n\rFlight-time %u min  Total:%u min" ,FlugMinuten,FlugMinutenGesamt);
341
 
342
 
343
        if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) > 4)
344
        {
345
                printf("\n\rACC noch nicht calibriert !");
346
        }
347
 
348
        ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);             // #define  STRUCT_PARAM_LAENGE  sizeof(EE_Parameter)
349
 
350
        printf("\n\rUsing parameterset %d", GetActiveParamSetNumber());
351
 
352
 
353
        if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
354
        {
355
                printf("\n\rKalibrieren des Drucksensors.");
356
                timer = SetDelay(1000);                                                                         // 
357
                SucheLuftruckOffset();
358
                while (!CheckDelay(timer));                                                             // pause 1 sec
359
                printf("OK\n\r");
360
        }
361
 
362
        SetNeutral();                                                                                                   // Nullwerte ermitteln und Startwerte festlegen - goto fc.c line 162
363
 
364
        ROT_OFF;                                                                                                                // redLED off // PORTB |= 0x01;
365
 
366
        beeptime = 2000;
367
        ExternControl.Digital[0] = 0x55;                                                                // externe Steuerung per serieller Schnittstelle - siehe uart.h
368
 
369
        printf("\n\rControl: ");
370
        if (EE_Parameter.GlobalConfig & CFG_HEADING_HOLD) printf("HeadingHold");
371
        else printf("normaler (ACC-Mode)");
372
 
373
        LcdClear();
374
        I2CTimeout = 5000;                                                                                              // watchdog set up to 10 sec
375
        WinkelOut.Orientation = 1;
376
 
377
        LipoDetection(1);                                                                                               // Lipos should be detected now
378
 
379
        printf("\n\r===================================\n\r");
380
 
381
        timer = SetDelay(2000);
382
        // -------------------------------- end of main() prelude ---------------------------------------------------------------------
383
 
384
 
385
 
386
        //----------------------------------------------------------------------------------------------------------------------
387
        // forever loop of main program
388
        //----------------------------------------------------------------------------------------------------------------------
389
        while(1)
390
        {
391
                if(UpdateMotor && AdReady)                                                      // motor is updated every 2 ms and ADC is already passed
392
                {
393
                        UpdateMotor=0;                                                                          // reset and wait fpr the next 2ms timed trigger from timer0 IR
394
 
395
                        if(WinkelOut.CalcState) CalMk3Mag();                            // In diesem Spezial-Fall soll der Kompass kalibriert werden
396
                        else MotorRegler();                                                                     // Im Normalfall Sollwerte für die Motoren berechnen = goto fc.c line 541
397
 
398
                        SendMotorData();                                                                        // Sollwerte an die Motorren senden -> fc.c Zeile 465
399
 
400
                        ROT_OFF;                                                                                        // switch red LED off   // PORTB |= 0x01;
401
 
402
                        if(SenderOkay) SenderOkay--;                                            // ICIE1: Timer/Counter1, Input Capture Interrupt Enable
403
                        else TIMSK1 |= _BV(ICIE1);                                                      // enable PPM-Input     // TIMSK1 – Timer/Counter1 Interrupt Mask Register -> – – ICIE1 – – OCIE1B OCIE1A TOIE1
404
 
405
                        if(!--I2CTimeout || MissingMotor)                                       // counting down I2CTimeout or motor is missing
406
                        {
407
                                if(!I2CTimeout)
408
                                {
409
                                        i2c_reset();
410
                                        I2CTimeout = 5;
411
                                        DebugOut.Analog[28]++;                                  // I2C-Error
412
                                }
413
 
414
                                if((BeepMuster == 0xffff) && MotorenEin)
415
                                {
416
                                        beeptime = 10000;
417
                                        BeepMuster = 0x0080;
418
                                }
419
                        }
420
                        else
421
                        {
422
                                ROT_OFF;                                                                                // switch red LED off   // PORTB |= 0x01;
423
                        }
424
 
425
                        if( 1 && (!UpdateMotor || !MotorenEin))
426
                        {
427
                                DatenUebertragung();
428
                                BearbeiteRxDaten();
429
                        }
430
                        else BearbeiteRxDaten();
431
 
432
                        // DatenUebertragung();                                                         // where ist that contained?
433
                        // BearbeiteRxDaten();                                                          // where ist that contained?
434
 
435
                        if(CheckDelay(timer))                                                           // goto timer0.c line 65
436
                        {
437
                                timer += 20;
438
 
439
                                if(PcZugriff) PcZugriff--;                                              // flight-CTRL controlled by external PC
440
                                else
441
                                {
442
                                        ExternControl.Config = 0;
443
                                        ExternStickNick = 0;
444
                                        ExternStickRoll = 0;
445
                                        ExternStickGier = 0;
446
                                        if(BeepMuster == 0xffff && SenderOkay == 0)
447
                                        {
448
                                                beeptime = 15000;
449
                                                BeepMuster = 0x0c00;
450
                                        }
451
                                }
452
 
453
                                if(UBat < BattLowVoltageWarning)                                        // low battery
454
                                {
455
                                        MikroKopterFlags |= FLAG_LOWBAT;
456
                                        if(BeepMuster == 0xffff)
457
                                        {
458
                                                beeptime = 6000;
459
                                                BeepMuster = 0x0300;
460
                                        }
461
                                }
462
                                else MikroKopterFlags &= ~FLAG_LOWBAT;
463
 
464
                                //SPI_StartTransmitPacket();                                            // where ist that contained?
465
                                SendSPI = 4;
466
                                if(!MotorenEin) timer2 = 1450;                                          // round it up to 30 sec                                
467
                                if(++timer2 == 2930)                                                            // one minute
468
                                {
469
                                        timer2 = 0;
470
                                        FlugMinuten++;
471
                                        FlugMinutenGesamt++;
472
                                        eeprom_write_byte(&EEPromArray[EEPROM_ADR_MINUTES2],FlugMinuten / 256);
473
                                        eeprom_write_byte(&EEPromArray[EEPROM_ADR_MINUTES2+1],FlugMinuten % 256);
474
                                        eeprom_write_byte(&EEPromArray[EEPROM_ADR_MINUTES],FlugMinutenGesamt / 256);
475
                                        eeprom_write_byte(&EEPromArray[EEPROM_ADR_MINUTES+1],FlugMinutenGesamt % 256);
476
 
477
                                        timer = SetDelay(20);                                                   // delay 20 ms
478
                                }
479
                        }
480
 
481
                        LED_Update();                                                                                   // junmps erery 2ms to led.c line 32
482
 
483
                } // *** EOF : if(UpdateMotor && AdReady) 
484
 
485
                // *** EOF: if(!SendSPI) { SPI_TransmitByte(); }
486
 
487
        } // End of endlessloop
488
 
489
        return (1);
490
}
491
// *** EOF: main(void) ************************************************************************************************************