Subversion Repositories Projects

Rev

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

Rev Author Line No. Line
1932 - 1
/*****************************************************************************
2
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
3
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
4
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
5
 *   Copyright (C) 2011 Harald Bongartz                                      *
6
 *                                                                           *
7
 *   This program is free software; you can redistribute it and/or modify    *
8
 *   it under the terms of the GNU General Public License as published by    *
9
 *   the Free Software Foundation; either version 2 of the License.          *
10
 *                                                                           *
11
 *   This program is distributed in the hope that it will be useful,         *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
14
 *   GNU General Public License for more details.                            *
15
 *                                                                           *
16
 *   You should have received a copy of the GNU General Public License       *
17
 *   along with this program; if not, write to the                           *
18
 *   Free Software Foundation, Inc.,                                         *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
20
 *                                                                           *
21
 *                                                                           *
22
 *   Credits to:                                                             *
23
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
24
 *                          http://www.mikrokopter.de                        *
25
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
26
 *   Thomas Kaiser "thkais" for the original project. See                    *
27
 *                          http://www.ft-fanpage.de/mikrokopter/            *
28
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
29
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
30
 *                          http://www.mylifesucks.de/oss/c-osd/             *
31
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
32
 *****************************************************************************/
33
 
34
//############################################################################
35
//# HISTORY  osd.c
36
//#
37
//# 10.03.2013 OG
38
//# - fix: doppelte Degree-Anzeige in OSD_Element_CompassDegree()
39
//# - add: neuer Screen "MK-Status"
40
//# - add: 7 neue OSD-Flags
41
//# - chg: Screen-Refresh Zeit via timer2 (einstellbar durch define OSD_REFRESH_TIME)
42
//# - chg: mit define OSD_DEBUG_SCREEN kann ein zusaetzlicher Screen verwendet werden zum testen/entwickeln
43
//# - del: entfernt CFG2_HEIGHT_LIMIT in OSD_Element_AltitudeControl() (bis bessere Loesung gefunden ist)
44
//#
45
//# 08.03.2013 OG
46
//# - del: OSD_Screen_Element() und cleanup in osd.h
47
//# - add: OSD_Element_UpDown() (steigend/sinken via Pfeilen)
48
//# - chg: OSD_Element_UpDown() in Screen "General" und "Navigation" hinzugefuegt (rechts neben der Hoehenanzeige)
49
//# - chg: Screen "General" die Sat-Warnung wurde auf OSD_Element_Flag(OSD_FLAG_S0) geaendert
50
//# - chg: Anzeige von Flag 'nicht genug GPS-Sateliten' (OSD_FLAG_S0) auf "S!" geändert
51
//#
52
//# 07.03.2013 OG
53
//# - Hinweis bzgl. LowBatt-Anzeige in den Screens "General" und "Navigation":
54
//#      Es gibt zwei unabhängige LowBatt-Warnungen. 
55
//#      1. die PKT LowBatt-Warnung: sie arbeitet mit der im PKT hinterlegten
56
//#         LowBatt Spannung und stellt den Spannungswert inkl. der Einheit "V"
57
//#         invers dar wenn der Warnwert erreicht wurde (inkl. lautem PKT-Peepen) 
58
//#      2. die MK-LowBatt Warnung: hierbeit wird das Flag "BA" angezeigt wenn
59
//#         der MK eine LowBatt Warnung sendet
60
//#      Dadurch hat man nun zwei verschiedene LowBatt Warnungen die man auf Wunsch
61
//#      verschieden einstellen kann. Bei mir ist die PKT-LowBatt etwas niedriger  
62
//#      eingestellt als die MK-Warnung und bedeutet "es ist aller hoechste Zeit zu landen".
63
//#      Die Spannung der MK-LowBat ist ein wenig hoeher eingestellt und 
64
//#      zeigt mir "es ist bald Zeit zu landen". 
65
//# - del: Kommunikation zu FC - siehe Kommentare in osd()
66
//# - chg: Kommunikation zu NC - siehe Kommentare in osd()
67
//# - add: neuer Screen "Navigation"
68
//# - chg: Layout Screen "Statistics" - Einheiten um zwei Pixel nach rechts verschoben
69
//# - chg: Layout von Screen "General" modifiziert (u.a. xoffs,yoffs Pixelverschiebungen)
70
//# - add: OSD_FLAG_BA in Screen "General"
71
//# - add: die OSD_Element_xyz() Funktionen in osd.h aufgenommen
72
//# - chg: an verschiedenen Stellen die Char-Drawmode defines MNORMAL, MINVERS, usw. eingebaut
73
//# - del: Kompatibilitaetscode fuer "3D-Lage" ueber Hauptmenue entfernt 
74
//# - chg: die Funktionen OSD_Element_Switch() und OSD_Element_SwitchLabel() heissen 
75
//#        nun OSD_Element_Flag() und OSD_Element_Flag_Label()
76
//# - chg: die defines OSD_SWITCH_xy heissen jetzt OSD_FLAG_xy
77
//# - fix: letzte GPS-Koordinaten werden jetzt permanent Config.LastLatitude, Config.LastLongitude gespeichert 
78
//#
79
//# 03.03.2013 OG
80
//# - add: delay in Mainloop von osd() um springende Werte abzudaempfen (TEST)
81
//# - add: Startverzoegerung der Screens bis NaviData sich etwas stabilisiert hat (TEST)
82
//# - add: OSD Startup Message "connecting MK..."
83
//# - add: 'Emergency Landing' (EL) Anzeige in Screen "General"
84
//# - del: OUT1/OUT2 Anzeige in Screen "General"
85
//# - add: RC-Quality in Screen "General"
86
//# - add: func: draw_symbol_rc() (alternative RC-Quality Symbol)
87
//# - fix: Hoehenanzeige fuer Screens "OSD0" und "OSD1"
88
//# - fix: OSD_Element_SwitchLabel() angepasst fuer x=0 und y=0
89
//# - add: OSD_Element_Switch/Label() erweitert um OSD_SWITCH_FS
90
//# - fix: Screen-Redraw nach OSD_Timeout() und anderen Fehlermeldungen
91
//# - chg: messages.c: STATS_ITEM_0 bis STATS_ITEM_6 angepasst (1 char kuerzer)
92
//# - chg: Layout von OSD_Info() - mehr background-clear und etwas kleiner
93
//#
94
//# 02.03.2013 OG
95
//# - chg: keine internal func in Screen's wegen warnings bei anderen
96
//# - del: Screen "OSD3"
97
//# - fix: Hoehenanzeige in Screen "General" (Minuszeichen)
98
//# - add: MK LowBat Warning in Screen "General"
99
//# - add: neues Degree Symbol (als func) in Screen General (kleiner als das Char 0x1E)
100
//# - add: weitere Flags in OSD_Element_Flag()
101
//#
102
//# 01.03.2013 OG
103
//# - Reskrukturierung Code (+ neuer OSD-Screens und einiges mehr) 
104
//############################################################################
105
 
106
 
107
//############################################################################
108
//# HINWEISE:
109
//#
110
//# 1. define: OSD_DEMO
111
//#    mit define OSD_DEMO wird ein Demo-Modus bei den neuen Screens einge-
112
//#    schaltet - damit werden u.a. alle Flag's angezeigt fuer Scree-Fotos
113
//#
114
//# 2. define: OSD_DEBUG_SCREEN
115
//#    mit diesem define wird ein zusaetzlicher Screen "Debug" einkompiliert
116
//#    fuer Test / Experimente / Debug von OSD-Elementen
117
//#
118
//# 3. Informationen zum Display
119
//#    DOG: 128 x 64 Pixel with 6x8 Font => 21 x 8
120
//############################################################################
121
 
122
 
123
#include "../cpu.h"
124
#include <avr/io.h>
125
#include <inttypes.h>
126
#include <stdlib.h>
127
#include <avr/pgmspace.h>
128
#include <util/delay.h>
129
 
130
#include "../main.h"
131
#include "../osd/osd.h"
132
#include "../lcd/lcd.h"
133
#include "../timer/timer.h"
134
#include "../uart/usart.h"
135
#include "../eeprom/eeprom.h"
136
#include "../messages.h"
137
#include "../parameter.h"
138
#include "../sound/pwmsine8bit.h"
139
#include "../mk-data-structs.h"
140
 
141
 
142
//#define OSD_DEMO                              // zeigt Demo-Daten in den OSD-Screens (sofern vom Screen unterstuetzt)
143
//#define OSD_DEBUG_SCREEN              // zusaetzlichen Debug-Screen aktivieren
144
 
145
#define OSD_REFRESH_TIME        45      // Screen Refresh; ein Wert von 100 entspricht ca. 1 Sekunde (Steuerung via timer2)
146
 
147
#define COSD_WASFLYING          4
148
#define TIMEOUT                         200     // 2 sec 
149
 
150
 
151
// Hier Höhenanzeigefehler Korrigieren
152
#define AltimeterAdjust 1.5
153
 
154
 
155
// global definitions and global vars
156
NaviData_t                      *naviData;
157
mk_param_struct_t       *mk_param_struct;
158
uint8_t                         Flags_ExtraConfig;
159
uint8_t                         Flags_GlobalConfig;
160
uint8_t                         Flags_GlobalConfig3;
161
unsigned char           Element;
162
uint16_t                        heading_home;
163
uint8_t                         drawmode;
164
 
165
// flags from last round to check for changes
166
uint8_t  old_FCFlags            = 0;
167
uint8_t  old_AngleNick          = 0;
168
uint8_t  old_AngleRoll          = 0;
169
uint16_t old_hh                         = 0;
170
 
171
// stats for after flight
172
int16_t  max_Altimeter          = 0;
173
uint16_t max_GroundSpeed        = 0;
174
int16_t  max_Distance           = 0;
175
uint8_t  min_UBat                       = 255;
176
uint16_t max_FlyingTime         = 0;
177
uint16_t max_Current            = 0;
178
uint16_t max_Capacity           = 0;
179
 
180
// cache old vars for blinking attribute, checkup is faster than full
181
// attribute write each time
182
volatile uint8_t last_UBat                      = 255;
183
volatile uint8_t last_RC_Quality        = 255;
184
 
185
volatile uint16_t ftimer        = 0;
186
volatile uint8_t OSD_active;
187
 
188
uint8_t Vario_Beep_Up                           = 0;
189
uint8_t Vario_Beep_Down                         = 0;
190
uint8_t Vario_Beep_Up_Interval          = 9;
191
uint8_t Vario_Beep_Down_Interval        = 6;
192
uint8_t Vario_Threshold                         = 0;
193
uint8_t Vario_Threshold_Value           = 7;
194
uint8_t OldWP                                           = 0;
195
uint8_t NextWP                                          = 0;
196
 
197
 
198
 
199
//char* rose = "-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W";
200
const char rose[48] PROGMEM = {
201
        0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S',
202
        0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O',
203
        0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N',
204
        0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W',
205
};
206
 
207
// the center is char 19 (north), we add the current heading in 8th
208
// which would be 22.5 degrees, but float would bloat up the code
209
// and *10 / 225 would take ages... so we take the uncorrect way
210
 
211
const char str_NE[] PROGMEM = "NE";
212
const char str_E[] PROGMEM  = "E ";
213
const char str_SE[] PROGMEM = "SE";
214
const char str_S[] PROGMEM  = "S ";
215
const char str_SW[] PROGMEM = "SW";
216
const char str_W[] PROGMEM  = "W ";
217
const char str_NW[] PROGMEM = "NW";
218
const char str_N[] PROGMEM  = "N ";
219
const char *directions_p[8] PROGMEM = {
220
        str_NE,
221
        str_E,
222
        str_SE,
223
        str_S,
224
        str_SW,
225
        str_W,
226
        str_NW,
227
        str_N
228
};
229
 
230
 
231
#define MAX_CELL_VOLTAGE 43 // max cell voltage for LiPO
232
#define MIN_CELL_VOLTAGE 32 // min cell voltage for LiPO
233
 
234
// Flags
235
GPS_Pos_t last5pos[7];
236
uint8_t COSD_FLAGS2                     = 0;
237
volatile uint8_t error                  = 0;
238
uint8_t cells                                   = 0;
239
uint8_t BattLowVoltageWarning   = 0;
240
uint8_t CellIsChecked                   = 0;
241
uint8_t AkkuWarnThreshold               = 0;
242
uint16_t duration                               = 0;
243
 
244
 
245
 
246
//###########################################################
247
//###########################################################
248
 
249
//--------------------------------------------------------------
250
//--------------------------------------------------------------
251
void variobeep(int16_t vario)
252
{
253
  { //start Beep
254
 
255
    if (vario >0 )          // MK steigt
256
      {
257
       Vario_Beep_Down = 0;                 // Down Beep freischalten
258
       Vario_Threshold++;
259
 
260
       if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value))
261
        {
262
//         set_beep ( 100, 0xffff, BeepNormal);
263
         duration = 52 -vario;
264
//         if (duration =0); duration = 1;
265
 
266
//         write_ndigit_number_u (0,6,duration,5,0);
267
 
268
         playTone(300+vario*2,duration,Config.Volume);
269
//         playTone(300,duration,volume);
270
         Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
271
        }
272
       Vario_Beep_Up++;                 // Interval hochzählen in dem nicht gepiept wird
273
       if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0;
274
      }
275
 
276
    if (vario <0)          // MK fällt
277
      {
278
       Vario_Beep_Up = 0;                 // Up Beep freischalten
279
       Vario_Threshold++;
280
       if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value))
281
        {
282
         duration = 50 -vario;
283
//         write_ndigit_number_u (0,7,duration,5,0);
284
//         if (duration < vario) ; duration = 0;
285
//         playTone(300,50,volume);
286
 
287
 
288
         playTone(300+vario*2,duration,Config.Volume);
289
         Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
290
        }
291
       Vario_Beep_Down++;                 // Interval hochzählen in dem nicht gepiept wird
292
       if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0;
293
      }
294
 
295
    if (vario == 0) Vario_Threshold = 0;  //Startverzögerung löschen
296
  }  // end Beep
297
 
298
}
299
 
300
 
301
//--------------------------------------------------------------
302
// Diese Funktion Beept unabhaengig von der Einstellung Config.OSD_VarioBeep
303
// Aufruf ggf. mit: if( Config.OSD_VarioBeep ) Beep_Vario();
304
//
305
// Ansonten:
306
// -> hier noch aufräumen in Zusammenhang mit func variobeep()
307
//--------------------------------------------------------------
308
void Beep_Vario(void)
309
{
310
        if ( (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN) && (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL))
311
    { //start Beep
312
      if (naviData->Variometer <0)          // MK fällt
313
        {
314
         Vario_Beep_Up = 0;                 // Up Beep freischalten
315
         Vario_Threshold++;
316
         if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value))
317
          {
318
 
319
          if (!Config.HWSound) set_beep ( 300, 0xffff, BeepNormal);
320
               else  variobeep(naviData->Variometer);
321
 
322
           Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
323
          }
324
         Vario_Beep_Down++;                 // Interval hochzählen in dem nicht gepiept wird
325
         if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0;
326
        }
327
 
328
      if (naviData->Variometer == 0) Vario_Threshold = 0;  //Startverzögerung löschen
329
 
