Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
962 - 1
 
2
/****************************************************************/
3
/*                                                                                                                              */
4
/*                               NG-Video 5,8GHz                                                        */
5
/*                                                                                                                              */
6
/*                              Copyright (C) 2011 - gebad                                              */
7
/*                                                                                                                              */
8
/*  This code is distributed under the GNU Public License               */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt       */
10
/*                                                                                                                              */
11
/****************************************************************/
12
 
13
#include <avr/io.h>
14
#include <stdlib.h>
15
#include <avr/interrupt.h>
16
#include <avr/eeprom.h>
17
#include <util/delay.h>
18
 
19
#include "config.h"
20
#include "dogm.h"
21
#include "messages.h"
22
#include "ngvideo.h"
23
#include "menue.h"
24
#include "servo.h"
25
#include "tracking.c"
26
 
27
 
28
/************************************************************************************/
29
/*  initialisiert den EEPROM mit default Werten, bzw. liest EEPROM gespeicherte         */
30
/*  Werte in gloabale Variablen.                                                                                                        */
31
/*      Parameter:                                                                                                                                              */
32
/*  uint8_t ep_reset   :0 = zwangsweises Rückstetzen auf default-Werte                          */
33
/*                                                                                                                                                                      */
34
/************************************************************************************/
35
void Init_EEPROM(uint8_t ep_reset)
36
{ char ver[sizeof(VERSION)];
37
  uint8_t eep_init;
38
 
39
  eep_init = eeprom_read_byte(&ep_eep_init);
40
  eeprom_read_block(&ver, &ep_version, sizeof(VERSION));
41
  _delay_ms(1);
42
 
43
  if ((eep_init != EEP_INITB) || (ep_reset == 0) || strcmp(VERSION, ver))
44
  {
45
     // nur bei Erstinitialisierung DOGM auf default 3,3V setzen
46
        if ((eep_init != EEP_INITB) || strcmp(VERSION, ver)){
47
          eeprom_write_byte(&ep_eep_init, EEP_INITB);
48
          eeprom_write_byte(&ep_dogm_vers, DOGM3V);
49
          eeprom_write_byte(&ep_contrast, CONTRAST3V);
50
      eeprom_write_block(&VERSION, &ep_version, sizeof(VERSION));
51
    }
52
        eeprom_write_byte(&ep_light_time, BACKGR_LIGHT_MAX);
53
        eeprom_write_byte(&ep_u_offset, U_OFFSET);
54
        eeprom_write_dword(&ep_u_min, U_MIN);
55
    eeprom_write_byte(&ep_channel, CHANNEL);
56
    eeprom_write_byte(&ep_av_source, AV_SOURCE);
57
        eeprom_write_byte(&ep_language, NO_LANGUAGE);
58
    eeprom_write_word(&ep_udbm_min, UDBM_MIN);
59
        eeprom_write_word(&ep_udbm_max, UDBM_MAX);
60
        eeprom_write_word(&ep_udbm_korr_1, UDBM_KORR_FA);
61
        eeprom_write_word(&ep_udbm_korr_2, UDBM_KORR_FA);
62
    eeprom_write_byte(&ep_sIdxSteps, STEPS_255);
63
        eeprom_write_block(&servo[0],&ep_servo[0],sizeof(servo_t));
64
        eeprom_write_block(&servo[1],&ep_servo[1],sizeof(servo_t));
65
        eeprom_write_byte(&ep_tracking, TRACKING_MIN);
66
        eeprom_write_byte(&ep_track_hyst, TRACKING_HYSTERESE);
67
        eeprom_write_byte(&ep_track_tx, 0);
68
        eeprom_write_byte(&ep_baudrate, BAUDRATE);
69
        sIdxSteps = STEPS_255;
70
  }
71
  else
72
  {
73
        light_time = eeprom_read_byte(&ep_light_time);
74
        u_offset = eeprom_read_byte(&ep_u_offset);
75
        u_min = eeprom_read_dword(&ep_u_min);
76
    channel = eeprom_read_byte(&ep_channel);
77
    av_source = eeprom_read_byte(&ep_av_source);
78
        language = eeprom_read_byte(&ep_language);
79
        udbm_min = eeprom_read_word(&ep_udbm_min);
80
        udbm_max = eeprom_read_word(&ep_udbm_max);
81
        udbm_korr_1 = eeprom_read_word(&ep_udbm_korr_1);
82
        udbm_korr_2 = eeprom_read_word(&ep_udbm_korr_2);
83
        sIdxSteps = eeprom_read_byte(&ep_sIdxSteps);
84
        eeprom_read_block(&servo[0],&ep_servo[0],sizeof(servo_t));
85
        eeprom_read_block(&servo[1],&ep_servo[1],sizeof(servo_t));
86
    tracking = eeprom_read_byte(&ep_tracking);
87
    track_hyst = eeprom_read_byte(&ep_track_hyst);
88
        track_tx = eeprom_read_byte(&ep_track_tx);
89
        baudrate = eeprom_read_byte(&ep_baudrate);
90
 }
91
  dogm_vers = eeprom_read_byte(&ep_dogm_vers);
92
  contrast = eeprom_read_byte(&ep_contrast);
93
  hyst_u_min = u_min;
94
  RSSI_Calc_UdBm(pudbm); // Vergleichstabelle für dBm-Balken berechnen
95
  sw_avx = av_source;
96
  for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
97
        servoSet_rev(i, servo[i].rev);
98
        servoSet_min(i, servo[i].min);
99
        servoSet_max(i, servo[i].max);
100
        servoSet_mid(i, servo[i].mid);
101
  }