330
      if (naviData->Variometer >0 )          // MK steigt
331
        {
332
         Vario_Beep_Down = 0;                 // Down Beep freischalten
333
         Vario_Threshold++;
334
 
335
         if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value))
336
          {
337
           if (!Config.HWSound) set_beep ( 100, 0xffff, BeepNormal);
338
           else  variobeep(naviData->Variometer);
339
           Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
340
          }
341
         Vario_Beep_Up++;                 // Interval hochzählen in dem nicht gepiept wird
342
         if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0;
343
        }
344
    }  // end Beep
345
}            
346
 
347
 
348
 
349
//--------------------------------------------------------------
350
// Quelle Mikrokopter FC-Software Holger + Ingo
351
//--------------------------------------------------------------
352
void CheckMKLipo(void)
353
{
354
    if(Config.MK_LowBat < 50) // automatische Zellenerkennung
355
    {
356
       if (CellIsChecked <= 2)   //Nur beim Start 1x prüfen
357
       {
358
                // up to 6s LiPo, less than 2s is technical impossible
359
                for(cells = 2; cells < 7; cells++)
360
                {
361
                        if(naviData->UBat < cells * MAX_CELL_VOLTAGE) break;
362
                }
363
                BattLowVoltageWarning = cells * Config.MK_LowBat;
364
                CellIsChecked++;
365
       }
366
    }
367
    else BattLowVoltageWarning = Config.MK_LowBat;
368
 
369
    if (naviData->UBat < BattLowVoltageWarning)
370
    {
371
        if (AkkuWarnThreshold <= 4) AkkuWarnThreshold++;
372
        else
373
        { //Beeper ein
374
                set_beep ( 1000, 0x0020, BeepSevere);
375
//               BeepTime = 3000;
376
//               BeepMuster = 0x0020;
377
        }
378
    }
379
}
380
 
381
 
382
//--------------------------------------------------------------
383
// convert the <heading> gotton from NC into an index
384
uint8_t heading_conv (uint16_t heading)
385
{
386
        if (heading > 23 && heading < 68)
387
                return 0;               //direction = "NE";
388
        else if (heading > 67 && heading < 113)
389
                return 1;               //direction = "E ";
390
        else if (heading > 112 && heading < 158)
391
                return 2;               //direction = "SE";
392
        else if (heading > 157 && heading < 203)
393
                return 3;               //direction = "S ";
394
        else if (heading > 202 && heading < 248)
395
                return 4;               //direction = "SW";
396
        else if (heading > 247 && heading < 293)
397
                return 5;               //direction = "W ";
398
        else if (heading > 292 && heading < 338)
399
                return 6;               //direction = "NW";
400
 
401
        return 7;       //direction = "N ";
402
}
403
 
404
 
405
//--------------------------------------------------------------
406
// draw a compass rose at <x>/<y> for <heading>
407
void draw_compass (uint8_t x, uint8_t y, uint16_t heading)
408
{
409
        uint8_t front = 19 + (heading / 22);
410
        for (uint8_t i = 0; i < 9; i++)
411
                lcd_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), 0);
412
}
413
 
414
 
415
//--------------------------------------------------------------
416
// variometer
417
// x, y in Pixel!
418
//--------------------------------------------------------------
419
void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
420
{
421
        lcd_rect (x, y - ((hight) / 2), width, hight, 1);
422
        lcd_frect (x + 1, y - ((hight) / 2) + 1, width - 2, hight - 2, 0);
423
        lcd_line (x, y, x + width, y, 1);
424
 
425
        if (variometer > 0)  // steigend
426
        {
427
                switch (variometer / 5)
428
                {
429
                        case 0:
430
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
431
                        break;
432
 
433
                        case 1:
434
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
435
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
436
                        break;
437
 
438
                        case 2:
439
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
440
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
441
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
442
                        break;
443
 
444
                        default:
445
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);  //  1 >  4
446
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
447
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
448
                                lcd_frect (x + 1, y - 6, 8, 1, 1);                      // 15 >
449
                        break;
450
                }
451
        }
452
        else if (variometer < 0)  // fallend
453
        {
454
                switch ((variometer) / -5)
455
                {
456
                        case 0:
457
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
458
                        break;
459
 
460
                        case 1:
461
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
462
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
463
                        break;
464
 
465
                        case 2:
466
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
467
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
468
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
469
                        break;
470
 
471
                        default:
472
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
473
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
474
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
475
                                lcd_frect (x + 1, y + 5, 8, 1, 1);                      // -15 >
476
                        break;
477
                }
478
        }
479
}
480
 
481
 
482
//--------------------------------------------------------------
483
// variometer 2
484
//
485
// x, y in Pixel
486
// x, y top, left
487
//--------------------------------------------------------------
488
/*
489
void draw_variometer2( uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
490
{
491
        uint8_t max = 5;        // max: 5 m/sec == 100%
492
 
493
        lcd_rect (x, y, width, hight, 1);
494
        lcd_frect(x + 1, y + 1, width - 2, hight - 2, 0);
495
        lcd_line (x, y + ((hight) / 2), x + width, y + ((hight) / 2), 1);
496
 
497
}
498
*/
499
 
500
 
501
//--------------------------------------------------------------
502
// Home symbol
503
// draw Homesymbol at <x>/<y>
504
//--------------------------------------------------------------
505
void draw_homesymbol (uint8_t x, uint8_t y)
506
{
507
        x *= 6;
508
        y *= 8;
509
        y += 7;
510
 
511
        lcd_plot (x,y-4,1);
512
        lcd_line (x+1,y-1,x+1,y-5,1);
513
        lcd_plot (x+2,y-6,1);
514
        lcd_plot (x+3,y-7,1);
515
        lcd_plot (x+4,y-6,1);
516
        lcd_line (x+5,y-1,x+5,y-5,1);
517
        lcd_plot (x+6,y-4,1);
518
        lcd_plot (x+3,y-1,1);
519
        lcd_plot (x+3,y-2,1);
520
        lcd_line (x+1,y,x+5,y,1);
521
 
522
}
523
 
524
//--------------------------------------------------------------
525
// Target symbol
526
// draw Targetsymbol at <x>/<y>
527
//--------------------------------------------------------------
528
void draw_targetsymbol (uint8_t x, uint8_t y)
529
{
530
        x *= 6;
531
        y *= 8;
532
        y += 7;
533
 
534
        lcd_circle (x+3, y-3, 4, 1);
535
        lcd_line (x,y-3,x+6,y-3,1);
536
        lcd_line (x+3,y,x+3,y-6,1);
537
        lcd_circle (x+3, y-3, 2, 1);
538
}
539
 
540
 
541
//--------------------------------------------------------------
542
// Degree symbol
543
// draw Degreesymbol at <x>/<y>
544
//
545
// Ein etwas kleineres Degeree als Char 0x1E
546
//--------------------------------------------------------------
547
void draw_symbol_degree (uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs)
548
{
549
        x *= 6;
550
        y *= 8;
551
            lcd_rect (x+1+xoffs, y+yoffs, 2, 2, 1);
552
}
553
 
554
 
555
//--------------------------------------------------------------
556
// RC symbol
557
// alternatives Symbol fuer RC-Quality
558
//--------------------------------------------------------------
559
void draw_symbol_rc (uint8_t x, uint8_t y)
560
{
561
        x *= 6;
562
        y *= 8;
563
                y += 1;
564
                x += 1;
565
 
566
        lcd_plot  ( x+3, y+4, 1);
567
        lcd_line  ( x+2, y+2, x+4, y+2, 1);
568
        lcd_line  ( x+1, y+0, x+5, y+0, 1);
569
}
570
 
571
 
572
//--------------------------------------------------------------
573
void print_position (void)
574
{
575
        lcd_cls ();
576
        lcd_puts_at(0, 0, strGet(START_LASTPOS1), 2);   // Breitengr  Längengr
577
        lcd_puts_at(12, 7, strGet(ENDE), 0);
578
        uint8_t ij =0;
579
 
580
        for(ij=0;ij<6;ij++)
581
        {
582
                uint32_t lon = last5pos[ij].Latitude;
583
                write_ndigit_number_u (1, ij+1, (uint16_t)(lon/10000000), 2, 0,0);
584
                lcd_printp_at (3, ij+1, PSTR("."), 0);
585
                write_ndigit_number_u (4, ij+1, (uint16_t)((lon/1000) % 10000), 4, 1,0);
586
                write_ndigit_number_u (8, ij+1, (uint16_t)((lon/10) % 100), 2, 1,0);
587
 
588
                uint32_t lat = last5pos[ij].Longitude;
589
                write_ndigit_number_u (12, ij+1, (uint16_t)(lat/10000000), 2, 0,0);
590
                lcd_printp_at (14, ij+1, PSTR("."), 0);
591
                write_ndigit_number_u (15, ij+1, (uint16_t)((lat/1000) % 10000), 4, 1,0);
592
                write_ndigit_number_u (19, ij+1, (uint16_t)((lat/10) % 100), 2, 1,0);
593
        }
594
 
595
        while (!get_key_press (1 << KEY_ESC))
596
                timer = TIMEOUT;
597
 
598
        get_key_press(KEY_ALL);
599
        lcd_cls();
600
}
601
 
602
 
603
//--------------------------------------------------------------
604
void Show_LastPosition(void)
605
{
606
        lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
607
        lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
608
        lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
609
        uint32_t lon = last5pos[0].Latitude;
610
        write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0);
611
        lcd_printp_at (3, 6, PSTR("."), 0);
612
        write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0);
613
        write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0);
614
 
615
        uint32_t lat = last5pos[0].Longitude;
616
        write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0);
617
        lcd_printp_at (14, 6, PSTR("."), 0);
618
        write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0);
619
        write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0);
620
 
621
}
622
 
623
 
624
//--------------------------------------------------------------
625
void OSD_Timeout(uint8_t flag)
626
{
627
 
628
//      uint8_t flag;
629
        uint8_t tmp_dat;
630
//      flag = 0;
631
        timer = TIMEOUT;
632
        // disable OSD Data from NC
633
//      RS232_request_mk_data (1, 'o', 0);
634
//      tmp_dat = 0;
635
//      SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
636
 
637
        mode = 0;
638
        rxd_buffer_locked = FALSE;
639
 
640
 
641
        // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
642
        if( flag )
643
        {
644
                // Falls Spannungswarnung an war Beeper aus//
645
 
646
                set_beep ( 0, 0, BeepOff);
647
 
648
                lcd_cls ();
649
                WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
650
                lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);                                                // ERROR: Datenverlust
651
                lcd_puts_at(0, 2, strGet(OSD_POS1), 0);                                                 // Letzte bekannte
652
                lcd_puts_at(0, 3, strGet(OSD_POS2), 0);                                                 // Position gespeichert.
653
                lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);                                   // Breitengr  Längengr
654
//              lcd_puts_at(12, 7, strGet(ENDE), 0);
655
//              lcd_puts_at(19, 7, strGet(OK), 0);
656
//              if (OSD_RCErrorbeep==true)
657
//              {
658
                        set_beep ( 250, 0x0040, BeepNormal);
659
//              }
660
 
661
                uint32_t lon = last5pos[0].Latitude;
662
                write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0);
663
                lcd_printp_at (3, 6, PSTR("."), 0);
664
                write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0);
665
                write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0);
666
 
667
                uint32_t lat = last5pos[0].Longitude;
668
                write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0);
669
                lcd_printp_at (14, 6, PSTR("."), 0);
670
                write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0);
671
                write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0);
672
 
673
//              while (!get_key_press (1 << KEY_ENTER));
674
//              _delay_ms(1000);
675
                timer = TIMEOUT;
676
//              lcd_cls();
677
//              return;
678
        }
679
        else
680
        {
681
                lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
682
                Show_LastPosition();
683
                if (Config.OSD_RCErrorbeep==true) set_beep ( 200, 0x0080, BeepNormal);
684
//              _delay_ms(2000);
685
        }
686
 
687
    rxd_buffer_locked = FALSE;  // 07.03.2013 OG: fix
688
                                                        //   es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den 
689
                                                        //   OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt'
690
 
691
        SwitchToNC();
692
 
693
        mode = 'O';
694
 
695
        // disable debug...
696
//      RS232_request_mk_data (0, 'd', 0);
697
        tmp_dat = 0;
698
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
699
 
700
        // request OSD Data from NC every 100ms
701
//      RS232_request_mk_data (1, 'o', 100);
702
        tmp_dat = 10;
703
        SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
704
 
705
        //_delay_ms(100);
706
        //rxd_buffer_locked = FALSE;
707
}
708
 
709
 
710
 
711
 
712
//-----------------------------------------------------------
713
//
714
void lcd_o_circle (uint16_t x, uint16_t y, int16_t breite, uint8_t mode, int8_t xoffs, int8_t yoffs)
715
{
716
        breite *= 6;
717
        int16_t radius = breite / 2;
718
        x += 2;
719
        x *= 6;
720
        x += 2;
721
        y += 1;
722
        y *= 8;
723
        y += 3;
724
 
725
        // 04.03.2012 OG: chg: x-radius von -3 auf -2 (runder auf dem display)
726
        //lcd_ellipse (x, y, radius - 3, radius - 5, mode);
727
        lcd_ellipse( x+xoffs, y+yoffs, radius - 2, radius - 5, mode);
728
}
729
 
730
 
731
//-----------------------------------------------------------
732
// lcd_o_circ_line( x, y, breite, deg, rOffset, mode)
733
//
734
// x, y   : in Chars
735
// breite : in Chars
736
// deg    : in Pixel
737
// rOffset: Beeinflusst den Schluss der Linie zum Huellkreis 
738
//          0 = Standard
739
//          >0 naeher zum Huellkreis
740
//          <0 entfernter vom Huellkreis
741
// mode   : siehe: lcd_ellipse_line()
742
//-----------------------------------------------------------
743
void lcd_o_circ_line( uint16_t x, uint16_t y, uint8_t breite, uint16_t deg, int8_t rOffset, uint8_t mode, int8_t xoffs, int8_t yoffs)
744
{
745
        breite *= 6;
746
        int16_t radius = breite / 3;
747
        x += 2;
748
        x *= 6;
749
        x += 2;
750
        y += 1;
751
        y *= 8;
752
        y += 3;
753
 
754
    // 04.03.2013 OG: der Radius kann mit rOffset >0 vergroessert werden um zum Kreis aufzuschliessen
755
        lcd_ellipse_line( x+xoffs, y+yoffs, radius+rOffset, radius+rOffset, deg, mode);
756
}
757
 
758
 
759
//--------------------------------------------------------------
760
void draw_icon_home(uint8_t x, uint8_t y)
761
{
762
        //lcd_plot( x+0, y+0, 1);                       // Referenz 0,0
763
        lcd_rect( x+0, y+5, 10, 8, 1);          // Mitte
764
        lcd_line( x+5, y+0, x+0, y+5, 1);       // Dach Links
765
        lcd_line( x+5, y+0, x+10, y+5, 1);  // Dach Rechts
766
        lcd_rect( x+4, y+10, 2, 3, 1);          // Tuere
767
 
768
}
769
 
770
 
771
//--------------------------------------------------------------
772
void draw_icon_sat(uint8_t x, uint8_t y)
773
{
774
        //lcd_plot( x+0, y+0, 1);                        // Referenz 0,0
775
        lcd_rect( x+0, y+2, 4, 2, 1);            // linker Fluegel
776
        lcd_rect( x+8, y+2, 4, 2, 1);            // rechter Fluegel
777
        lcd_rect( x+4, y+0, 4, 6, 1);            // Mitte, oben
778
        lcd_line( x+6, y+7, x+2, y+11, 1);       // Strahl Links
779
        lcd_line( x+6, y+7, x+10, y+11, 1);  // Strahl Rechts
780
        lcd_line( x+1, y+12, x+11, y+12, 1); // Strahl Unten
781
}
782
 
783
 
784
//--------------------------------------------------------------
785
void draw_icon_battery(uint8_t x, uint8_t y)
786
{
787
        //lcd_plot( x+0, y+0, 1);                       // Referenz 0,0
788
    lcd_rect( x+2, y+0, 2, 2,  1);              // der kleine Knubbel oben
789
    lcd_rect( x+0, y+2, 6, 15, 1);              // body
790
}
791
 
792
 
793
 
794
//##############################################################
795
//# OSD-ELEMENTS 
796
//##############################################################
797
 
798
//--------------------------------------------------------------
799
// OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs, yoffs)
800
//
801
// xC, yC               : x,y in Characters
802
// item                 : OSD_FLAG_AH, OSD_FLAG_PH, usw.
803
// lOn                  : true / false
804
// xoffs,yoffs  : x,y Pixelverschiebung
805
//--------------------------------------------------------------
806
void OSD_Element_Flag_Label( uint8_t xC, uint8_t yC, uint8_t item, uint8_t lOn, int8_t xoffs, int8_t yoffs)
807
{
808
        int8_t  x = (xC*6)-2;
809
        int8_t  y = (yC*8)-1;
810
        uint8_t w = 14;
811
        uint8_t h = 8;
812
 
813
        const char *labels[OSD_FLAG_COUNT] =
814
        {
815
                PSTR("AH"),  // OSD_FLAG_AH  Altitue Hold
816
                PSTR("PH"),  // OSD_FLAG_PH  Position Hold
817
                PSTR("CF"),  // OSD_FLAG_CF  Care Free
818
                PSTR("CH"),  // OSD_FLAG_CH  Coming Home
819
                PSTR("o1"),  // OSD_FLAG_O1  Out1
820
                PSTR("o2"),  // OSD_FLAG_O2  Out2
821
                PSTR("BA"),  // OSD_FLAG_BA  LowBat warning (MK)
822
                PSTR("CA"),  // OSD_FLAG_CA  Calibrate
823
                PSTR("ST"),  // OSD_FLAG_ST  Start
824
                PSTR("MR"),  // OSD_FLAG_MR  Motor Run
825
                PSTR("FY"),  // OSD_FLAG_FY  Fly
826
                PSTR("EL"),  // OSD_FLAG_EL  Emergency Landing
827
                PSTR("FS"),      // OSD_FLAG_FS  RX Failsave Active
828
                PSTR("GP"),  // OSD_FLAG_GP  GPS Ok
829
                PSTR("S!"),  // OSD_FLAG_S0  GPS-Sat not ok (GPS NOT ok)
830
                PSTR("TU"),  // OSD_FLAG_TU  Vario Trim Up
831
                PSTR("TD"),  // OSD_FLAG_TD  Vario Trim Down
832
                PSTR("FR"),  // OSD_FLAG_FR  Free
833
                PSTR("RL"),  // OSD_FLAG_RL  Range Limit
834
                PSTR("SL"),  // OSD_FLAG_SL  No Serial Link
835
                PSTR("TR"),  // OSD_FLAG_TR  Target Reached
836
                PSTR("MC")   // OSD_FLAG_MC  Manual Control             
837
        };
838
 
839
        //lcd_plot( x-2, y-2, 1);                                               // Referenz
840
 
841
        if( yC==0 )     {       y = 0;  h = 7;  }
842
        if( xC==0 )     {       x = 0;  w = 12; }
843
 
844
        if( lOn )
845
        {              
846
        lcd_frect( x+xoffs, y+yoffs, w, h, 1);                                          // Filler
847
                lcdx_printp_at(  xC, yC, labels[item], MINVERS, xoffs,yoffs);   // Label
848
    }
849
    else
850
        {              
851
        lcd_frect( x+xoffs, y+yoffs, w, h, 0);                                          // clear
852
    }    
853
}
854
 
855
 
856
//--------------------------------------------------------------
857
//--------------------------------------------------------------
858
void OSD_Element_Flag( uint8_t xC, uint8_t yC, uint8_t item, int8_t xoffs, int8_t yoffs)
859
{
860
        uint8_t lOn = 0;
861
 
862
        // FC_StatusFlags 0.88
863
        switch( item )
864
    {
865
        // Altitue Hold
866
        case OSD_FLAG_AH :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL);
867
                                                        break;
868
 
869
                // Position Hold
870
        case OSD_FLAG_PH :      lOn = (naviData->NCFlags & NC_FLAG_PH);
871
                                                        break;
872
 
873
                // Coming Home
874
        case OSD_FLAG_CH :      lOn = (naviData->NCFlags & NC_FLAG_CH);
875
                                                        break;
876
 
877
                // Care Free
878
        case OSD_FLAG_CF :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE);
879
                                                        break;
880
 
881
                // Out1
882
        case OSD_FLAG_O1 :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE);
883
                                                        break;
884
 
885
                // Out2
886
        case OSD_FLAG_O2 :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT2_ACTIVE);
887
                                                        break;
888
 
889
                //  LowBat warning (MK)
890
        case OSD_FLAG_BA :      lOn = (naviData->FCStatusFlags & FC_STATUS_LOWBAT);
891
                                                        break;
892
 
893
                //  Calibrate
894
        case OSD_FLAG_CA :      lOn = (naviData->FCStatusFlags & FC_STATUS_CALIBRATE);
895
                                                        break;
896
 
897
                //  Start
898
        case OSD_FLAG_ST :      lOn = (naviData->FCStatusFlags & FC_STATUS_START);
899
                                                        break;
900
 
901
                //  Motor Run
902
        case OSD_FLAG_MR :      lOn = (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN);
903
                                                        break;
904
 
905
                //  Fly
906
        case OSD_FLAG_FY :      lOn = (naviData->FCStatusFlags & FC_STATUS_FLY);
907
                                                        break;
908
 
909
                //  Emergency Landing
910
        case OSD_FLAG_EL :      lOn = (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING);
911
                                                        break;
912
 
913
                //  RC Failsave Active
914
        case OSD_FLAG_FS :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE);
915
                                                        break;
916
 
917
                //  GPS ok
918
        case OSD_FLAG_GP :      lOn = (naviData->NCFlags & NC_FLAG_GPS_OK);
919
                                                        break;
920
 
921
                //  GPS-Sat not ok (GPS NOT ok)
922
        case OSD_FLAG_S0 :      lOn = !(naviData->NCFlags & NC_FLAG_GPS_OK);
923
                                                        break;
924
 
925
                //  Vario Trim Up
926
        case OSD_FLAG_TU :      lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_UP);
927
                                                        break;
928
 
929
                //  Vario Trim Down
930
        case OSD_FLAG_TD :      lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_DOWN);
931
                                                        break;
932
 
933
                //  Free
934
        case OSD_FLAG_FR :      lOn = (naviData->NCFlags & NC_FLAG_FREE);
935
                                                        break;
936
 
937
                //  Range Limit
938
        case OSD_FLAG_RL :      lOn = (naviData->NCFlags & NC_FLAG_RANGE_LIMIT);
939
                                                        break;
940
 
941
                //  No Serial Link
942
        case OSD_FLAG_SL :      lOn = (naviData->NCFlags & NC_FLAG_NOSERIALLINK);
943
                                                        break;
944
 
945
                //  Target Reached
946
        case OSD_FLAG_TR :      lOn = (naviData->NCFlags & NC_FLAG_TARGET_REACHED);
947
                                                        break;
948
 
949
                //  Manual Control
950
        case OSD_FLAG_MC :      lOn = (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL);
951
                                                        break;
952
 
953
        }
954
 
955
        OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs,yoffs);
956
}
957
 
958
 
959
//--------------------------------------------------------------
960
// OSD_Element_AltitudeControl( x, y)
961
//--------------------------------------------------------------
962
void OSD_Element_AltitudeControl( uint8_t x, uint8_t y )
963
{
964
                //---------------------------------------------------------
965
                // 10.03.2013 OG: 
966
                //   CFG2_HEIGHT_LIMIT im Augenblick nicht unterstuetzt
967
                //   Siehe Anmerkungen in osd()
968
                //---------------------------------------------------------
969
                /*
970
                if (Flags_ExtraConfig & CFG2_HEIGHT_LIMIT)
971
                {
972
                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
973
                                lcd_puts_at (x, y, strGet(OSD_ALTI_1), 0);      // Höhe begr.
974
                        else
975
                                lcd_puts_at (x, y, strGet(OSD_ALTI_0), 0);      // Höhe aus
976
                }
977
                else
978
                {
979
                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
980
                                lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0);     // Vario Höhe
981
                        else
982
                                lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0);     // Vario aus
983
                }
984
                */
985
 
986
                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
987
                                lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0);     // Vario Höhe
988
                        else
989
                                lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0);     // Vario aus
990
 
991
}
992
 
993
 
994
//--------------------------------------------------------------
995
// Anzeige von Steigen / Sinken
996
//--------------------------------------------------------------
997
void OSD_Element_UpDown( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs)
998
{
999
        x = (x*6) + xoffs;
1000
        y = (y*8) + yoffs;
1001
 
1002
    lcd_frect( x, y, 6, 7, 0);                  // clear
1003
 
1004
    if( naviData->Variometer > 2 )              // steigen mehr als 0.2 m/sec (ein guter Wert muss noch in der Praxis ermittelt werden)
1005
    {
1006
                lcd_line( x+2, y+0, x+0, y+2, 1);
1007
                lcd_line( x+2, y+0, x+4, y+2, 1);
1008
    }
1009
    else if( naviData->Variometer < -2 )        // sinken  mehr als 0.2 m/sec
1010
    {
1011
                lcd_line( x+2, y+6, x+0, y+4, 1);
1012
                lcd_line( x+2, y+6, x+4, y+4, 1);
1013
    }
1014
 
1015
}
1016
 
1017
 
1018
//--------------------------------------------------------------
1019
// OSD_Element_Altitude( x, y, nStyle)
1020
// nStyle entspricht dem ehemaligen 'Mode'
1021
//--------------------------------------------------------------
1022
void OSD_Element_Altitude( uint8_t x, uint8_t y, uint8_t nStyle )
1023
{
1024
        switch( nStyle )
1025
        {
1026
                case 0 :
1027
                case 1 :        //note:lephisto:according to several sources it's /30
1028
                    if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))        // above 10m only write full meters
1029
                             write_ndigit_number_s (x, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL);
1030
                    else        // up to 10m write meters.dm
1031
                             write_ndigit_number_s_10th (x, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MNORMAL);
1032
 
1033
                    lcd_printp_at (x+4, y, PSTR("m"), MNORMAL);
1034
                    lcd_putc (x+5, y, 0x09, 0);  // Hoehensymbol
1035
                    break;
1036
 
1037
                case 2 :        //note:lephisto:according to several sources it's /30
1038
                        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))        // above 10m only write full meters
1039
                        write_ndigit_number_s (x+4, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MBIG);
1040
                        else        // up to 10m write meters.dm
1041
                        write_ndigit_number_s_10th (x+4, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MBIG);
1042
                        lcd_putc( x+8, y, 'm', MBIG);
1043
                        lcd_printp_at (x, y, PSTR("Höhe"), MNORMAL);
1044
                        break;
1045
        }      
1046
}
1047
 
1048
 
1049
//--------------------------------------------------------------
1050
// fuer: Config.OSD_LipoBar==1
1051
//--------------------------------------------------------------
1052
void OSD_Element_BatteryLevel_Bar( uint8_t x, uint8_t y )
1053
{
1054
        uint16_t Balken = 0;
1055
 
1056
        drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0);
1057
 
1058
        if( cells > 0 )  // LipobargraphAnzeige nur wenn Anzahl der Lipozellen bekannt sind
1059
        {
1060
        write_ndigit_number_u (x+6, y, cells, 1, 0, drawmode);
1061
        lcd_printp_at (x+7, y, PSTR("S"), drawmode);
1062
 
1063
            if( cells==3 )
1064
        {
1065
                lcd_rect(x*6, y*8, 28, 7, 1);  // Rahmen
1066
            Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/12;
1067
            if((Balken > 0) && (Balken <28)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1);         // Fuellung
1068
            if(Balken <= 26) lcd_frect(Balken+(x*6)+1, (y*8)+1, 26-Balken, 5, 0);                       // loeschen
1069
        }
1070
 
1071
            if( cells==4 ||cells==5 )
1072
        {
1073
           lcd_rect(x*6, y*8, 30, 7, 1);  // Rahmen
1074
           if (cells == 4) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/15;
1075
           if (cells == 5) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/19;
1076
           if ((Balken > 0) && (Balken <=29)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1);        // Fuellung
1077
           if (Balken <= 27) lcd_frect(Balken+(x*6)+1, (y*8)+1, 28-Balken, 5, 0);                       // loeschen
1078
        }
1079
 
1080
          } // end if: cells > 0   (TODO: Anzeige fuer cells==0 implementieren)
1081
}
1082
 
1083
 
1084
 
1085
//--------------------------------------------------------------
1086
// fuer die neuen OSD-Screens
1087
//--------------------------------------------------------------
1088
void OSD_Element_BattLevel2( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs )
1089
{
1090
        drawmode = (naviData->UBat < BattLowVoltageWarning ? MINVERS : MNORMAL);
1091
    writex_ndigit_number_u_10th( x, y, naviData->UBat, 3, 0, drawmode, xoffs,yoffs);
1092
        lcdx_printp_at( x+4, y, PSTR("V"), drawmode, xoffs+1,yoffs);                            // Einheit
1093
    lcd_line( (x+4)*6, y*8, (x+4)*6, y*8+7, (drawmode==MINVERS ? 1 : 0) );              // filler zwischen Spannung und "V"
1094
 
1095
}
1096
 
1097
 
1098
//--------------------------------------------------------------
1099
// fuer: Config.OSD_LipoBar==0
1100
// nStyle entspricht dem ehemaligen 'Mode'
1101
//--------------------------------------------------------------
1102
void OSD_Element_BatteryLevel_Text( uint8_t x, uint8_t y, uint8_t nStyle )
1103
{
1104
        if( nStyle <= 1)
1105
                drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0);  // Normal-Schrift
1106
        else           
1107
                drawmode = (naviData->UBat < BattLowVoltageWarning ? 4 : 3);  // Fett-Schrift
1108
 
1109
        if( nStyle <= 1)
1110
        {
1111
        write_ndigit_number_u_10th (x, y, naviData->UBat, 3, 0, drawmode);
1112
        lcd_printp_at (x+4, y, PSTR("V"), drawmode);
1113
        }
1114
        else           