102
  // Vorberechnung von ServoChannels[channel].duty
103
  servoSetDefaultPos(); // Ausgangsstellung beider Servos
104
  coldstart = 1;
105
  USART_Init_Baudrate();
106
  USART_RX_Mode(tracking);
107
}
108
 
109
void servoSetDefaultPos(void)
110
{
111
  servoSetPosition(SERVO_PAN, ServoSteps()/2);  // Ausgangsstellung SERVO_PAN
112
  servoSetPosition(SERVO_TILT, 0);                              // Ausgangsstellung SERVO_TILT
113
}
114
 
115
void USART_Init_Baudrate(void)
116
{
117
  if (tracking == TRACKING_MKCOCKPIT)
118
    USART_Init(baud[baudrate]);
119
  else
120
    USART_Init(baud[6]);        //57600
121
}
122
 
123
/************************************************************************************/
124
/*  setzt Flag für 3,3V oder 5V DOGM                                                                                            */
125
/*      Parameter:                                                                                                                                              */
126
/*  uint8_t dogm        :Version                                                                                                                */
127
/*                                                                                                                                                                      */
128
/************************************************************************************/
129
void Set_DOGM_Version(void)
130
{
131
  if(dogm_vers == DOGM5V) {
132
    dogm_vers = DOGM3V;
133
        contrast = CONTRAST3V;
134
  }
135
  else {
136
    dogm_vers = DOGM5V;
137
        contrast = CONTRAST5V;
138
  }
139
  eeprom_write_byte(&ep_dogm_vers, dogm_vers);
140
  eeprom_write_byte(&ep_contrast, contrast);
141
}
142
 
143
/************************************************************************************/
144
/*  setzt den RX-Kanal von 1 bis 7                                                                                                      */
145
/*      Parameter:                                                                                                                                              */
146
/*  uint8_t channel     :Kanal                                                                                                                  */
147
/*                                                                                                                                                                      */
148
/************************************************************************************/
149
void Set_Channel(uint8_t channel)
150
{ uint8_t tmp;
151
 
152
  channel--;
153
  tmp = channel & 0b00000111;   // Kanal 1 bis 7 Werte 0 bis 6 setzen
154
  PORTA |= tmp;
155
  PORTB |= tmp;
156
  tmp = channel | 0b11111000;
157
  PORTA &= tmp;
158
  PORTB &= tmp;  
159
}
160
 