1115
        {
1116
        write_ndigit_number_u_10th (x-2, y, naviData->UBat, 3, 0, drawmode);
1117
        lcd_printp_at (x+2, y, PSTR("V"), drawmode);
1118
        }      
1119
}
1120
 
1121
 
1122
//--------------------------------------------------------------
1123
// nStyle entspricht dem ehemaligen 'Mode'
1124
//--------------------------------------------------------------
1125
void OSD_Element_BatteryLevel( uint8_t x, uint8_t y, uint8_t nStyle )
1126
{
1127
        if( Config.OSD_LipoBar )
1128
                OSD_Element_BatteryLevel_Bar( x, y);
1129
        else
1130
                OSD_Element_BatteryLevel_Text( x, y, nStyle);
1131
}
1132
 
1133
 
1134
//--------------------------------------------------------------
1135
//--------------------------------------------------------------
1136
void OSD_Element_Capacity( uint8_t x, uint8_t y )
1137
{
1138
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? 2 : 0);
1139
 
1140
        write_ndigit_number_u (x, y, naviData->UsedCapacity, 5, 0, drawmode);
1141
        lcd_printp_at (x+5, y, PSTR("mAh"), drawmode);
1142
        // BeepTime = 3000;
1143
        // BeepMuster = 0x0020;
1144
}
1145
 
1146
 
1147
//--------------------------------------------------------------
1148
// OSD_Element_CareFree( x, y)
1149
//--------------------------------------------------------------
1150
void OSD_Element_CareFree( uint8_t x, uint8_t y )
1151
{
1152
        lcd_puts_at (x, y, strGet( naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE ? OSD_CARE_FREE_1 : OSD_CARE_FREE_0 ), 0);
1153
}
1154
 
1155
 
1156
//--------------------------------------------------------------
1157
// OSD_Element_CompassDegree( x, y, nStyle)
1158
// nStyle entspricht dem ehemaligen 'Mode'
1159
//--------------------------------------------------------------
1160
void OSD_Element_CompassDegree( uint8_t x, uint8_t y, uint8_t nStyle )
1161
{
1162
        switch( nStyle )
1163
    {
1164
        case 0 :
1165
        case 1 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MNORMAL);
1166
                     x += 3;
1167
                 break;
1168
 
1169
        case 2 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MBIG);
1170
                     x += 8;
1171
                 break;
1172
        }
1173
    lcd_putc( x, y, 0x1E, MNORMAL);     // degree symbol
1174
}
1175
 
1176
 
1177
//--------------------------------------------------------------
1178
//--------------------------------------------------------------
1179
void OSD_Element_CompassDirection( uint8_t x, uint8_t y )
1180
{
1181
        lcd_printp_at (x, y, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);
1182
}
1183
 
1184
 
1185
//--------------------------------------------------------------
1186
//--------------------------------------------------------------
1187
void OSD_Element_CompassRose( uint8_t x, uint8_t y )
1188
{
1189
        draw_compass (x, y, naviData->CompassHeading);
1190
}
1191
 
1192
//--------------------------------------------------------------
1193
//--------------------------------------------------------------
1194
void OSD_Element_Current( uint8_t x, uint8_t y )
1195
{
1196
        write_ndigit_number_u_10th (x, y, naviData->Current, 3, 0,0);
1197
        lcd_printp_at (x+4, y, PSTR("A"), 0);
1198
}
1199
 
1200
 
1201
//--------------------------------------------------------------
1202
//--------------------------------------------------------------
1203
void OSD_Element_FlyingTime( uint8_t x, uint8_t y )
1204
{
1205
        write_time (x, y, naviData->FlyingTime);
1206
        lcd_printp_at (x+5, y, PSTR("m"), 0);  
1207
}
1208
 
1209
 
1210
//--------------------------------------------------------------
1211
//--------------------------------------------------------------
1212
void OSD_Element_GroundSpeed( uint8_t x, uint8_t y )
1213
{
1214
        write_ndigit_number_u (x, y, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,0);
1215
        lcd_printp_at (x+3, y, PSTR("Kmh"), 0);
1216
}
1217
 
1218
 
1219
 
1220
//--------------------------------------------------------------
1221
//--------------------------------------------------------------
1222
void OSD_Element_HomeCircle( uint8_t x, uint8_t y, uint8_t breite, int8_t rOffset, int8_t xoffs, int8_t yoffs )
1223
{
1224
        lcd_o_circle( x, y, breite, 1, xoffs,yoffs);
1225
 
1226
    if (Config.OSD_HomeMKView==1)
1227
        heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
1228
    else
1229
        heading_home = (naviData->CompassHeading- naviData->HomePositionDeviation.Bearing + 360 ) % 360;
1230
 
1231
    lcd_o_circ_line( x, y, breite, old_hh      , rOffset, 0, xoffs,yoffs);
1232
    lcd_o_circ_line( x, y, breite, heading_home, rOffset, 1, xoffs,yoffs);
1233
 
1234
    old_hh = heading_home;
1235
}
1236
 
1237
 
1238
 
1239
 
1240
//--------------------------------------------------------------
1241
//--------------------------------------------------------------
1242
void OSD_Element_HomeDegree( uint8_t x, uint8_t y )
1243
{
1244
        write_ndigit_number_u (x, y, heading_home, 3, 0,0);
1245
        lcd_putc (x+3, y, 0x1e, 0);     // degree symbol
1246
}
1247
 
1248
 
1249
//--------------------------------------------------------------
1250
// OSD_Element_HomeDistance( x, y, nStyle)
1251
//--------------------------------------------------------------
1252
void OSD_Element_HomeDistance( uint8_t x, uint8_t y, uint8_t nStyle )
1253
{
1254
        switch( nStyle )
1255
    {
1256
        case 0 :
1257
        case 1 : write_ndigit_number_u (x, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0);
1258
                                 lcd_putc (x+3, y, 'm', 0);
1259
                                 draw_homesymbol(x+4, y);
1260
                 break;
1261
 
1262
        case 2 : lcd_printp_at (x, y, PSTR("Home"), 0);
1263
                 write_ndigit_number_u (x+5, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0);
1264
                 lcd_printp_at (x+8, y, PSTR("m -"), 0);
1265
                 break;
1266
        }              
1267
}
1268
 
1269
 
1270
//--------------------------------------------------------------
1271
// OSD_Element_LEDOutput( x, y, bitmask)
1272
//
1273
// bitmask: LED1 = FC_STATUS2_OUT1_ACTIVE
1274
//          LED2 = FC_STATUS2_OUT2_ACTIVE
1275
//--------------------------------------------------------------
1276
void OSD_Element_LEDOutput( uint8_t x, uint8_t y, uint8_t bitmask )
1277
{
1278
        uint8_t lOn;
1279
 
1280
        lOn = (naviData->FCStatusFlags2 & bitmask ? 1 : 0);   // Bit gesetzt?
1281
        lOn = (Config.OSD_InvertOut ? !lOn : lOn);            // Invertieren?
1282
        lOn = (lOn ? 1 : 0);                                  // auf 0 oder 1 setzen (hmm, geht auch besser...).
1283
 
1284
    lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, lOn);
1285
    lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
1286
 
1287
  /*
1288
    if (!Config.OSD_InvertOut)
1289
    {
1290
        if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE)
1291
        {
1292
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0);
1293
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
1294
        }
1295
        else
1296
        {
1297
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 1);
1298
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
1299
        }
1300
    }
1301
    else
1302
    {
1303
        if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE)
1304
        {
1305
            lcd_fcircle (x * 6 + 5, y * 8 + 3,Config.OSD_LEDform, 1);
1306
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
1307
        }
1308
        else
1309
        {
1310
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0);
1311
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
1312
        }
1313
    }
1314
    break;  
1315
  */
1316
}
1317
 
1318
 
1319
//--------------------------------------------------------------
1320
// OSD_Element_LED1Output( x, y)
1321
//--------------------------------------------------------------
1322
void OSD_Element_LED1Output( uint8_t x, uint8_t y )
1323
{
1324
        OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT1_ACTIVE );
1325
}
1326
 
1327
 
1328
//--------------------------------------------------------------
1329
// OSD_Element_LED2Output( x, y)
1330
//--------------------------------------------------------------
1331
void OSD_Element_LED2Output( uint8_t x, uint8_t y )
1332
{
1333
        OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT2_ACTIVE );
1334
}
1335
 
1336
 
1337
//--------------------------------------------------------------
1338
// OSD_Element_Manuell( x, y)
1339
//--------------------------------------------------------------
1340
void OSD_Element_Manuell( uint8_t x, uint8_t y )
1341
{
1342
        if (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL)
1343
                lcd_putc (x, y, 'M', 0); // rc transmitter
1344
        else
1345
                lcd_putc (x, y, 'X', 0); // clear       
1346
}
1347
 
1348
 
1349
//--------------------------------------------------------------
1350
// OSD_Element_NaviMode( x, y)
1351
//--------------------------------------------------------------
1352
void OSD_Element_NaviMode( uint8_t x, uint8_t y )
1353
{
1354
        if (naviData->NCFlags & NC_FLAG_FREE)
1355
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_0), 0); // Navi aus
1356
        else if (naviData->NCFlags & NC_FLAG_PH)
1357
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_1), 0); // Pos. Hold
1358
        else if (naviData->NCFlags & NC_FLAG_CH)
1359
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_2), 0); // Coming Home
1360
}
1361
 
1362
 
1363
//--------------------------------------------------------------
1364
// OSD_Element_RCIntensity( x, y)
1365
//--------------------------------------------------------------
1366
void OSD_Element_RCIntensity( uint8_t x, uint8_t y )
1367
{
1368
        write_ndigit_number_u (x, y, naviData->RC_Quality, 3, 0,0);
1369
        lcd_printp_at (x+3, y, PSTR("\x1F"), 0);                // RC-transmitter
1370
        if (naviData->NCFlags & NC_FLAG_NOSERIALLINK)
1371
        {
1372
                lcd_printpns_at(x+3, y, PSTR("  "), 0);         // Clear
1373
        }
1374
        else
1375
        {
1376
                lcd_printpns_at(x+3, y, PSTR("PC"), 0);
1377
        }
1378
}
1379
 
1380
 
1381
//--------------------------------------------------------------
1382
// OSD_Element_SatsInUse( x, y, nStyle)
1383
//
1384
// nStyle == 0: "00s"
1385
// nStyle == 1: wie 0
1386
// nStyle == 2: "00 Sat"
1387
//
1388
// nStyle entspricht dem ehemaligen 'Mode'
1389
//--------------------------------------------------------------
1390
void OSD_Element_SatsInUse( uint8_t x, uint8_t y, uint8_t  nStyle )
1391
{
1392
        drawmode = (naviData->NCFlags & NC_FLAG_GPS_OK ? 0 : 2);
1393
 
1394
        switch( nStyle )
1395
    {
1396
        case 0 :
1397
        case 1 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode);
1398
                 lcd_putc (x+2, y, 0x08, drawmode);
1399
                 break;
1400
 
1401
        case 2 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode);
1402
                 lcd_printp_at (x+2, y, PSTR(" Sat"), drawmode);
1403
                 break;
1404
        }
1405
}
1406
 
1407
 
1408
//--------------------------------------------------------------
1409
// OSD_Element_StatusFlags( x, y)
1410
//--------------------------------------------------------------
1411
void OSD_Element_StatusFlags( uint8_t x, uint8_t y )
1412
{
1413
        // FC_StatusFlags 0.88
1414
        // #define FC_STATUS_MOTOR_RUN           0x01
1415
        // #define FC_STATUS_FLY                 0x02
1416
        // #define FC_STATUS_CALIBRATE           0x04
1417
        // #define FC_STATUS_START               0x08
1418
        // #define FC_STATUS_EMERGENCY_LANDING   0x10
1419
        // #define FC_STATUS_LOWBAT              0x20
1420
        // #define FC_STATUS_VARIO_TRIM_UP       0x40
1421
        // #define FC_STATUS_VARIO_TRIM_DOWN     0x80
1422
 
1423
        if (naviData->FCStatusFlags & FC_STATUS_CALIBRATE)
1424
                lcd_puts_at (x, y, strGet(OSD_FLAGS_1), 0);     // Calibrate
1425
        else if (naviData->FCStatusFlags & FC_STATUS_START)
1426
                lcd_puts_at (x, y, strGet(OSD_FLAGS_2), 0);     // Start
1427
        else if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN)
1428
                lcd_puts_at (x, y, strGet(OSD_FLAGS_3), 0);     // Run
1429
        else if (naviData->FCStatusFlags & FC_STATUS_FLY)
1430
                lcd_puts_at (x, y, strGet(OSD_FLAGS_4), 0);     // Fly
1431
        else if (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING)
1432
                lcd_puts_at (x, y, strGet(OSD_FLAGS_5), 0);     // Landing
1433
        else if (naviData->FCStatusFlags & FC_STATUS_LOWBAT)
1434
                lcd_puts_at (x, y, strGet(OSD_FLAGS_6), 0);     // LowBat
1435
        else
1436
    //  lcd_printp_at (x, y, PSTR("         "), 0);     // Clear
1437
                lcd_puts_at (x, y, strGet(OSD_FLAGS_0), 0);     // Clear
1438
}
1439
 
1440
 
1441
//--------------------------------------------------------------
1442
// OSD_Element_Variometer( x, y)
1443
//--------------------------------------------------------------
1444
void OSD_Element_Variometer( uint8_t x, uint8_t y )
1445
{
1446
        x *= 6;
1447
        y *= 8;
1448
        y += 7;
1449
 
1450
        draw_variometer (x, y, 10, 14, naviData->Variometer);
1451
}
1452
 
1453
 
1454
//--------------------------------------------------------------
1455
// OSD_Element_Target( x, y, nStyle)
1456
//
1457
// nStyle entspricht dem ehemaligen 'Mode'
1458
// nStyle = 0,1: "000m" 
1459
// nStyle = 2,3: "Ziel 000m -" 
1460
//--------------------------------------------------------------
1461
void OSD_Element_Target( uint8_t x, uint8_t y, uint8_t nStyle )
1462
{
1463
        if( nStyle <= 1 )
1464
        {
1465
                write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0);
1466
                lcd_putc (x+3, y, 'm', 0);
1467
                draw_targetsymbol(x+4,y);
1468
        }
1469
        else   
1470
        {
1471
        lcd_printp_at (x, y, PSTR("Ziel"), 0);
1472
        write_ndigit_number_u (x+5, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0);
1473
        lcd_printp_at (x+8, y, PSTR("m -"), 0);
1474
        }
1475
}
1476
 
1477
 
1478
//--------------------------------------------------------------
1479
// TODO:
1480
// - pruefen ob beep hier an richtiger Stelle ist
1481
//--------------------------------------------------------------
1482
void OSD_Element_VarioWert( uint8_t x, uint8_t y )
1483
{
1484
        uint8_t FC_Fallspeed;
1485
 
1486
    FC_Fallspeed = (unsigned int)naviData->Variometer;
1487
    FC_Fallspeed = 255-FC_Fallspeed;
1488
 
1489
        drawmode = ( (naviData->Variometer < 0) && (FC_Fallspeed > Config.OSD_Fallspeed) ? 2 : 0);
1490
 
1491
 
1492
        if( Config.OSD_VarioBeep )
1493
                Beep_Vario();                                                           // Beep ???
1494
 
1495
    if( drawmode == 2 )
1496
        {
1497
        if( !Config.HWSound )  
1498
                set_beep ( 1000, 0x0060, BeepNormal);   // muss ein Beep hier hin????
1499
        else  
1500
                variobeep(naviData->Variometer);        // muss ein Beep hier hin????
1501
    }
1502
 
1503
    write_ndigit_number_s_10th (x, y, naviData->Variometer, 3,0, drawmode);
1504
    lcd_printpns_at(x+4, y, PSTR("ms"), drawmode);     
1505
}
1506
 
1507
 
1508
//--------------------------------------------------------------
1509
//--------------------------------------------------------------
1510
void OSD_Element_WayPoint( uint8_t x, uint8_t y )
1511
{
1512
        if (!OldWP == naviData->WaypointIndex)
1513
        {
1514
                // BeepTime = 500;
1515
                // BeepMuster = 0x0080;
1516
        OldWP = naviData->WaypointIndex;
1517
        NextWP = true;
1518
    }
1519
 
1520
    if ((NextWP==true)&& naviData->NCFlags & NC_FLAG_TARGET_REACHED)
1521
    {
1522
        set_beep ( 500, 0x0080, BeepNormal);
1523
        NextWP = false;
1524
    }
1525
 
1526
    write_ndigit_number_u (x+2, y, naviData->WaypointIndex , 2, 0,0);
1527
 
1528
    lcd_printp_at (x, y, PSTR("WP"), 0);
1529
}
1530
 
1531
 
1532
//--------------------------------------------------------------
1533
//--------------------------------------------------------------
1534
void OSD_Element_TargetDegree( uint8_t x, uint8_t y )
1535
{
1536
        write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Bearing/ 10, 3, 0,0);
1537
        lcd_putc (x+3, y, 0x1e, 0);     // degree symbol
1538
}
1539
 
1540
 
1541
 
1542
//##############################################################
1543
//# OSD-SCREENS
1544
//##############################################################
1545
 
1546
//--------------------------------------------------------------
1547
// OSD-Screen "General"
1548
//
1549
// nMode: 0 = update values
1550
//        1 = redraw labels and update values  
1551
//--------------------------------------------------------------
1552
const char * OSD_Screen_General( uint8_t nMode )
1553
{
1554
        const char *ScreenName = PSTR("General");
1555
 
1556
        //-----------------------------------------
1557
        // REDRAW
1558
        // statische Screen Elemente die nicht
1559
        // jedesmal neu gezeichnet werden muessen
1560
        //-----------------------------------------
1561
        if( nMode == OSD_SCREEN_REDRAW )
1562
        {      
1563
        // Display: 128 x 64 with 6x8 Font => 21 x 8
1564
 
1565
                // Linien: Horizontal
1566
                lcd_line (0, 28, 127, 28, 1);  // mitte
1567
            lcd_line (0, 51, 127, 51, 1);  // unten
1568
 
1569
                // Linien: Vertikal
1570
        lcd_line (65, 0, 65, 50, 1);   // mitte
1571
 
1572
                //-----------------------------------------
1573
                // Block: Oben - Links
1574
                //-----------------------------------------             
1575
                draw_icon_battery(0,4);
1576
                //lcdx_printp_at( 6, 0, PSTR("V")        , MNORMAL, 1,0);       // Spannung (Volt)
1577
                lcdx_printp_at( 7, 2, PSTR(" mA"), MNORMAL, 0,2);
1578
 
1579
                //-----------------------------------------
1580
                // Block: Oben - Rechts
1581
                //-----------------------------------------
1582
                lcdx_printp_at( 12, 0, PSTR("Alt:")     , MNORMAL, 0,0);
1583
                lcdx_printp_at( 12, 1, PSTR("Dir:")     , MNORMAL, 0,1);
1584
        draw_symbol_degree( 20, 1, 1,1);
1585
                lcdx_printp_at( 12, 2, PSTR("  I:")     , MNORMAL, 0,2);
1586
                lcdx_printp_at( 20, 2, PSTR("A")        , MNORMAL, 2,2);
1587
 
1588
                //-----------------------------------------
1589
                // Block: Unten - Links
1590
                //-----------------------------------------
1591
                draw_icon_sat(0,33);
1592
                lcdx_printp_at( 6, 5, PSTR(" kmh"), MNORMAL, 0,1);
1593
 
1594
                //-----------------------------------------
1595
                // Block: Unten - Rechts
1596
                //-----------------------------------------
1597
                draw_icon_home( 70, 32);
1598
                lcdx_printp_at( 20, 4, PSTR("m"), MNORMAL, 2,0);
1599
                draw_symbol_degree( 20, 5, 1,1);
1600
        //lcd_putc( 20, 5, 0x1E, 0);     // alternativ: degree symbol   
1601
 
1602
                //-----------------------------------------
1603
                // unterste Zeile
1604
                //-----------------------------------------
1605
                draw_symbol_rc(20,7);                   // RC-transmitter
1606
        }
1607
 
1608
    //-----------------
1609
    // Batt Level (Volt)
1610
    //-----------------
1611
        OSD_Element_BattLevel2( 2, 0, 0,0 );
1612
 
1613
    //-----------------
1614
    // LowBat Warnung MK
1615
    //-----------------
1616
        OSD_Element_Flag( 8, 0, OSD_FLAG_BA, 0,0 );
1617
 
1618
    //-----------------
1619
    // Flugzeit
1620
    //-----------------
1621
        writex_time(2, 1, naviData->FlyingTime, MNORMAL, 0,1);
1622
 
1623
    //-----------------
1624
        // entnommene Kapazitaet (mAh)
1625
    //-----------------
1626
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL);
1627
        writex_ndigit_number_u( 2, 2, naviData->UsedCapacity, 5, 0, drawmode, 0,2);
1628
 
1629
    //-----------------
1630
    // Höhe
1631
    //-----------------
1632
        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
1633
        write_ndigit_number_s ( 16, 0, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, MNORMAL);
1634
        else                                                                                                                                                                                                    // up to 10m write meters.dm
1635
        write_ndigit_number_s_10th( 16, 0, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, MNORMAL);
1636
 
1637
    //-----------------
1638
    // steigen / sinken
1639
    //-----------------
1640
        OSD_Element_UpDown( 20, 0, 2,0);
1641
 
1642
    //-----------------
1643
        // Compass Degree
1644
    //-----------------
1645
    writex_ndigit_number_u (17, 1, naviData->CompassHeading, 3, 0,MNORMAL, 0,1);
1646
 
1647
    //-----------------
1648
    // Strom
1649
    //-----------------
1650
        //write_ndigit_number_u_10th( 16, 2, naviData->Current, 3, 0,0);  // alternativ mit Nachkomma
1651
        writex_ndigit_number_u( 17, 2, naviData->Current/10, 3, 0,MNORMAL, 0,2);
1652
 
1653
    //-----------------
1654
        // Sat Anzahl
1655
    //-----------------
1656
        write_ndigit_number_u (4, 4, naviData->SatsInUse, 2, 0,MNORMAL);
1657
 
1658
    //-----------------
1659
        // Sat Warnung "!"
1660
    //-----------------
1661
        /*
1662
        if( naviData->NCFlags & NC_FLAG_GPS_OK )
1663
                lcd_printp_at( 9, 4, PSTR(" "), MNORMAL);
1664
        else
1665
                lcd_printp_at( 9, 4, PSTR("!"), MNORMAL);
1666
        */     
1667
        OSD_Element_Flag(  8, 4, OSD_FLAG_S0, -1,0 );  // Sat Warnung (GPS not ok)
1668
 
1669
    //-----------------
1670
        // Geschwindigkeit
1671
    //-----------------
1672
        writex_ndigit_number_u( 3, 5, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL, 0,1);
1673
 
1674
    //-----------------
1675
        // Home Distance
1676
    //-----------------
1677
        write_ndigit_number_u( 17, 4, naviData->HomePositionDeviation.Distance / 10, 3, 0,MNORMAL);
1678
 
1679
    //-----------------
1680
        // Home Winkel
1681
    //-----------------
1682
    writex_ndigit_number_u( 16, 5, heading_home, 4, 0,MNORMAL, 0,1);
1683
 
1684
    //-----------------
1685
    // Flags
1686
    //-----------------
1687
        OSD_Element_Flag(  1, 7, OSD_FLAG_CF, 0,0 );  // Care Free
1688
        OSD_Element_Flag(  4, 7, OSD_FLAG_AH, 0,0 );  // Altitude Hold
1689
        OSD_Element_Flag(  7, 7, OSD_FLAG_PH, 0,0 );  // Position Hold
1690
        OSD_Element_Flag( 10, 7, OSD_FLAG_CH, 0,0 );  // Coming Home
1691
        OSD_Element_Flag( 13, 7, OSD_FLAG_EL, 0,0 );  // Emergency Landing
1692
 
1693
    //-----------------
1694
    // RC-Quality (MK)
1695
    //-----------------
1696
        write_ndigit_number_u( 17, 7, naviData->RC_Quality, 3, 0,MNORMAL);
1697
 
1698
        #ifdef OSD_DEMO
1699
        //-----------------
1700
        // Flags
1701
        //-----------------
1702
                OSD_Element_Flag_Label(  8, 0, OSD_FLAG_BA, true, 0,0 );        // DEMO: Batterie Warnung
1703
                OSD_Element_Flag_Label(  8, 4, OSD_FLAG_S0, true, -1,0 );       // DEMO: Sat Warnung (GPS not ok)
1704
 
1705
                OSD_Element_Flag_Label(  1, 7, OSD_FLAG_CF, true, 0,0 );        // DEMO
1706
                OSD_Element_Flag_Label(  4, 7, OSD_FLAG_AH, true, 0,0 );        // DEMO
1707
                OSD_Element_Flag_Label(  7, 7, OSD_FLAG_PH, true, 0,0 );        // DEMO
1708
                OSD_Element_Flag_Label( 10, 7, OSD_FLAG_CH, true, 0,0 );        // DEMO
1709
                OSD_Element_Flag_Label( 13, 7, OSD_FLAG_EL, true, 0,0 );        // DEMO
1710
    #endif      
1711
 
1712
 
1713
        return( ScreenName );
1714
}
1715
 
1716
 
1717
//--------------------------------------------------------------
1718
// OSD-Screen "Navigation"
1719
//
1720
// nMode: 0 = update values
1721
//        1 = redraw labels and update values  
1722
//--------------------------------------------------------------
1723
const char * OSD_Screen_Navigation( uint8_t nMode )
1724
{
1725
        const char *ScreenName = PSTR("Navigation");
1726
        int8_t xoffs, yoffs;
1727
 
1728
        //-----------------------------------------
1729
        // REDRAW
1730
        // statische Screen Elemente die nicht
1731
        // jedesmal neu gezeichnet werden muessen
1732
        //-----------------------------------------
1733
        if( nMode == OSD_SCREEN_REDRAW )
1734
        {      
1735
                // do things here for static screen elements like labels and so....
1736
 
1737
        lcd_line ((6*6-4), 0, (6*6-4), 9, 1);                                           // Linie Vertikal links
1738
        lcd_line ((15*6+3), 0, (15*6+3), 9, 1);                                         // Linie Vertikal rechts
1739
        lcd_line (0, 10, 127, 10, 1);                                                           // Linie Horizontal
1740
 
1741
                lcdx_printp_at( 0, 2, PSTR("Alt:"), MNORMAL, 0,2);              // Hoehe
1742
                lcdx_printp_at( 0, 5, PSTR("Home:"), MNORMAL, 0,3);             // Home Distance
1743
    }
1744
 
1745
 
1746
    //-----------------
1747
    // Oben: Batt Level (Volt)
1748
    //-----------------
1749
        OSD_Element_BattLevel2( 0, 0, 0,0 );
1750
 
1751
    //-----------------
1752
    // Oben: Kompass Rose
1753
    //-----------------
1754
        OSD_Element_CompassRose( 6, 0);
1755
 
1756
    //-----------------
1757
    // Oben: Flugzeit
1758
    //-----------------
1759
        write_time(16, 0, naviData->FlyingTime);
1760
 
1761
    //-----------------
1762
    // Hoehe
1763
    //-----------------
1764
    xoffs = 0;
1765
    yoffs = 3;
1766
        drawmode = MNORMAL;
1767
        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
1768
        writex_ndigit_number_s ( 0, 3, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, drawmode, xoffs,yoffs);
1769
        else                                                                                                                                                                                                    // up to 10m write meters.dm
1770
        writex_ndigit_number_s_10th( 0, 3, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, drawmode, xoffs,yoffs);
1771
 
1772
    //-----------------
1773
    // Steigen / Sinken
1774
    //-----------------
1775
        OSD_Element_UpDown( 4, 3, 1,yoffs);
1776
 
1777
    //-----------------
1778
    // Home Distance
1779
    //-----------------
1780
    yoffs = 3;
1781
        writex_ndigit_number_u( 0, 6, naviData->HomePositionDeviation.Distance / 10, 4, 0,MNORMAL, 0,yoffs+1);
1782
        lcdx_printp_at( 4, 6, PSTR("m"), MNORMAL, 2,yoffs+1);           // Home
1783
 
1784
    //-----------------
1785
    // Home Circle
1786
    //-----------------
1787
    xoffs = 0;
1788
    yoffs = 3;
1789
        OSD_Element_HomeCircle(  8, 3, 9, 4, xoffs,yoffs);                                              // Home Circle
1790
        lcd_frect( (9*6)-3+xoffs, (4*8)-2+yoffs, (3*6)+4, (1*8)+2, 0);                  // inner clear
1791
        lcd_rect ( (9*6)-4+xoffs, (4*8)-3+yoffs, (3*6)+6, (1*8)+4, 1);                  // inner rect
1792
        lcd_frect ( 61+xoffs, 57+yoffs, 2, 2, 1);                                                               // bottom mini rect
1793
    writex_ndigit_number_u( 9, 4, heading_home, 3, 0,MNORMAL, xoffs,yoffs);     // Degree (Winkel)
1794
 
1795
    //-----------------
1796
    // Variometer
1797
    //-----------------
1798
        //void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
1799
        //draw_variometer( 95, 38,  7, 30, naviData->Variometer);
1800
        //draw_variometer( 94, 38,  7, 21, naviData->Variometer);
1801
        //draw_variometer2( 94, 28,  7, 21, naviData->Variometer);
1802
 
1803
    //-----------------
1804
    // Flags
1805
    //-----------------
1806
        OSD_Element_Flag(  16, 2, OSD_FLAG_BA, -3, 0);  // MK Batt Warning
1807
        OSD_Element_Flag(  19, 2, OSD_FLAG_CF,  0, 0);  // Carefree
1808
        OSD_Element_Flag(  19, 4, OSD_FLAG_AH,  0,-3);  // Altitude Hold
1809
        OSD_Element_Flag(  19, 6, OSD_FLAG_PH,  0,-6);  // Position Hold
1810
        OSD_Element_Flag(  19, 7, OSD_FLAG_CH,  0,-1);  // Coming Home
1811
        OSD_Element_Flag(  16, 7, OSD_FLAG_S0, -3,-1);  // GPS-Sat not ok (GPS NOT ok)
1812
 
1813
 
1814
    #ifdef OSD_DEMO
1815
        //-----------------
1816
        // Flags
1817
        //-----------------
1818
                OSD_Element_Flag_Label(  16, 2, OSD_FLAG_BA, true, -3,0);       // DEMO
1819
 
1820
                OSD_Element_Flag_Label(  19, 2, OSD_FLAG_CF, true, 0,0);        // DEMO
1821
                OSD_Element_Flag_Label(  19, 4, OSD_FLAG_AH, true, 0,-3);       // DEMO
1822
                OSD_Element_Flag_Label(  19, 6, OSD_FLAG_PH, true, 0,-6);       // DEMO
1823
                OSD_Element_Flag_Label(  19, 7, OSD_FLAG_CH, true, 0,-1);       // DEMO
1824
 
1825
                OSD_Element_Flag_Label(  16, 7, OSD_FLAG_S0, true, -3,-1);      // DEMO
1826
    #endif      
1827
 
1828
 
1829
        return( ScreenName );
1830
}
1831
 