161
/************************************************************************************/
162
/*  schaltet den MUX auf AV1 oder AV2 ohne Darstellung und en-/disabled Interrupt       */
163
/*  wird nur in main.c (Initialisierung) und Menü Sourceumschaltung eingesetzt          */
164
/*  deswegen cli() und sei() nur in Menu_AV_Source(void)                                                        */
165
/*  Parameter:                                                                                                                                          */
166
/*  uint8_t src :0-AV1, 1-AV2                                                                                                           */
167
/*                                                                                                                                                                      */
168
/************************************************************************************/
169
uint8_t Set_AV_Source(uint8_t src)
170
{
171
  switch(src) {
172
    case AV1:           CLEAR_INT10;    // Interrupt für Sync ausschalten
173
                                        SET_MUX_0;
174
                                        break;
175
    case AV2:           CLEAR_INT10;    // Interrupt für Sync ausschalten
176
                                        SET_MUX_1;
177
                                        break;
178
    case DIVERSITY: SET_INT10;          // External Interrupt Mask Register ein
179
                                        SET_MUX_0;
180
                                        break;
181
  }
182
  return(src);
183
}
184
 
185
 
186
/**************************************************************/
187
/*                                                                                                                        */
188
/*                     LCD-Backlight                                              */
189
/*                                                                                                                        */
190
/**************************************************************/
191
 
192
void lcdSet_BackgrLight_Off(void)
193
{
194
  backgr_light = OFF;
195
  lcdBacklightOff();
196
}
197
 
198
void lcd_BackgrLight_On(void)
199
{ // ...&& (light_count < light_time)) ==> sonst wird Beleuchtung laufend wieder eingeschaltet
200
  if ((backgr_light == OFF) && (light_time > BACKGR_LIGHT_MIN) && (light_count < light_time)) {
201
    cli();
202
        light_count = 0;
203
        sei();
204
        backgr_light = ON;
205
        lcdBacklightOn();
206
  }
207
}
208
 
209
void lcd_BackgrLight(void)
210
{
211
  if (backgr_light == ON) {                                     // nur wenn Beleuchtung an
212
    if (light_time == BACKGR_LIGHT_MIN)         // Hintergrundbeleuchtung immer aus?
213
      lcdSet_BackgrLight_Off();
214
        else
215
          if (light_time < BACKGR_LIGHT_MAX) {  // Hintergrundbeleuchtung immer an?
216
            cli();
217
                light_count++;
218
                sei();
219
                if (light_count >= light_time) lcdSet_BackgrLight_Off();
220
          }
221
  }
222
}
223
 
224
/**************************************************************/
225
/*                                                                                                                        */
226
/*                           ADC                                                      */
227
/*                                                                                                                        */
228
/*      http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial  */
229
/*                                                                                                                        */
230
/**************************************************************/
231
 
232
void ADC_Init(void)
233
{
234
  uint16_t result;
235
 
236
  ADMUX = (0<<REFS1) | (1<<REFS0);              // AVcc als Referenz benutzen, da an AREF 4,8 V
237
  ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);        // Frequenzvorteiler Prescaler 128
238
  ADCSRA |= (1<<ADEN);                                  // ADC aktivieren
239
 
240
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
241
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
242
 
243
  ADCSRA |= (1<<ADSC);                                  // eine ADC-Wandlung 
244
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
245
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
246
     Wandlung nicht übernommen. */
247
  result = ADCW;
248
}
249
 
250
/* ADC Einzelmessung */
251
uint16_t ADC_Read( uint8_t channel )
252
{
253
  // Kanal waehlen, ohne andere Bits zu beeinflußen
254
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
255
  ADCSRA |= (1<<ADSC);                          // eine Wandlung "single conversion"
256
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
257
  return ADCW;                                  // ADC auslesen und zurückgeben
258
}
259
 