1832
 
1833
 
1834
 
1835
//--------------------------------------------------------------
1836
// OSD-Screen "Status"
1837
//
1838
// nMode: 0 = update values
1839
//        1 = redraw labels and update values  
1840
//--------------------------------------------------------------
1841
const char * OSD_Screen_MKStatus( uint8_t nMode )
1842
{
1843
        const char *ScreenName = PSTR("MK-Status");
1844
        int8_t xoffs;
1845
 
1846
        //-----------------------------------------
1847
        // REDRAW
1848
        // statische Screen Elemente die nicht
1849
        // jedesmal neu gezeichnet werden muessen
1850
        //-----------------------------------------
1851
        if( nMode == OSD_SCREEN_REDRAW )
1852
        {      
1853
                // do things here for static screen elements like labels and so....
1854
 
1855
        lcd_line ((6*6-3), 0, (6*6-3), 9, 1);                                           // Linie Vertikal links
1856
        lcd_line ((15*6+3), 0, (15*6+3), 9, 1);                                         // Linie Vertikal rechts
1857
        lcd_line (0, 10, 127, 10, 1);                                                           // Linie Horizontal
1858
 
1859
                //lcdx_printp_at( 8, 0, PSTR("Status"), MNORMAL, -3,0);         // oben, mitte Text
1860
                lcdx_printp_at( 13, 0, PSTR("A"), MNORMAL, -4,0);                       // oben, mitte "A"
1861
    }
1862
 
1863
 
1864
    //-----------------
1865
    // Oben: Batt Level (Volt)
1866
    //-----------------
1867
        OSD_Element_BattLevel2( 0, 0, 0,0 );
1868
 
1869
    //-----------------
1870
    // Strom
1871
    //-----------------
1872
        writex_ndigit_number_u_10th( 7, 0, naviData->Current, 4, 0,MNORMAL, 1,0);  // Strom mit Nachkomma
1873
 
1874
    //-----------------
1875
    // Oben: Flugzeit
1876
    //-----------------
1877
        write_time(16, 0, naviData->FlyingTime);
1878
 
1879
    //-----------------
1880
    // Flags
1881
    //-----------------
1882
    xoffs = -7;
1883
        OSD_Element_Flag(  19, 2, OSD_FLAG_CF,  0+xoffs, 0);    // Carefree
1884
        OSD_Element_Flag(  19, 4, OSD_FLAG_AH,  0+xoffs,-3);    // Altitude Hold
1885
        OSD_Element_Flag(  19, 6, OSD_FLAG_PH,  0+xoffs,-6);    // Position Hold
1886
        OSD_Element_Flag(  19, 7, OSD_FLAG_CH,  0+xoffs,-1);    // Coming Home
1887
 
1888
    xoffs -= 4;
1889
        OSD_Element_Flag(  16, 2, OSD_FLAG_BA, -3+xoffs, 0);    // MK Batt Warning
1890
        OSD_Element_Flag(  16, 4, OSD_FLAG_EL, -3+xoffs,-3);    // Emergency Landing
1891
        OSD_Element_Flag(  16, 6, OSD_FLAG_RL, -3+xoffs,-6);    // Range Limit
1892
        OSD_Element_Flag(  16, 7, OSD_FLAG_S0, -3+xoffs,-1);    // GPS-Sat not ok (GPS NOT ok)
1893
 
1894
    xoffs -= 4;
1895
        OSD_Element_Flag(  12, 2, OSD_FLAG_CA,  0+xoffs, 0);    // Calibrate
1896
        OSD_Element_Flag(  12, 4, OSD_FLAG_ST,  0+xoffs,-3);    // Start
1897
        OSD_Element_Flag(  12, 6, OSD_FLAG_MR,  0+xoffs,-6);    // Motor Run
1898
        OSD_Element_Flag(  12, 7, OSD_FLAG_FY,  0+xoffs,-1);    // Fly
1899
 
1900
    xoffs -= 4;
1901
        OSD_Element_Flag(   9, 2, OSD_FLAG_O1, -2+xoffs, 0);    // Out1
1902
        OSD_Element_Flag(   9, 4, OSD_FLAG_O2, -2+xoffs,-3);    // Out2
1903
        OSD_Element_Flag(   9, 6, OSD_FLAG_TR, -2+xoffs,-6);    // Target Reached
1904
        OSD_Element_Flag(   9, 7, OSD_FLAG_MC, -2+xoffs,-1);    // Manual Control
1905
 
1906
    xoffs -= 4;
1907
        OSD_Element_Flag(   6, 2, OSD_FLAG_TU, -4+xoffs, 0);    // Vario Trim Up
1908
        OSD_Element_Flag(   6, 4, OSD_FLAG_TD, -4+xoffs,-3);    // Vario Trim Down
1909
        OSD_Element_Flag(   6, 6, OSD_FLAG_FR, -4+xoffs,-6);    // Free
1910
        OSD_Element_Flag(   6, 7, OSD_FLAG_SL, -4+xoffs,-1);    // No Serial Link
1911
 
1912
 
1913
    #ifdef OSD_DEMO
1914
        //-----------------
1915
        // Flags
1916
        //-----------------
1917
 /*
1918
                PSTR("AH"),  // OSD_FLAG_AH  Altitue Hold
1919
                PSTR("PH"),  // OSD_FLAG_PH  Position Hold
1920
                PSTR("CF"),  // OSD_FLAG_CF  Care Free
1921
                PSTR("CH"),  // OSD_FLAG_CH  Coming Home
1922
                PSTR("o1"),  // OSD_FLAG_O1  Out1
1923
                PSTR("o2"),  // OSD_FLAG_O2  Out2
1924
                PSTR("BA"),  // OSD_FLAG_BA  LowBat warning (MK)
1925
                PSTR("CA"),  // OSD_FLAG_CA  Calibrate
1926
                PSTR("ST"),  // OSD_FLAG_ST  Start
1927
                PSTR("MR"),  // OSD_FLAG_MR  Motor Run
1928
                PSTR("FY"),  // OSD_FLAG_FY  Fly
1929
                PSTR("EL"),  // OSD_FLAG_EL  Emergency Landing
1930
                PSTR("FS"),      // OSD_FLAG_FS  RX Failsave Active
1931
                PSTR("GP"),  // OSD_FLAG_GP  GPS Ok
1932
                PSTR("S!")       // OSD_FLAG_S0  GPS-Sat not ok (GPS NOT ok)
1933
                PSTR("TU"),  // OSD_FLAG_TU  Vario Trim Up
1934
                PSTR("TD"),  // OSD_FLAG_TD  Vario Trim Down
1935
                PSTR("FR"),  // OSD_FLAG_FR  Free
1936
                PSTR("RL"),  // OSD_FLAG_RL  Range Limit
1937
                PSTR("SL"),  // OSD_FLAG_SL  No Serial Link
1938
                PSTR("TR"),  // OSD_FLAG_TR  Target Reached
1939
                PSTR("MC")   // OSD_FLAG_MC  Manual Control            
1940
*/
1941
        xoffs = -7;    
1942
                OSD_Element_Flag_Label(  19, 2, OSD_FLAG_CF, true,  0+xoffs, 0);        // DEMO: Carefree
1943
                OSD_Element_Flag_Label(  19, 4, OSD_FLAG_AH, true,  0+xoffs,-3);        // DEMO: Altitude Hold
1944
                OSD_Element_Flag_Label(  19, 6, OSD_FLAG_PH, true,  0+xoffs,-6);        // DEMO: Position Hold
1945
                OSD_Element_Flag_Label(  19, 7, OSD_FLAG_CH, true,  0+xoffs,-1);        // DEMO: Coming Home
1946
 
1947
        xoffs -= 4;
1948
                OSD_Element_Flag_Label(  16, 2, OSD_FLAG_BA, true, -3+xoffs, 0);        // DEMO: MK Batt Warning
1949
                OSD_Element_Flag_Label(  16, 4, OSD_FLAG_EL, true, -3+xoffs,-3);        // DEMO: Emergency Landing
1950
                OSD_Element_Flag_Label(  16, 6, OSD_FLAG_RL, true, -3+xoffs,-6);        // DEMO: Range Limit
1951
                OSD_Element_Flag_Label(  16, 7, OSD_FLAG_S0, true, -3+xoffs,-1);        // DEMO: GPS-Sat not ok (GPS NOT ok)
1952
 
1953
        xoffs -= 4;
1954
                OSD_Element_Flag_Label(  12, 2, OSD_FLAG_CA, true,  0+xoffs, 0);        // DEMO: Calibrate
1955
                OSD_Element_Flag_Label(  12, 4, OSD_FLAG_ST, true,  0+xoffs,-3);        // DEMO: Start
1956
                OSD_Element_Flag_Label(  12, 6, OSD_FLAG_MR, true,  0+xoffs,-6);        // DEMO: Motor Run
1957
                OSD_Element_Flag_Label(  12, 7, OSD_FLAG_FY, true,  0+xoffs,-1);        // DEMO: Fly
1958
 
1959
        xoffs -= 4;
1960
                OSD_Element_Flag_Label(   9, 2, OSD_FLAG_O1, true, -2+xoffs, 0);        // DEMO: Out1
1961
                OSD_Element_Flag_Label(   9, 4, OSD_FLAG_O2, true, -2+xoffs,-3);        // DEMO: Out2
1962
                OSD_Element_Flag_Label(   9, 6, OSD_FLAG_TR, true, -2+xoffs,-6);        // DEMO: Target Reached
1963
                OSD_Element_Flag_Label(   9, 7, OSD_FLAG_MC, true, -2+xoffs,-1);        // DEMO: Manual Control
1964
 
1965
        xoffs -= 4;
1966
                OSD_Element_Flag_Label(   6, 2, OSD_FLAG_TU, true, -4+xoffs, 0);        // DEMO: Vario Trim Up
1967
                OSD_Element_Flag_Label(   6, 4, OSD_FLAG_TD, true, -4+xoffs,-3);        // DEMO: Vario Trim Down
1968
                OSD_Element_Flag_Label(   6, 6, OSD_FLAG_FR, true, -4+xoffs,-6);        // DEMO: Free
1969
                OSD_Element_Flag_Label(   6, 7, OSD_FLAG_SL, true, -4+xoffs,-1);        // DEMO: No Serial Link
1970
 
1971
    #endif      
1972
 
1973
 
1974
        return( ScreenName );
1975
}
1976
 
1977
 
1978
 
1979
//##############################################################
1980
#ifdef OSD_DEBUG_SCREEN
1981
//##############################################################
1982
 
1983
//**************************************************************
1984
//* OSD_DEBUG_SCREEN - Experimental-Code usw. 
1985
//* - nicht fuer die Oeffentlichkeit bestimmt
1986
//* - gesteuert ueber define OSD_DEBUG_SCREEN
1987
//**************************************************************
1988
 
1989
 
1990
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1991
// NOTIZEN
1992
//
1993
// 1. Thema: Motorwerte abfragen
1994
//
1995
// ja, auf die gleiche Weise wie man an die Config Parameter kommt.
1996
// 
1997
// SwitchToFC();
1998
// SendOutData( 'u', ADDRESS_FC, BL-Adresse,  &tmp_dat, 1);
1999
// 
2000
// Die Daten kommen dann in der Form:
2001
// typedef struct
2002
// {
2003
//         uint8_t Version;                        // the version of the BL (0 = old)
2004
//         uint8_t SetPoint;                       // written by attitude controller
2005
//         uint8_t SetPointLowerBits;      // for higher Resolution of new BLs
2006
//         uint8_t State;                          // 7 bit for I2C error counter, highest bit indicates if motor is present
2007
//         uint8_t ReadMode;                       // select data to read
2008
//         // the following bytes must be exactly in that order!
2009
//         uint8_t Current;                        // in 0.1 A steps, read back from BL
2010
//         uint8_t MaxPWM;                         // read back from BL -> is less than 255 if BL is in current limit, not running (250) or starting (40)
2011
//         int8_t  Temperature;                    // old BL-Ctrl will return a 255 here, the new version the temp. in ?C
2012
// } __attribute__((packed)) MotorData_t;
2013
// 
2014
// 
2015
// kennst Du die Seite?:http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=%28%28----%28-*%29%28\r%29%3F\n%29%28.*%29CategoryCoding%29#en.2BAC8-SerialCommands.Flight-Ctrl
2016
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2017
 
2018
 
2019
//--------------------------------------------------------------
2020
//--------------------------------------------------------------
2021
uint8_t xload_setting( uint8_t setting )
2022
{
2023
        mode = 'Q';     // Settings
2024
        uint8_t timeout = 50;
2025
        rxd_buffer_locked = FALSE;
2026
 
2027
        while (!rxd_buffer_locked && timeout)
2028
        {
2029
                SendOutData ('q', ADDRESS_FC, 1, &setting, 1);
2030
        //      _delay_ms(50);
2031
                timer = 20;
2032
                while (timer > 0);
2033
                timeout--;
2034
        }
2035
 
2036
        if (timeout != 0)
2037
        {
2038
                Decode64 ();
2039
                setting = *pRxData;
2040
                mk_param_struct = (mk_param_struct_t *) (pRxData + 1) ;
2041
        }
2042
        else
2043
        {       // timeout occured
2044
//              lcd_printp_at (0, 2, PSTR("Fehler: keine Daten"), 0);
2045
               lcd_puts_at(0, 2, strGet(OSD_ERROR), 0);
2046
                timer = 100;
2047
                while (timer > 0);
2048
                setting = 255;
2049
        }
2050
        return setting;
2051
}
2052
 
2053
 