260
/* ADC Mehrfachmessung mit Mittelwertbbildung */
261
uint16_t ADC_Read_Avg( uint8_t channel, uint16_t average )
262
{
263
  uint32_t result = 0;
264
 
265
  for (uint16_t i = 0; i < average; ++i ){
266
    result += ADC_Read( channel );
267
        _delay_ms(1);
268
  }
269
  return (uint16_t)( result / average );
270
}
271
 
272
 
273
/**************************************************************/
274
/*                                                                                                                        */
275
/*                         Beeper                                                         */
276
/*                                                                                                                        */
277
/**************************************************************/
278
 
279
void Beep(uint8_t time)
280
{
281
  PINB |= (1<<BEEPER);
282
  PINB &= ~(1<<BEEPER);
283
  _delay_ms(time);
284
  PINB |= (1<<BEEPER);
285
  PINB &= ~(1<<BEEPER);
286
}
287
 
288
void Double_Beep(uint8_t time, uint8_t pause)
289
{
290
        Beep(time);
291
        _delay_ms(pause);
292
        Beep(time);
293
}
294
 
295
/**************************************************************/
296
/*                                                                                                                        */
297
/*                        U-Batterie                                              */
298
/*                                                                                                                        */
299
/**************************************************************/
300
 
301
void Displ_Format_U(uint32_t u, uint8_t nkst)
302
{ char s[3];
303
  uint16_t d1;
304
  int i;
305
 
306
/* vereinfacht Variablenübergabe funktion change_value(uint32_t x),
307
   kein printf, double oder float
308
   siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik */
309
  //nkst für 1 bis 2 Nachkommastellen mitgeben
310
  d1 = u / 100 ;
311
  if (d1 < 10) lcdPutc(' ');
312
  utoa(d1 ,s ,10 );
313
  lcdPuts(s);
314
  lcdPuts(Msg(MSG_KOMMA));
315
  for ( i = 1; i >= 0; i--)  // Zahl hat hier immer 2 Nachkommatellen
316
  {
317
        s[i] = (u % 10) + '0';   // modulo für Nachkommastelle gleich als char
318
    u /= 10;
319
  }  
320
  s[nkst] = '\0';
321
  lcdPuts(s);
322
 }
323
 
324
// uint32_t u, da bei Displ_Fnct[fu_index](val) der größte Wert UBat gleich 32 Bit 
325
void Displ_1Nk(uint32_t u)
326
{
327
  Displ_Format_U(u, 1);
328
}
329
 
330
void Displ_U_2Nk(uint32_t u)
331
{
332
  Displ_Format_U(u, 2);
333
  lcdPutc('V');
334
}
335
 
336
// uint8_t beep_timer :Akku-leer-Beeper nur mit Task_0_1()-Intervalle bei Menü-Rücksprung
337
uint32_t U_Messen_cmp(uint8_t beep_timer)
338
{ uint32_t ubat;
339
  static struct
340
  { uint8_t time;
341
        uint8_t count;
342
  } beep_low;
343
 
344
 
345
/*       ubat = ((ADC_Read(VBAT) * Vref * (R104 + R103)) /(1024 * R103)) + UD10 (UD10 ist Offset)
346
         Verhältniswert * 100 *8192 ( Verhältniswert = realer Korrekturwert;
347
         mal 100 da alle Werte 2 Nachkommastellen berücksichtigt, aber ohne gerechnet wird
348
         mal 8192 => ohne Bruch gerechnet aber dabei mehr Kommastellen berücksichtigt) */
349
  ubat = (ADC_Read(VBAT) * (uint64_t)43504 + (uint64_t)u_offset * 8192)/ 8192;
350
  if ( ubat <= hyst_u_min )
351
  {
352
    if (bat_low != 0) {         // nicht laufend Display neu schreiben
353
          hyst_u_min = u_min + 20;      // 200mV Hysterese - beruhigt Anzeige
354
          lcdClear();
355
          lcdPuts(Msg(MSG_ACCU_LOW));
356
          bat_low = 0;
357
          Beep(BEEPBAT);
358
          // da derzeit Fkt. aller 500ms aufgerufen, mit 2 Min Abstand beginnen
359
          beep_low.time = BEEP_LOW_TIME;
360
          beep_low.count = 0;
361
        }
362
        // Akku leer, in immer kürzeren Intervallen Beep
363
        if ((beep_timer == 1) && (beep_low.count++ >= beep_low.time)){
364
          Beep(BEEPBAT);
365
          if (beep_low.time > 2)
366
            beep_low.time /= 2;
367
          beep_low.count = 0;
368
        }
369
  }
370
  else {
371
    if (hyst_u_min > u_min) {   // falls Anzeige von Batterie leer
372
          bat_low = 1;                          // und zurück geschaltet wird,
373
          hyst_u_min = u_min;           // dann Main_Disp wieder darstellen
374
          Displ_Main_Disp();
375
        }
376
  }
377
  return(ubat);
378
}
379
 
380
void Displ_VBat(void) // da u_offset globale Variable
381
{ uint32_t ubat;
382
 
383
  ubat = U_Messen_cmp(ENABLE_BTIMER);
384
  if (bat_low != 0) { // würde sonst Anzeige Akku leer überschreiben
385
    lcdGotoXY(11, 0);
386
    Displ_1Nk(ubat);
387
  }
388
}
389
 
390
 
391
/**************************************************************/
392
/*                                                                                                                        */
393
/*                          RSSI                                                          */
394
/*                                                                                                                        */
395
/**************************************************************/
396
 
397
/* RSSI Werte Korrekturfaktor berechnen */
398
uint16_t  RSSI_Calc_Korr(uint16_t u0, uint16_t u1)
399
{ uint16_t u_max;
400
 
401
  // immer nur den kleineren Wert vergrößern
402
  if (u0 < u1) {
403
    udbm_korr_1 = (((uint32_t)u1 * UDBM_KORR_FA) / u0)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
404
        udbm_korr_2 = UDBM_KORR_FA;
405
        u_max = u1;
406
  }
407
  else {
408
    udbm_korr_2 = (((uint32_t)u0 * UDBM_KORR_FA) / u1)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
409
    udbm_korr_1 = UDBM_KORR_FA;
410
        u_max = u0;
411
  }
412
  eeprom_write_word(&ep_udbm_korr_1, udbm_korr_1);
413
  eeprom_write_word(&ep_udbm_korr_2, udbm_korr_2);
414
  return(u_max);
415
}
416
 
417
void Displ_Calibr_Aktiv(void)
418
{
419
  lcdClear();
420
  Disp_Str_mid(Msg(MSG_CALIBRATION),0);
421
  Disp_Str_mid(Msg(MSG_RUNNING),1);
422
}
423
 
424
void Displ_Error_TX(uint8_t message)
425
{
426
  lcdClear();
427
  Disp_Str_mid(Msg(MSG_ERROR),0);
428
  Disp_Str_mid(Msg(MSG_TX_NOT),1);
429
  Disp_Str_mid(Msg(message), 2);
430
  for ( uint8_t i=0; i<=30;i++)
431
    _delay_ms(100);
432
}
433
 
434
void RSSI_Min_Calibrate(uint16_t *pudbm)
435
{ uint16_t u0, u1;
436
 
437
  Displ_Calibr_Aktiv();
438
  u0 = ADC_Read_Avg(RSSI0, 1000);               //1000 Wiederholungen mit
439
  u1 = ADC_Read_Avg(RSSI1, 1000);               //Mittelwertbildung
440
  // Plausibilitätsprüfung ob Sender ausgeschaltet
441
  if (u0 + u1 > 500) {
442
    udbm_min = RSSI_Calc_Korr(u0, u1); // ist real die größere Spannung, aber der kleinere dbm Wert
443
    eeprom_write_word(&ep_udbm_min, udbm_min);
444
        Double_Beep(DBEEPWR, DBEEPWRP);
445
        RSSI_Calc_UdBm(pudbm);
446
  }
447
  else Displ_Error_TX(MSG_TX_OFF);
448
}
449
 