2054
//--------------------------------------------------------------
2055
//--------------------------------------------------------------
2056
const char * OSD_Screen_Debug( uint8_t nMode )
2057
{
2058
        const char *ScreenName = PSTR("Debug");
2059
 
2060
        static s16              min_debug = 0;
2061
        static s16              max_debug = 0;
2062
        static uint16_t debug_count = 0;
2063
 
2064
        //-----------------------------------------
2065
        // REDRAW
2066
        // statische Screen Elemente die nicht
2067
        // jedesmal neu gezeichnet werden muessen
2068
        //-----------------------------------------
2069
        if( nMode == OSD_SCREEN_REDRAW )
2070
        {      
2071
                // do things here for static screen elements like labels and so....
2072
                min_debug = 0;
2073
                max_debug = 0;
2074
    }
2075
 
2076
        lcd_printp_at( 0, 0, PSTR("Debug"), 0);
2077
 
2078
 
2079
    debug_count++;
2080
 
2081
        if( naviData->Variometer < min_debug ) min_debug = naviData->Variometer;
2082
        if( naviData->Variometer > max_debug ) max_debug = naviData->Variometer;
2083
 
2084
    write_ndigit_number_s ( 8, 1, (naviData->Variometer), 12, 0,MNORMAL);   // s16 Variometer;  
2085
    write_ndigit_number_s ( 8, 2, (min_debug), 12, 0,MNORMAL);   // s16 Variometer;  
2086
    write_ndigit_number_s ( 8, 3, (max_debug), 12, 0,MNORMAL);   // s16 Variometer;  
2087
 
2088
    write_ndigit_number_u ( 8, 5, (debug_count), 12, 0,MNORMAL);   //  
2089
    //write_ndigit_number_u ( 8, 6, (timer), 12, 0,MNORMAL);   //  
2090
 
2091
        //draw_variometer2( 6, 19,  7, 21, naviData->Variometer);
2092
 
2093
        return( ScreenName );
2094
}
2095
//##############################################################
2096
#endif  // OSD_DEBUG_SCREEN
2097
//##############################################################
2098
 
2099
 
2100
 
2101
//--------------------------------------------------------------
2102
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 0
2103
//--------------------------------------------------------------
2104
const char * OSD_Screen_OSD0( uint8_t nMode )
2105
{
2106
        const char *ScreenName = PSTR("OSD0");
2107
        //uint8_t xoffs;
2108
 
2109
        //-----------------------------------------
2110
        // REDRAW static screen elements
2111
        //-----------------------------------------
2112
        if( nMode == OSD_SCREEN_REDRAW )
2113
        {      
2114
                // do things here for static screen elements like labels and so....
2115
    }
2116
 
2117
        OSD_Element_AltitudeControl ( 0, 3);
2118
        OSD_Element_Altitude        ( 11, 3, 0);
2119
        OSD_Element_BatteryLevel    (  0, 7, 0);
2120
        OSD_Element_Capacity        ( 13, 7);
2121
        OSD_Element_Current         (  8, 7);
2122
        OSD_Element_CareFree        (  0, 5);
2123
        OSD_Element_CompassDegree   ( 13, 0, 0);
2124
        OSD_Element_CompassDirection( 18, 0);
2125
        OSD_Element_CompassRose     ( 12, 1);
2126
        OSD_Element_FlyingTime      (  0, 1);
2127
        OSD_Element_GroundSpeed     (  0, 0);
2128
        OSD_Element_HomeCircle      ( 16, 4, 5, 0, 0,0);
2129
        OSD_Element_HomeDegree      ( 12, 4);
2130
        OSD_Element_HomeDistance    ( 10, 5, 0);
2131
        OSD_Element_Target          ( 10, 6, 0);
2132
        //OSD_Element_TargetDegree  (  x, y);
2133
        OSD_Element_WayPoint        (  5, 6);
2134
        OSD_Element_LED1Output      (  0, 6);
2135
        OSD_Element_LED2Output      (  3, 6);
2136
        //OSD_Element_Manuell       (  x, y);
2137
        OSD_Element_NaviMode        (  0, 4);
2138
        //OSD_Element_RCIntensity   (  x, y);
2139
        OSD_Element_VarioWert       ( 12, 2);
2140
        OSD_Element_SatsInUse       ( 18, 2, 0);
2141
        OSD_Element_StatusFlags     (  0, 2);
2142
        OSD_Element_Variometer      (  9, 0);
2143
 
2144
        return( ScreenName );
2145
}
2146
 
2147
 
2148
 
2149
 
2150
//--------------------------------------------------------------
2151
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 1
2152
//--------------------------------------------------------------
2153
const char * OSD_Screen_OSD1( uint8_t nMode )
2154
{
2155
        const char *ScreenName = PSTR("OSD1");
2156
        //uint8_t xoffs;
2157
 
2158
        //-----------------------------------------
2159
        // REDRAW static screen elements
2160
        //-----------------------------------------
2161
        if( nMode == OSD_SCREEN_REDRAW )
2162
        {      
2163
                // do things here for static screen elements like labels and so....
2164
    }
2165
 
2166
        //OSD_Element_AltitudeControl( x, y);
2167
        OSD_Element_Altitude        (  1, 1, 1);
2168
        OSD_Element_BatteryLevel    (  0, 7, 1);
2169
        OSD_Element_Capacity        ( 13, 7);
2170
        OSD_Element_Current         (  8, 7);
2171
        //OSD_Element_CareFree      (  x, y);
2172
        OSD_Element_CompassDegree   ( 13, 0, 1);
2173
        OSD_Element_CompassDirection( 18, 0);
2174
        OSD_Element_CompassRose     ( 12, 1);
2175
        OSD_Element_FlyingTime      (  7, 6);
2176
        OSD_Element_GroundSpeed     (  0, 0);
2177
        OSD_Element_HomeCircle      (  1, 3, 7, 0, 0,0);
2178
        OSD_Element_HomeDegree      (  8, 3);
2179
        OSD_Element_HomeDistance    (  7, 2, 1);
2180
        //OSD_Element_Target        (  x, y, 1);
2181
        //OSD_Element_TargetDegree  (  x, y);
2182
        //OSD_Element_WayPoint      (  x, y);
2183
        //OSD_Element_LED1Output    (  x, y);
2184
        //OSD_Element_LED2Output    (  x, y);
2185
        //OSD_Element_Manuell       (  x, y);
2186
        OSD_Element_NaviMode        (  8, 5);
2187
        OSD_Element_RCIntensity     ( 15, 6);
2188
        OSD_Element_VarioWert       ( 15, 2);
2189
        OSD_Element_SatsInUse       (  8, 4, 1);
2190
        //OSD_Element_StatusFlags   (  x, y);
2191
        OSD_Element_Variometer      (  9, 0);
2192
 
2193
        return( ScreenName );
2194
}
2195
 
2196
 
2197
//--------------------------------------------------------------
2198
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 2
2199
//--------------------------------------------------------------
2200
const char * OSD_Screen_OSD2( uint8_t nMode )
2201
{
2202
        const char *ScreenName = PSTR("OSD2");
2203
        //uint8_t xoffs;
2204
 
2205
        //-----------------------------------------
2206
        // REDRAW static screen elements
2207
        //-----------------------------------------
2208
        if( nMode == OSD_SCREEN_REDRAW )
2209
        {      
2210
                // do things here for static screen elements like labels and so....
2211
    }
2212
 
2213
        OSD_Element_AltitudeControl ( 0, 1);   
2214
        OSD_Element_Altitude        (  0, 4, 2);
2215
        OSD_Element_BatteryLevel    ( 13, 7, 2);
2216
        OSD_Element_Capacity        (  0, 7);
2217
        OSD_Element_Current         (  8, 7);
2218
        OSD_Element_CareFree        (  0, 3);
2219
        OSD_Element_CompassDegree   ( 12, 3, 2);
2220
        //OSD_Element_CompassDirection( x, y);
2221
        //OSD_Element_CompassRose   ( x, y);
2222
        OSD_Element_FlyingTime      ( 15, 5);
2223
        //OSD_Element_GroundSpeed   (  x, y);
2224
        OSD_Element_HomeCircle      ( 16, 0, 5, 0, 0,0);
2225
        OSD_Element_HomeDegree      ( 11, 5);
2226
        OSD_Element_HomeDistance    (  0, 5, 2);
2227
        OSD_Element_Target          (  0, 6, 2);
2228
        OSD_Element_TargetDegree    ( 11, 6);
2229
        //OSD_Element_WayPoint      (  x, y);
2230
        OSD_Element_LED1Output      ( 12, 2);
2231
        OSD_Element_LED2Output      ( 14, 2);
2232
        //OSD_Element_Manuell       (  x, y);
2233
        OSD_Element_NaviMode        (  0, 2);
2234
        //OSD_Element_RCIntensity   (  x, y);
2235
        OSD_Element_VarioWert       ( 15, 4);
2236
        OSD_Element_SatsInUse       ( 10, 0, 2);
2237
        OSD_Element_StatusFlags     (  0, 0);
2238
        //OSD_Element_Variometer    (  x, y);
2239
 
2240
        return( ScreenName );
2241
}
2242
 
2243
 
2244
//--------------------------------------------------------------
2245
//--------------------------------------------------------------
2246
const char * OSD_Screen_3DLage( uint8_t nMode )
2247
{
2248
        const char *ScreenName = PSTR("3D Lage");
2249
        uint16_t head_home;
2250
        uint8_t Nick;
2251
        uint8_t Roll;
2252
 
2253
        //-----------------------------------------
2254
        // REDRAW static screen elements
2255
        //-----------------------------------------
2256
        if( nMode == OSD_SCREEN_REDRAW )
2257
        {      
2258
                // do things here for static screen elements like labels and so....
2259
    }
2260
 
2261
        head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
2262
 
2263
        //lcd_cls ();
2264
 
2265
        lcd_line(26,32,100,32,1);  // horizontal //
2266
        lcd_line(63,0,63,63,1);    //  vertical  //
2267
        //lcd_puts_at(12, 7, strGet(KEYLINE5), 0);
2268
 
2269
        // 45' Angel
2270
        lcd_line(61,11,65,11,1);   //    --    //
2271
        lcd_line(40,30,40,34,1);   //  |       //
2272
        lcd_line(86,30,86,34,1);   //       |  //
2273
        lcd_line(61,53,65,53,1);   //    --    //
2274
 
2275
        lcd_puts_at(9, 0, strGet(OSD_3D_V), 0);  // V
2276
        lcd_puts_at(3, 3, strGet(OSD_3D_L), 0);  // L
2277
        lcd_puts_at(17, 3, strGet(OSD_3D_R), 0); // R
2278
        lcd_puts_at(9, 7, strGet(OSD_3D_H), 0);  // H
2279
 
2280
        lcd_puts_at(0, 0, strGet(OSD_3D_NICK), 0);      // Ni
2281
        write_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0,0);
2282
        lcd_putc (5, 0, 0x1e, 0);       // degree symbol
2283
 
2284
        lcd_puts_at(0, 7, strGet(OSD_3D_ROLL), 0);      // Ro
2285
        write_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0,0);
2286
        lcd_putc (5, 7, 0x1e, 0);       // degree symbol
2287
 
2288
        lcd_puts_at(13, 0, strGet(OSD_3D_COMPASS), 0);
2289
    //write_ndigit_number_s (15, 0,head_home, 3, 0);
2290
        write_ndigit_number_u (15, 0, naviData->CompassHeading, 3, 0,0);
2291
        lcd_putc (18, 0, 0x1e, 0);      // degree symbol
2292
        lcd_printp_at (19, 0, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);
2293
 
2294
        Nick = ((-naviData->AngleNick/2)+32);
2295
        Roll = ((-naviData->AngleRoll/2)+63);
2296
 
2297
        lcd_ellipse     ( old_AngleRoll, old_AngleNick, 9, 8, 0);
2298
        lcd_ellipse_line( old_AngleRoll, old_AngleNick, 8, 7, old_hh, 0);
2299
 
2300
        lcd_ellipse     ( Roll, Nick, 9, 8, 1);
2301
        lcd_ellipse_line( Roll, Nick, 8, 7, head_home, 1);
2302
 
2303
        // remember last values (3DL)
2304
        old_hh                  = head_home;
2305
        old_AngleNick   = Nick;
2306
        old_AngleRoll   = Roll;
2307
 
2308
        return( ScreenName );
2309
}
2310
 
2311
 
2312
//--------------------------------------------------------------
2313
//--------------------------------------------------------------
2314
const char * OSD_Screen_Statistics( uint8_t nMode )
2315
{
2316
        const char *ScreenName = PSTR("Statistics");
2317
        uint8_t line = 0;
2318
 
2319
        //-----------------------------------------
2320
        // REDRAW static screen elements
2321
        //-----------------------------------------
2322
        /*
2323
        if( nMode == OSD_SCREEN_REDRAW )
2324
        {      
2325
                // do things here for static screen elements like labels and so....
2326
    }
2327
    */
2328
 
2329
        //---------------------------
2330
        // max Altitude
2331
        lcd_puts_at (0, line, strGet(STATS_ITEM_0), MNORMAL);
2332
        write_ndigit_number_s (14, line, max_Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL);
2333
        lcdx_putc (18, line, 'm', MNORMAL, 2,0);
2334
 
2335
        //---------------------------
2336
        // max Speed
2337
        // max_GroundSpeed = 1;
2338
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_1), MNORMAL);
2339
        write_ndigit_number_u (15, line, (uint16_t) (((uint32_t) max_GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL);
2340
        lcdx_printp_at(18, line, PSTR("kmh"), MNORMAL, 2,0);
2341
 
2342
        //---------------------------
2343
        // max Distance
2344
        // max_Distance = 64512;
2345
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_2), MNORMAL);
2346
        write_ndigit_number_u (14, line, max_Distance / 10, 4, 0,MNORMAL);
2347
        lcdx_putc (18, line, 'm', MNORMAL, 2,0);
2348
 
2349
        //---------------------------
2350
        // max time
2351
        // max_FlyingTime = 3600;
2352
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_4), MNORMAL);
2353
        write_time (13, line, max_FlyingTime);
2354
 
2355
        //---------------------------
2356
        // min voltage
2357
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_3), MNORMAL);
2358
        if( min_UBat==255 )
2359
                lcd_printp_at(14, line, PSTR("   0"), MNORMAL);
2360
        else
2361
                write_ndigit_number_u_10th (14, line, min_UBat, 3, 0,MNORMAL);
2362
        lcdx_putc (18, line, 'V', MNORMAL, 2,0);
2363
 
2364
        //---------------------------
2365
        // max Current
2366
        // max_Current = 1000;
2367
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_5), MNORMAL);
2368
        write_ndigit_number_u_10th (13, line, max_Current, 4, 0,MNORMAL);
2369
        lcdx_putc (18, line, 'A', MNORMAL, 2,0);
2370
 
2371
        //---------------------------
2372
        // Used Capacity
2373
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_6), MNORMAL);
2374
        write_ndigit_number_u (14, line, max_Capacity, 4, 0,MNORMAL);
2375
        lcdx_printp_at(18, line, PSTR("mAh"), MNORMAL, 2,0);
2376
 
2377
        return( ScreenName );
2378
}
2379
 
2380
 
2381
//--------------------------------------------------------------
2382
//--------------------------------------------------------------
2383
void print_statistics (void)
2384
{
2385
        lcd_cls ();
2386
        lcd_puts_at(12, 7, strGet(ENDE), 0);
2387
 
2388
    OSD_Screen_Statistics( OSD_SCREEN_REDRAW );
2389
 
2390
        while (!get_key_press (1 << KEY_ESC))
2391
                timer = TIMEOUT;
2392
 
2393
        COSD_FLAGS2 &= ~COSD_WASFLYING;
2394
        get_key_press(KEY_ALL);
2395
        lcd_cls();
2396
}
2397
 