450
void RSSI_Max_Calibrate(uint16_t *pudbm)
451
{ uint16_t u0, u1;
452
 
453
  Displ_Calibr_Aktiv();
454
  u0 = ADC_Read_Avg(RSSI0, 1000);       //1000 Wiederholungen mit
455
  u1 = ADC_Read_Avg(RSSI1, 1000);       //Mittelwertbildung
456
  // Plausibilitätsprüfung ob Sender in der Nähe eingeschaltet
457
  if (u0 + u1 < 400) {
458
    udbm_max = RSSI_Calc_Korr(u0, u1); // ist real die kleinere Spannung, aber der größere dbm Wert
459
    eeprom_write_word(&ep_udbm_max, udbm_max);
460
        Double_Beep(DBEEPWR, DBEEPWRP);
461
    RSSI_Calc_UdBm(pudbm);
462
  }
463
  else Displ_Error_TX(MSG_TX_ON);
464
}
465
 
466
// Vergleichstabelle für RSSI-Bargraph berechnen, vermeidet laufend gleiche Berechnung
467
void RSSI_Calc_UdBm(uint16_t *pudbm)
468
{ uint8_t n;
469
  n = (udbm_min - udbm_max -3)/11;      // -3 um Ende dBm Skala sicher zu erreichen
470
  for (uint8_t i = 0; i < 12; i++)
471
    pudbm[i] = (udbm_min - i * n);
472
}
473
 
474
void Displ_RSSI_Bargraph(uint16_t *pudbm, uint16_t uadc)
475
{ uint8_t i;
476
 
477
  // Balken zeichnen - udbm
478
  for (i = 0; i < 12; i++)
479
    if (uadc < pudbm[i]) lcdPutc(0); else lcdPutc(' ');
480
}
481
 
482
uint8_t RSSI_Diversity(uint8_t src, uint16_t *pudbm, uint8_t visible)
483
{ uint16_t u0, u1;
484
  static uint8_t div_flag, ret_div_flag;
485
  char marker;
486
 
487
  u0 = (ADC_Read(RSSI0) * (uint32_t)udbm_korr_1)/UDBM_KORR_FA;
488
  u1 = (ADC_Read(RSSI1) * (uint32_t)udbm_korr_2)/UDBM_KORR_FA;
489
 
490
  // falls beide RX gleich gut/schlecht synchronisieren
491
  // Achtung! Niedrigere Spannung - größere Feldstärke
492
  if (src == DIVERSITY) {
493
    if (u0 < u1) {
494
          ret_div_flag = AV1;
495
          if ((vscount0 == 255) && (vscount1 == 255)) SET_MUX_0;
496
    }
497
    else {
498
          ret_div_flag = AV2;
499
          if ((vscount0 == 255) && (vscount1 == 255)) SET_MUX_1;
500
    }
501
  }
502
  else ret_div_flag = src; // sonst leerer Returnwert
503
 
504
  if (visible) {
505
    if (src == DIVERSITY) {
506
          // Synchronisation vorrangig zur Feldstärke
507
      if ((vsync0 != vsync1) && ((vscount0 & vscount1) < 255)) {
508
            // ist nur zur Anzeige - Sync-MUX wird über Interrupt gesteuert
509
        if (vsync0 == 0) {
510
              div_flag = AV1;
511
            }
512
            else {
513
              div_flag = AV2;
514
            }
515
            marker = MARKER_SYNC;
516
      }
517
          else {
518
            div_flag = ret_div_flag;
519
                marker = MARKER_RSSI;
520
          }
521
    }
522
    else marker = MARKER_AV;
523
        // wäre unschön - keine RSSI-Anzeige, aber Marker springt
524
        if ((u0 > pudbm[0]) && (u1 > pudbm[0])) marker = ' ';
525
        lcdGotoXY(2, 1);
526
    Displ_RSSI_Bargraph(pudbm, u0);
527
    lcdGotoXY(2, 2);
528
        Displ_RSSI_Bargraph(pudbm, u1);
529
        if (src == DIVERSITY) Displ_AV_Mark(div_flag, marker);
530
  }
531
  return(ret_div_flag);
532
}
533
 