2398
 
2399
//-----------------------------------------------------------
2400
//-----------------------------------------------------------
2401
void OSD_Info( uint8_t ScreenNum, const char *ScreenName)
2402
{
2403
    lcd_frect(     0, 36, 127, 10, 0);  // clear
2404
    lcd_frect(     0, 34,   4,  4, 0);  // clear links
2405
    lcd_frect(     0, 40, 127, 24, 1);  // Box
2406
    lcd_frect(    10, 36, 108, 4, 1);   // Filler oben
2407
    lcd_fcircle(   8, 39,   7, 1);              // Links
2408
    lcd_fcircle( 121, 41,   5, 1);      // Rechts
2409
 
2410
        lcd_line (     4, 51, 122, 51, 0);  // Linie mitte
2411
 
2412
    //-----------------------
2413
    // ScreenNummer: ScreenName
2414
    //-----------------------
2415
    write_ndigit_number_s ( 1, 5, ScreenNum, 2,  1,2);
2416
    lcd_printp_at( 3, 5, PSTR(":"), 2);
2417
    lcd_printp_at( 5, 5, ScreenName, 2);
2418
 
2419
    //-----------------------
2420
    // Key's
2421
    //-----------------------
2422
    lcd_puts_at(0, 7, strGet(KEYLINE3), 2);
2423
        lcd_printp_at (17, 7, PSTR("Info"), 2);
2424
 
2425
        do
2426
        {
2427
                timer = TIMEOUT;
2428
                _delay_ms(50);
2429
        } while ( !( (get_key_press (1 << KEY_ENTER)) || (get_key_press (1 << KEY_ESC))  || (get_key_press (1 << KEY_PLUS))  || (get_key_press (1 << KEY_MINUS))  ) );
2430
}
2431
 
2432
 
2433
 
2434
//##############################################################
2435
//# OSD MAIN LOOP
2436
//##############################################################
2437
 
2438
//--------------------------------------------------------------
2439
// OSD MAIN LOOP
2440
//--------------------------------------------------------------
2441
void osd( uint8_t ShowMode )
2442
{
2443
        uint8_t flag;
2444
        uint8_t tmp_dat;
2445
        uint8_t ScreenRefresh;
2446
        uint8_t MAX_OSD_Screens;
2447
        //uint8_t status;               // FC Kommunikation
2448
 
2449
        const char *ScreenName = PSTR("");
2450
 
2451
        lcd_cls();     
2452
 
2453
    //----------------------------------------
2454
    // NC Hardware needed
2455
    //----------------------------------------
2456
        if( hardware == FC )
2457
        {
2458
                lcd_puts_at(0, 3, strGet(ONLY_NC), 0);  // Nur mit NC
2459
                timer = 100;
2460
                while (timer > 0);
2461
                return;
2462
        }
2463
 
2464
 
2465
    /*
2466
    //-----------------------------------------------------------------------------------------------
2467
    // 07.03.2013 OG: del
2468
    //   Dieser Teil hat immer wieder Probleme bereitet bei der Verbindung des PKT-OSD zum MK da
2469
    //   Timeouts zustande kamen. Eine Recherche im Code ergab, dass die Nutzdaten die
2470
    //   hierueber bezogen werden sich lediglich auf Flags_ExtraConfig beschraenkten (CFG2_HEIGHT_LIMIT).
2471
    //   Siehe dazu untere Kommentare.
2472
    //   
2473
    //   Der negative Effekt moeglicher Timeouts und Verzoegerungen sind es aktuell nicht Wert
2474
    //   CFG2_HEIGHT_LIMIT zu unterstuetzen. Dieses Feature ist erstmal raus.
2475
    //
2476
    //   Falls gewuenscht wird, dass CFG2_HEIGHT_LIMIT wieder in das PKT-OSD kommt muss
2477
    //   es zuverlaessig an anderer Stelle implementiert werden - und zwar nicht in osd.c
2478
    //   weil es eine statische FC-Information ist (ggf. beim Verbindungsaufbau PKT <-> MK).
2479
    //
2480
    //   Hat auch aktuell Auswirkung auf den Code OSD_Element_AltitudeControl()
2481
    //
2482
        lcd_printp_at( 0, 3, PSTR("connecting MK..."), 0);
2483
 
2484
    SwitchToFC();
2485
 
2486
        status = load_setting(0xff);
2487
 
2488
        if( status == 255 )
2489
        {
2490
                lcd_puts_at(0, 0, strGet(NO_SETTINGS), 0);      // Keine Settings
2491
                _delay_ms(2000);
2492
        }
2493
        Flags_ExtraConfig       = mk_param_struct->ExtraConfig;         // OG: wird in osd.c nur verwendet von: OSD_Element_AltitudeControl()
2494
        Flags_GlobalConfig      = mk_param_struct->GlobalConfig;        // OG: wird nicht in osd.c verwendet
2495
        Flags_GlobalConfig3 = mk_param_struct->GlobalConfig3;   // OG: wird nicht in osd.c verwendet
2496
        */
2497
 
2498
 
2499
    rxd_buffer_locked = FALSE;  // 07.03.2013 OG: fix
2500
                                                        //   es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den 
2501
                                                        //   OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt'
2502
 
2503
        SwitchToNC();
2504
 
2505
        mode = 'O';
2506
 
2507
        // disable debug...
2508
        //      RS232_request_mk_data (0, 'd', 0);
2509
        tmp_dat         = 0;
2510
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
2511
 
2512
        // request OSD Data from NC every 100ms
2513
        //      RS232_request_mk_data (1, 'o', 100);
2514
        tmp_dat         = 10;
2515
    OSD_active  = true;              // benoetigt für Navidata Ausgabe an SV2
2516
        SendOutData( 'o', ADDRESS_NC, 1,  &tmp_dat, 1);
2517
 
2518
 
2519
        //-------------------------
2520
        // Clear statistics
2521
        //-------------------------
2522
        max_Altimeter     = 0;
2523
        max_GroundSpeed   = 0;
2524
        max_Distance      = 0;
2525
        min_UBat          = 255;
2526
        max_FlyingTime    = 0;
2527
        CellIsChecked     = 0;
2528
        cells             = 0;
2529
        AkkuWarnThreshold = 0;
2530
        OldWP             = 0;
2531
        NextWP            = false;
2532
 
2533
 
2534
        //-------------------------
2535
        //-------------------------
2536
        MAX_OSD_Screens = 8;
2537
 
2538
        #ifdef OSD_DEBUG_SCREEN
2539
                MAX_OSD_Screens += 1;
2540
    #endif
2541
 
2542
        if( Config.OSD_ScreenMode >= MAX_OSD_Screens ) Config.OSD_ScreenMode = 0;
2543
 
2544
 
2545
        //-------------------------
2546
        // Timer & Flags
2547
        //-------------------------
2548
        ScreenRefresh   = OSD_SCREEN_REDRAW;
2549
        flag                    = 0;
2550
        timer                   = TIMEOUT;
2551
        abo_timer               = ABO_TIMEOUT;
2552
        timer2                  = OSD_REFRESH_TIME;
2553
 
2554
 
2555
        do
2556
        {
2557
                if( rxd_buffer_locked )
2558
                {
2559
                        timer = TIMEOUT;
2560
                        Decode64 ();
2561
                        naviData = (NaviData_t *) pRxData;
2562
 
2563
 
2564
                        //----------------------------------
2565
                // Winkel zu Home
2566
                        //----------------------------------
2567
                if( Config.OSD_HomeMKView == 1 )
2568
                        heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
2569
                else
2570
                        heading_home = (naviData->CompassHeading - naviData->HomePositionDeviation.Bearing + 360 ) % 360;
2571
 
2572
 
2573
                        //----------------------------------
2574
                        // speichere letzte GPS-Positionen
2575
                        //----------------------------------
2576
                        GPS_Pos_t currpos;
2577
                        currpos.Latitude  = naviData->CurrentPosition.Latitude;
2578
                        currpos.Longitude = naviData->CurrentPosition.Longitude;
2579
 
2580
                        if((currpos.Latitude != last5pos[0].Latitude)&&(currpos.Longitude != last5pos[0].Longitude))
2581
                        {
2582
                                last5pos[6] = last5pos[5];
2583
                                last5pos[5] = last5pos[4];
2584
                                last5pos[4] = last5pos[3];
2585
                                last5pos[3] = last5pos[2];
2586
                                last5pos[2] = last5pos[1];
2587
                                last5pos[1] = last5pos[0];
2588
                                last5pos[0] = currpos;
2589
                        }
2590
 
2591
                        // 07.03.2013 OG: Speichere permanent letzte Position in Config
2592
                        //   wurde vorher nur in OSD_TimeOut() gemacht
2593
                        Config.LastLatitude  = currpos.Latitude;        // speichere letzte Position in Config
2594
                        Config.LastLongitude = currpos.Longitude;       // speichere letzte Position in Config
2595
 
2596
                        flag = 1;
2597
 
2598
                        if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN)
2599
                        { // should be engines running
2600
                                // motors are on, assume we were/are flying
2601
                                COSD_FLAGS2 |= COSD_WASFLYING;
2602
                        }
2603
 
2604
 
2605
                        //----------------------------------
2606
                        // remember statistics (only when engines running)
2607
                        //----------------------------------
2608
                        if( naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN )
2609
                        {
2610
                                if (naviData->Altimeter > max_Altimeter)                                                max_Altimeter   = naviData->Altimeter;
2611
                                if (naviData->GroundSpeed > max_GroundSpeed)                                    max_GroundSpeed = naviData->GroundSpeed;
2612
                                if (naviData->HomePositionDeviation.Distance > max_Distance)    max_Distance    = naviData->HomePositionDeviation.Distance;
2613
                                if (naviData->FlyingTime > max_FlyingTime)                                              max_FlyingTime  = naviData->FlyingTime;
2614
                                if (naviData->UBat < min_UBat)                                                                  min_UBat                = naviData->UBat;
2615
                                if (naviData->Current > max_Current)                                                    max_Current     = naviData->Current;
2616
                                if (naviData->UsedCapacity > max_Capacity)                                              max_Capacity    = naviData->UsedCapacity;
2617
                        }
2618
 
2619
 
2620
                        //----------------------------------
2621
                        // OSD-Screens
2622
                        //----------------------------------
2623
                        if( ScreenRefresh == OSD_SCREEN_REDRAW )        lcd_cls();
2624
 
2625
                        if( timer2 == 0 || ScreenRefresh == OSD_SCREEN_REDRAW)
2626
                        {      
2627
                                if(      Config.OSD_ScreenMode == 0)    ScreenName = OSD_Screen_General( ScreenRefresh );
2628
                                else if( Config.OSD_ScreenMode == 1)    ScreenName = OSD_Screen_Navigation( ScreenRefresh );
2629
                                else if( Config.OSD_ScreenMode == 2)    ScreenName = OSD_Screen_MKStatus( ScreenRefresh );
2630
                                else if( Config.OSD_ScreenMode == 3)    ScreenName = OSD_Screen_OSD0( ScreenRefresh );
2631
                                else if( Config.OSD_ScreenMode == 4)    ScreenName = OSD_Screen_OSD1( ScreenRefresh );
2632
                                else if( Config.OSD_ScreenMode == 5)    ScreenName = OSD_Screen_OSD2( ScreenRefresh );
2633
                                else if( Config.OSD_ScreenMode == 6)    ScreenName = OSD_Screen_3DLage( ScreenRefresh );
2634
                                else if( Config.OSD_ScreenMode == 7)    ScreenName = OSD_Screen_Statistics( ScreenRefresh );
2635
 
2636
                #ifdef OSD_DEBUG_SCREEN 
2637
                                else if( Config.OSD_ScreenMode == (MAX_OSD_Screens-1) ) ScreenName = OSD_Screen_Debug( ScreenRefresh );
2638
                #endif
2639
 
2640
            }
2641
                        ScreenRefresh = OSD_SCREEN_REFRESH;
2642
 
2643
                        if( timer2 == 0 ) timer2 = OSD_REFRESH_TIME;
2644
 
2645
 
2646
                        //-----------------------
2647
                        // Key-Handler
2648
                        //-----------------------
2649
 
2650
                        //if (get_key_press (1 << KEY_PLUS))
2651
                        //{
2652
                        //      print_position ();
2653
                        //}
2654
 
2655
                        if( get_key_press (1 << KEY_ENTER) )            // info
2656
                        {
2657
                                OSD_Info( Config.OSD_ScreenMode, ScreenName);
2658
                                ScreenRefresh = OSD_SCREEN_REDRAW;
2659
                        }
2660
 
2661
                        if (get_key_press (1 << KEY_MINUS))             // previous screen
2662
            {
2663
                                if( Config.OSD_ScreenMode == 0 )
2664
                                  Config.OSD_ScreenMode = MAX_OSD_Screens-1;
2665
                                else  
2666
                                  Config.OSD_ScreenMode--;                             
2667
                                ScreenRefresh = OSD_SCREEN_REDRAW;
2668
                        }
2669
 
2670
                        if (get_key_press (1 << KEY_PLUS))              // next Screen
2671
            {
2672
                                Config.OSD_ScreenMode++;
2673
                                Config.OSD_ScreenMode = ( Config.OSD_ScreenMode >= MAX_OSD_Screens ? 0 : Config.OSD_ScreenMode );
2674
                                ScreenRefresh = OSD_SCREEN_REDRAW;
2675
                        }
2676
 
2677
 
2678
                        //-----------------------
2679
                        // Akku Warnung
2680
                        //-----------------------
2681
            CheckMKLipo();
2682
 
2683
//                      if (naviData->UBat > MK_LowBat)  //bei kurzzeitigen Schwankungen Beeper erst wieder aus wenn UBat 0,2 V höher als Warnschwelle
2684
//                      { //Beeper aus
2685
//                              BeepTime = 0;
2686
//                              BeepMuster = 0xFFFF;
2687
//                      }
2688
//                       Akku Warnung Ende
2689
 
2690
 
2691
                        //-----------------------
2692
                        // remember last values
2693
                        //-----------------------
2694
                        last_RC_Quality = naviData->RC_Quality;
2695
                        last_UBat               = naviData->UBat;
2696
                        old_FCFlags     = naviData->FCStatusFlags;
2697
 
2698
                        rxd_buffer_locked = FALSE;
2699
 
2700
 
2701
                        //-----------------------
2702
                        // abo_timer
2703
                        //-----------------------
2704
                        if (!abo_timer)
2705
                        {       // renew abo every 3 sec
2706
                                // request OSD Data from NC every 100ms
2707
                                //      RS232_request_mk_data (1, 'o', 100);
2708
                                tmp_dat = 10;
2709
                                SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
2710
                                abo_timer = ABO_TIMEOUT;
2711
                        }
2712
 
2713
                } //if (rxd_buffer_locked)
2714
 
2715
                if (!timer)
2716
                {
2717
                        OSD_Timeout(flag);
2718
                        flag  = 0;
2719
                        ScreenRefresh = OSD_SCREEN_REDRAW;
2720
                }
2721
 
2722
        } while (!get_key_press (1 << KEY_ESC));
2723
 
2724
        OSD_active = false;
2725
}