534
/**************************************************************/
535
/*                                                                                                                        */
536
/*      Diversity v-Synchronisation Interruptroutinen             */
537
/*                                                                                                                        */
538
/**************************************************************/
539
 
540
/* Impulszähler für V-Synchronisation 0 und 1
541
   wird durch Interrupt des jewiligen vSync einzeln zurückgesetzt */
542
ISR(TIMER2_OVF_vect)
543
{
544
  TCNT2 = (int8_t)(int16_t)-(F_CPU / 64 * 500e-6);  // preload
545
  if (vscount0 < 255) ++vscount0; // Überlauf von vscount vermeiden
546
  if (vscount1 < 255) ++vscount1; // Überlauf von vscount vermeiden
547
  if (rx_timeout < RX_TIME_OLD) ++rx_timeout; // veranlasst bei GPS-Tracking MK Datensatz senden
548
}
549
 
550
/* Messung von Impulsabstand v-Synchronisation 0
551
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
552
ISR(INT0_vect)
553
{
554
  if ((vscount0 >= 79) && (vscount0 <= 81))
555
    vsync0 = 0;
556
  else {
557
    vsync0 = 1;
558
        if (vsync1 == 0)
559
          SET_MUX_1;
560
  }
561
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI 
562
    if (sw_avx == AV1) {
563
          SET_MUX_0;
564
        }
565
        else
566
          SET_MUX_1;
567
  }
568
  vscount0 = 0;
569
}
570
 
571
/* Messung von Impulsabstand v-Synchronisation 1
572
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
573
ISR(INT1_vect)
574
{
575
 if ((vscount1 >= 79) && (vscount1 <= 81))
576
    vsync1 = 0;
577
  else {
578
    vsync1 = 1;
579
    if (vsync0 == 0)
580
          SET_MUX_0;
581
  }
582
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
583
    if (sw_avx == AV1) {
584
          SET_MUX_0;
585
        }
586
        else
587
          SET_MUX_1;
588
  }
589
  vscount1 = 0;
590
}
591
 
592
/**************************************************************/
593
/*                                                                                                                        */
594
/*                          Tasks                                                         */
595
/*        ermöglicht unterschiedliche Zeiten f. UBat, Sync...     */
596
/*                                                                                                                        */
597
/**************************************************************/
598
 
599
void Task_0_1(void)
600
{
601
  if (task_timer0_1) {
602
    cli();
603
        task_timer0_1 = 0;
604
        sei();
605
    Displ_VBat();
606
   }
607
 }
608
 
609
void Task_0_2(void)
610
{
611
  if (task_timer0_2) {
612
    cli();
613
        task_timer0_2 = 0;
614
        sei();
615
        sw_avx = RSSI_Diversity(av_source, pudbm, bat_low);
616
  }
617
}
618
 
619
void Task_0_3(void)
620
{
621
  if (task_timer0_3) {
622
    cli();
623
        task_timer0_3 = 0;
624
        sei();
625
    sw_avx = RSSI_Diversity(av_source, pudbm, 0);
626
        if (tracking == TRACKING_MKCOCKPIT) Tracking_MKCockpit();
627
  }
628
}
629
 
630
void Task_0_4(void)
631
{
632
  if (task_timer0_4) {
633
    cli();
634
        task_timer0_4 = 0;
635
        sei();
636
    if (tracking == TRACKING_GPS) Tracking_GPS();
637
  }
638
}
639
 
640
void Task_0_5(void)
641
{
642
  lcd_BackgrLight_On();         // muss bei beliebiger Taste sofort eingeschaltet werden
643
  if (task_timer0_5) {
644
    cli();
645
        task_timer0_5 = 0;
646
        sei();
647
        lcd_BackgrLight();
648
  }
649
}
650
 
651
void Tasks_unvisible(void)
652
{
653
  Task_0_3();
654
  Task_0_4();
655
  Task_0_5();
656
  if (tracking == TRACKING_RSSI) Tracking_RSSI();
657
}