Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1517 - 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
#include "cpu.h"
36
#include <avr/io.h>
37
#include <inttypes.h>
38
#include <stdlib.h>
39
#include <avr/pgmspace.h>
40
#include <util/delay.h>
41
 
42
#include "main.h"
43
#include "osd.h"
44
#include "lcd.h"
45
#include "timer.h"
46
#include "usart.h"
47
#include "eeprom.h"
48
#include "messages.h"
49
 
50
#include "mk-data-structs.h"
51
 
52
#define COSD_WASFLYING 4
53
#define TIMEOUT 200     // 2 sec
54
 
55
// global definitions and global vars
56
NaviData_t *naviData;
57
 
58
// löschen und alle mit "naviData->Variometer" ersetzen
59
//int8_t Variometer = 0;
60
 
61
// Hier Höhenanzeigefehler Korrigieren
62
#define AltimeterAdjust 1.5
63
 
64
// stats for after flight
65
int16_t max_Altimeter = 0;
66
uint16_t max_GroundSpeed = 0;
67
int16_t max_Distance = 0;
68
uint8_t min_UBat = 255;
69
uint16_t max_FlyingTime = 0;
70
uint16_t max_Current = 0;
71
uint16_t max_Capacity = 0;
72
 
73
// cache old vars for blinking attribute, checkup is faster than full
74
// attribute write each time
75
volatile uint8_t last_UBat = 255;
76
volatile uint8_t last_RC_Quality = 255;
77
 
78
volatile uint16_t ftimer = 0;
79
 
80
// store stats description in progmem to save space
81
const char stats_item_0[] PROGMEM = "max Altitude:";
82
const char stats_item_1[] PROGMEM = "max Speed   :";
83
const char stats_item_2[] PROGMEM = "max Distance:";
84
const char stats_item_3[] PROGMEM = "min Voltage :";
85
const char stats_item_4[] PROGMEM = "max Time    :";
86
#if 1
87
const char stats_item_5[] PROGMEM = "max Current :";
88
const char stats_item_6[] PROGMEM = "UsedCapacity:";
89
#else
90
const char stats_item_5[] PROGMEM = "Long. :";
91
const char stats_item_6[] PROGMEM = "Lat.  :";
92
#endif
93
 
94
 
95
const char *stats_item_pointers[] PROGMEM = {
96
        stats_item_0,
97
        stats_item_1,
98
        stats_item_2,
99
        stats_item_3,
100
        stats_item_4,
101
        stats_item_5,
102
        stats_item_6
103
};
104
 
105
//char* rose = "-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W";
106
const char rose[48] PROGMEM = {
107
        0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S',
108
        0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O',
109
        0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N',
110
        0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W',
111
};
112
 
113
// the center is char 19 (north), we add the current heading in 8th
114
// which would be 22.5 degrees, but float would bloat up the code
115
// and *10 / 225 would take ages... so we take the uncorrect way
116
 
117
const char str_NE[] PROGMEM = "NE";
118
const char str_E[] PROGMEM  = "E ";
119
const char str_SE[] PROGMEM = "SE";
120
const char str_S[] PROGMEM  = "S ";
121
const char str_SW[] PROGMEM = "SW";
122
const char str_W[] PROGMEM  = "W ";
123
const char str_NW[] PROGMEM = "NW";
124
const char str_N[] PROGMEM  = "N ";
125
const char *directions_p[8] PROGMEM = {
126
        str_NE,
127
        str_E,
128
        str_SE,
129
        str_S,
130
        str_SW,
131
        str_W,
132
        str_NW,
133
        str_N
134
};
135
 
136
// Flags
137
uint8_t COSD_FLAGS2 = 0;
138
 
139
GPS_Pos_t last5pos[7];
140
uint8_t error = 0;
141
 
142
 
143
//--------------------------------------------------------------
144
// convert the <heading> gotton from NC into an index
145
uint8_t heading_conv (uint16_t heading)
146
{
147
        if (heading > 23 && heading < 68)
148
                return 0;               //direction = "NE";
149
        else if (heading > 67 && heading < 113)
150
                return 1;               //direction = "E ";
151
        else if (heading > 112 && heading < 158)
152
                return 2;               //direction = "SE";
153
        else if (heading > 157 && heading < 203)
154
                return 3;               //direction = "S ";
155
        else if (heading > 202 && heading < 248)
156
                return 4;               //direction = "SW";
157
        else if (heading > 247 && heading < 293)
158
                return 5;               //direction = "W ";
159
        else if (heading > 292 && heading < 338)
160
                return 6;               //direction = "NW";
161
 
162
        return 7;       //direction = "N ";
163
}
164
 
165
//--------------------------------------------------------------
166
// draw a compass rose at <x>/<y> for <heading>
167
void draw_compass (uint8_t x, uint8_t y, uint16_t heading)
168
{
169
        uint8_t front = 19 + (heading / 22);
170
        for (uint8_t i = 0; i < 9; i++)
171
                lcd_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), 0);
172
}
173
 
174
 
175
//--------------------------------------------------------------
176
// variometer
177
// draw variometer arrows at <x>/<y> according to <variometer>
178
//
179
void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
180
{
181
        lcd_rect (x, y - ((hight) / 2), width, hight, 1);
182
        lcd_frect (x + 1, y - ((hight) / 2) + 1, width - 2, hight - 2, 0);
183
        lcd_line (x, y, x + width, y, 1);
184
 
185
        if (variometer > 0)  // steigend
186
        {
187
                switch (variometer / 5)
188
                {
189
                        case 0:
190
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
191
                        break;
192
 
193
                        case 1:
194
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
195
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
196
                        break;
197
 
198
                        case 2:
199
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
200
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
201
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
202
                        break;
203
 
204
                        default:
205
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);  //  1 >  4
206
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
207
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
208
                                lcd_frect (x + 1, y - 6, 8, 1, 1);                      // 15 >
209
                        break;
210
                }
211
        }
212
        else if (variometer < 0)  // fallend
213
        {
214
                switch ((variometer) / -5)
215
                {
216
                        case 0:
217
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
218
                        break;
219
 
220
                        case 1:
221
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
222
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
223
                        break;
224
 
225
                        case 2:
226
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
227
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
228
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
229
                        break;
230
 
231
                        default:
232
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
233
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
234
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
235
                                lcd_frect (x + 1, y + 5, 8, 1, 1);                      // -15 >
236
                        break;
237
                }
238
        }
239
}
240
 
241
 
242
//--------------------------------------------------------------
243
void print_statistics (void)
244
{
245
        uint8_t line = 0;
246
        lcd_cls ();
247
//      lcd_printp_at (12, 7, PSTR("Ende"), 0);
248
        lcd_puts_at(12, 7, strGet(ENDE), 0);
249
 
250
        // max Altitude
251
        lcd_printp_at (0, line, stats_item_pointers[0], 0);
252
        write_ndigit_number_s (13, line, max_Altimeter / (30 / AltimeterAdjust), 4, 0);
253
        lcd_putc (17, line, 'm', 0);
254
 
255
        // max Speed
256
        lcd_printp_at (0, ++line, stats_item_pointers[1], 0);
257
        write_ndigit_number_u (14, line, (uint16_t) (((uint32_t) max_GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0);
258
        lcd_printp_at(17, line, PSTR("km/h"), 0);
259
 
260
        // max Distance
261
        lcd_printp_at (0, ++line, stats_item_pointers[2], 0);
262
        write_ndigit_number_u (14, line, max_Distance / 10, 3, 0);
263
        lcd_putc (17, line, 'm', 0);
264
 
265
        // max time
266
        lcd_printp_at (0, ++line, stats_item_pointers[4], 0);
267
        write_time (13, line, max_FlyingTime);
268
 
269
        // min voltage
270
        lcd_printp_at (0, ++line, stats_item_pointers[3], 0);
271
        write_ndigit_number_u_10th (13, line, min_UBat, 3, 0);
272
        lcd_putc (17, line, 'V', 0);
273
 
274
#if 1
275
        // max Current
276
        lcd_printp_at (0, ++line, stats_item_pointers[5], 0);
277
        write_ndigit_number_u_10th (13, line, max_Current, 3, 0);
278
        lcd_putc (17, line, 'A', 0);
279
 
280
        // Used Capacity
281
        lcd_printp_at (0, ++line, stats_item_pointers[6], 0);
282
        write_ndigit_number_u (13, line, max_Capacity, 4, 0);
283
        lcd_printp_at(17, line, PSTR("mAh"), 0);
284
#else
285
        // longitude
286
        lcd_printp_at (0, ++line, stats_item_pointers[5], 0);
287
        write_gps_pos (8, line, naviData->CurrentPosition.Longitude);
288
 
289
        // latitude
290
        lcd_printp_at (0, ++line, stats_item_pointers[6], 0);
291
        write_gps_pos (8, line, naviData->CurrentPosition.Latitude);
292
#endif
293
 
294
        while (!get_key_press (1 << KEY_ESC))
295
                timer = TIMEOUT;
296
 
297
        COSD_FLAGS2 &= ~COSD_WASFLYING;
298
        get_key_press(KEY_ALL);
299
        lcd_cls();
300
}
301
 
302
//--------------------------------------------------------------
303
void print_position (void)
304
{
305
        lcd_cls ();
306
//      lcd_printp_at (0, 0, PSTR(" Breitengr  Längengr "), 2);
307
        lcd_puts_at(0, 0, strGet(START_LASTPOS1), 2);
308
//      lcd_printp_at (12, 7, PSTR("Ende"), 0);
309
        lcd_puts_at(12, 7, strGet(ENDE), 0);
310
        uint8_t ij =0;
311
 
312
        for(ij=0;ij<6;ij++)
313
        {
1518 - 314
                uint32_t lon = last5pos[ij].Latitude;
1517 - 315
                write_ndigit_number_u (1, ij+1, (uint16_t)(lon/10000000), 2, 0);
316
                lcd_printp_at (3, ij+1, PSTR("."), 0);
317
                write_ndigit_number_u (4, ij+1, (uint16_t)((lon/1000) % 10000), 4, 1);
318
                write_ndigit_number_u (8, ij+1, (uint16_t)((lon/10) % 100), 2, 1);
319
 
1518 - 320
                uint32_t lat = last5pos[ij].Longitude;
1517 - 321
                write_ndigit_number_u (12, ij+1, (uint16_t)(lat/10000000), 2, 0);
322
                lcd_printp_at (14, ij+1, PSTR("."), 0);
323
                write_ndigit_number_u (15, ij+1, (uint16_t)((lat/1000) % 10000), 4, 1);
324
                write_ndigit_number_u (19, ij+1, (uint16_t)((lat/10) % 100), 2, 1);
325
        }
326
 
327
        while (!get_key_press (1 << KEY_ESC))
328
                timer = TIMEOUT;
329
 
330
        get_key_press(KEY_ALL);
331
        lcd_cls();
332
}
1518 - 333
void Show_LastPosition(void)
334
{
1525 - 335
  lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
336
  lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
1518 - 337
  lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
338
  uint32_t lon = last5pos[0].Latitude;
339
  write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
340
  lcd_printp_at (3, 6, PSTR("."), 0);
341
  write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
342
  write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
1517 - 343
 
1518 - 344
  uint32_t lat = last5pos[0].Longitude;
345
  write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
346
  lcd_printp_at (14, 6, PSTR("."), 0);
347
  write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
348
  write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
1517 - 349
 
1518 - 350
}
351
 
352
void OSD_Timeout(uint8_t flag)
353
{
354
 
355
//  uint8_t flag;
356
  uint8_t tmp_dat;
357
 // flag = 0;
358
  timer = TIMEOUT;
359
  // disable OSD Data from NC
360
  //      RS232_request_mk_data (1, 'o', 0);
361
//  tmp_dat = 0;
362
//  SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
363
 
364
  mode = 0;
365
  rxd_buffer_locked = FALSE;
366
 
367
 
368
  // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
369
//  if (!timer)
370
//  {       // timeout occured
371
          if (flag)
372
          {
373
                  // Falls Spannungswarnung an war Beeper aus//
374
                  BeepTime = 0;
375
                  BeepMuster = 0xFFFF;
376
 
377
                  lcd_cls ();
378
                  WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
379
                  lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
380
 
381
//                      lcd_printp_at (0, 0, PSTR(" ERROR: Datenverlust "), 2);
382
 
383
//                      lcd_printp_at (0, 2, PSTR("Letzte bekannte"), 0);
384
//                      lcd_printp_at (0, 3, PSTR("Position gespeichert."), 0);
385
                  lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
386
                  lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
387
//                      lcd_printp_at (19, 7, PSTR("OK"), 0);
388
                  lcd_puts_at(19, 7, strGet(OK), 0);
389
//                      lcd_printp_at (0, 5, PSTR(" Breitengr  Längengr "), 0);
390
 
391
                  lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
392
 
393
                  lcd_puts_at(12, 7, strGet(ENDE), 0);
394
 
395
                  BeepTime = 250;
396
                  BeepMuster = 0x0080;
397
                  error = 1;
398
 
399
                  uint32_t lon = last5pos[0].Latitude;
400
                  write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
401
                  lcd_printp_at (3, 6, PSTR("."), 0);
402
                  write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
403
                  write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
404
 
405
                  uint32_t lat = last5pos[0].Longitude;
406
                  write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
407
                  lcd_printp_at (14, 6, PSTR("."), 0);
408
                  write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
409
                  write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
410
 
411
//                  while (!get_key_press (1 << KEY_ENTER));
412
                  _delay_ms(1000);
413
                  timer = TIMEOUT;
414
                  lcd_cls();
415
//                  return;
416
 
417
 
418
          }
419
          else
420
            {
421
              lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
422
              Show_LastPosition();
423
              BeepTime = 250;
424
              BeepMuster = 0x0080;
425
            }
426
//  }
427
                  SwitchToNC();
428
 
429
                  mode = 'O';
430
 
431
                  // disable debug...
432
                  //      RS232_request_mk_data (0, 'd', 0);
433
                  tmp_dat = 0;
434
                  SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
435
 
436
                  // request OSD Data from NC every 100ms
437
                  //      RS232_request_mk_data (1, 'o', 100);
438
                  tmp_dat = 10;
439
                  SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
440
 
441
 
442
}
443
 
444
 
445
 
446
 
1517 - 447
//--------------------------------------------------------------
448
void osd (uint8_t ShowMode)
449
{
450
        uint8_t flag;
451
        uint8_t tmp_dat;
452
        uint8_t OSD_Mode;
453
        uint8_t info_3D = 0;
454
 
455
        // Clear statistics
456
        max_Altimeter = 0;
457
        max_GroundSpeed = 0;
458
        max_Distance = 0;
459
        min_UBat = 255;
460
        max_FlyingTime = 0;
461
 
462
        // flags from last round to check for changes
463
        uint8_t old_FCFlags = 0;
464
 
465
        uint16_t old_hh = 0;
466
        uint8_t old_AngleNick = 0;
467
        uint8_t old_AngleRoll = 0;
1518 - 468
        lcd_cls();
1517 - 469
        OSD_Mode = ShowMode;
470
 
1518 - 471
//      if(error == 0)
472
//              lcd_cls();
1517 - 473
 
474
        if (hardware == FC)
475
        {
476
                lcd_printp_at(0, 3, PSTR("Only with NC !"), 0);
477
                timer = 100;
478
                while (timer > 0);
479
 
480
                return;
481
        }
482
 
483
        SwitchToNC();
484
 
485
        mode = 'O';
486
 
487
        // disable debug...
488
        //      RS232_request_mk_data (0, 'd', 0);
489
        tmp_dat = 0;
490
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
491
 
492
        // request OSD Data from NC every 100ms
493
        //      RS232_request_mk_data (1, 'o', 100);
494
        tmp_dat = 10;
495
        SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
496
 
497
        flag = 0;
498
        timer = TIMEOUT;
499
        abo_timer = ABO_TIMEOUT;
500
 
501
 
502
        do
503
        {
504
                if (rxd_buffer_locked)
505
                {
506
                        timer = TIMEOUT;
507
                        Decode64 ();
508
                        naviData = (NaviData_t *) pRxData;
509
 
510
                        if(error == 1)
511
                                lcd_cls();
512
 
513
                        error = 0;
514
                        GPS_Pos_t currpos;
515
                        currpos.Latitude = naviData->CurrentPosition.Latitude;
516
                        currpos.Longitude = naviData->CurrentPosition.Longitude;
517
 
518
                        if((currpos.Latitude != last5pos[0].Latitude)&&(currpos.Longitude != last5pos[0].Longitude))
519
                        {
520
                                last5pos[6] = last5pos[5];
521
                                last5pos[5] = last5pos[4];
522
                                last5pos[4] = last5pos[3];
523
                                last5pos[3] = last5pos[2];
524
                                last5pos[2] = last5pos[1];
525
                                last5pos[1] = last5pos[0];
526
                                last5pos[0] = currpos;
527
                        }
528
 
529
                        flag = 1;
530
 
531
                        if (OSD_Mode == 1)
532
                        {
533
                                if (naviData->FCFlags & FCFLAG_MOTOR_RUN)
534
                                { // should be engines running
535
                                        // motors are on, assume we were/are flying
536
                                        COSD_FLAGS2 |= COSD_WASFLYING;
537
                                }
538
                                else
539
                                {       // stats
540
                                        if ((COSD_FLAGS2 & COSD_WASFLYING) | (get_key_press (1 << KEY_ENTER)))
541
                                                print_statistics ();
542
 
543
                                        if (get_key_press (1 << KEY_PLUS))
544
                                                print_position ();
545
                                }
546
 
547
                                lcd_ecircle(22, 35, 16, 1);
548
 
549
                                // Ground Speed
550
                                write_ndigit_number_u (1, 0, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0);
551
                                lcd_printp_at(4, 0, PSTR("km/h"), 0);
552
 
553
                                // Compass
554
                                write_ndigit_number_u (14, 0, naviData->CompassHeading, 3, 0);
555
                                lcd_putc (17, 0, 0x1E, 0);      // degree symbol
556
                                lcd_printp_at (18, 0, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);
557
 
558
                                draw_compass (12, 1, naviData->CompassHeading);
559
 
560
                                // Altitude
561
                                //note:lephisto:according to several sources it's /30
562
                                if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
563
                                        write_ndigit_number_s (0, 1, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0);
564
                                else    // up to 10m write meters.dm
565
                                        write_ndigit_number_s_10th (0, 1, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0);
566
 
567
                                lcd_putc (4, 1, 'm', 0);
568
 
569
                                draw_variometer (54, 7, 10, 14, naviData->Variometer);
570
 
571
                                // TODO: verify correctness
572
                                uint16_t heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
573
                                lcd_ecirc_line (22, 35, 15, old_hh, 0);
574
                                old_hh = heading_home;
575
                                lcd_ecirc_line (22, 35, 15, heading_home, 1);
576
 
577
                                write_ndigit_number_u (7, 3, heading_home, 3, 0);
578
                                lcd_putc (10, 3, 0x1e, 0);      // degree symbol
579
 
580
                                write_ndigit_number_u (7, 2, naviData->HomePositionDeviation.Distance / 10, 3, 0);
581
                                lcd_putc (10, 2, 'm', 0);
582
 
583
                                // Sats in use
584
                                lcd_printp_at(11, 4, PSTR("Sats"), 0);
585
                                write_ndigit_number_u (8, 4, naviData->SatsInUse, 2, 0);
586
 
587
                                if (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL)
588
                                        lcd_putc (19, 4, 'M', 0); // rc transmitter
589
                                else
590
                                        lcd_putc (19, 4, 'X', 0); // clear
591
 
592
                                if (naviData->NCFlags & NC_FLAG_CH)
593
                                        lcd_printp_at (8, 5, PSTR("Coming Home"), 0);
594
                                else if (naviData->NCFlags & NC_FLAG_PH)
595
                                        lcd_printp_at (8, 5, PSTR("Pos. Hold  "), 0);
596
                                else    // (naviData->NCFlags & NC_FLAG_FREE)
597
                                        lcd_printp_at (8, 5, PSTR("Free       "), 0);
598
 
599
                                // Flying time
600
                                write_time (7, 6, naviData->FlyingTime);
601
                                lcd_printp_at (12, 6, PSTR("h"), 0);
602
 
603
                                // RC
604
                                write_ndigit_number_u (15, 6, naviData->RC_Quality, 3, 0);
605
                                lcd_printp_at(18, 6, PSTR("\x1F"), 0);          // RC-transmitter
606
                                if (naviData->NCFlags & NC_FLAG_NOSERIALLINK)
607
                                {
608
                                        lcd_printpns_at(19, 6, PSTR("  "), 0);          // clear
609
                                }
610
                                else
611
                                {
612
                                        lcd_printpns_at(19, 6, PSTR("PC"), 0);
613
                                }
614
 
615
                                // Battery level
616
                                write_ndigit_number_u_10th (0, 7, naviData->UBat, 3, 0);
617
                                lcd_putc (4, 7, 'V', 0);
618
 
619
                                // Akku Warnung
620
                                if (naviData->UBat < MK_LowBat)
621
                                { //Beeper ein
622
                                        BeepTime = 3000;
623
                                        BeepMuster = 0x0020;
624
                                }
625
 
626
                                //if (naviData->UBat > MK_LowBat+2)  //bei kurzzeitigen Schwankungen Beeper erst wieder aus wenn UBat 0,2 V höher als Warnschwelle
627
                                //{ //Beeper aus
628
                                //      BeepTime = 0;
629
                                //      BeepMuster = 0xFFFF;
630
                                //}
631
                                // Akku Warnung Ende
632
 
633
                                // Current
634
                                write_ndigit_number_u_10th (7, 7, naviData->Current, 3, 0);
635
                                lcd_putc (11, 7, 'A', 0);
636
 
637
                                // Capacity
638
                                write_ndigit_number_u (14, 7, naviData->UsedCapacity, 4, 0);
639
                                lcd_printp_at(18, 7, PSTR("mAh"), 0);
640
 
641
                                // remember statistics (only when engines running)
642
                                if (naviData->FCFlags & FCFLAG_MOTOR_RUN)
643
                                {
644
                                        if (naviData->Altimeter > max_Altimeter) max_Altimeter = naviData->Altimeter;
645
                                        if (naviData->GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData->GroundSpeed;
646
                                        if (naviData->HomePositionDeviation.Distance > max_Distance) max_Distance = naviData->HomePositionDeviation.Distance;
647
                                        if (naviData->UBat < min_UBat) min_UBat = naviData->UBat;
648
                                        if (naviData->FlyingTime > max_FlyingTime) max_FlyingTime = naviData->FlyingTime;
649
                                        if (naviData->Current > max_Current) max_Current = naviData->Current;
650
                                        if (naviData->UsedCapacity > max_Capacity) max_Capacity = naviData->UsedCapacity;
651
                                }
652
 
653
                                // remember last values
654
                                last_RC_Quality = naviData->RC_Quality;
655
                                last_UBat = naviData->UBat;
656
                                old_FCFlags = naviData->FCFlags;
657
 
658
                                rxd_buffer_locked = FALSE;
659
                        }
660
        // 3D Lage anzeige beginnt hier -----------------------------------
661
                        else if (OSD_Mode == 3)
662
                        {
663
                                uint16_t head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
664
 
665
                                lcd_cls ();
666
 
667
                                lcd_line(0,32,128,32,1);   // horizontal //
668
                                lcd_line(64,0,64,64,1);    // vertical   //
669
                                lcd_printp_at(12, 7, PSTR("End  Info"), 0);
670
 
671
 
672
                                // 45' Angel
673
                                lcd_line(62,11,66,11,1);   //    --    //
674
                                lcd_line(22,30,22,34,1);   //  |       //
675
                                lcd_line(106,30,106,34,1); //       |  //
676
                                lcd_line(62,53,66,53,1);   //    --    //
677
 
678
                                if (info_3D == 1)
679
                                {
680
                                        lcd_line(34,17,36,15,1);   //  /       //
681
                                        lcd_line(92,15,94,17,1);   //       \  //
682
                                        lcd_line(34,47,36,49,1);   //  \       //
683
                                        lcd_line(92,49,94,47,1);   //       /  //
684
 
685
//                                      lcd_printp_at(9, 0, PSTR("V"), 0);
686
//                                      lcd_printp_at(0, 3, PSTR("L"), 0);
687
//                                      lcd_printp_at(20, 3, PSTR("R"), 0);
688
//                                      lcd_printp_at(9, 7, PSTR("H"), 0);
689
 
690
                                        lcd_puts_at(9, 0, strGet(OSD_V), 0);
691
                                        lcd_puts_at(0, 3, strGet(OSD_L), 0);
692
                                        lcd_puts_at(20, 3, strGet(OSD_R), 0);
693
                                        lcd_puts_at(9, 7, strGet(OSD_H), 0);
694
 
695
                                        lcd_printp_at(0, 0, PSTR("N:"), 0);
696
                                        write_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0);
697
 
698
                                        lcd_printp_at(0, 7, PSTR("R:"), 0);
699
                                        write_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0);
700
 
701
                                        lcd_printp_at(15, 0, PSTR("K:"), 0);
702
                                        write_ndigit_number_s (18, 0,head_home, 3, 0);
703
                                }
704
 
705
                                if (get_key_press (1 << KEY_ENTER))
706
                                {
707
                                        info_3D++;
708
                                        if (info_3D > 1)
709
                                                info_3D = 0;
710
                                }
711
 
712
                                uint8_t Nick = ((-naviData->AngleNick/2)+32);
713
                                uint8_t Roll = -naviData->AngleRoll+64;
714
                                lcd_ecircle(old_AngleRoll,old_AngleNick, 10, 0);
715
                                lcd_ecirc_line (old_AngleRoll, old_AngleNick, 9, old_hh, 0);
716
 
717
                                lcd_ecircle(Roll, Nick, 10, 1);
718
                                lcd_ecirc_line (Roll, Nick, 9, head_home, 1);
719
 
720
                                old_hh = head_home;
721
                                old_AngleNick = Nick;
722
                                old_AngleRoll = Roll;
723
                                // remember last values
724
                                last_RC_Quality = naviData->RC_Quality;
725
                                last_UBat = naviData->UBat;
726
                                old_FCFlags = naviData->FCFlags;
727
                                rxd_buffer_locked = FALSE;
728
                        }
729
 
730
                        if (!abo_timer)
731
                        {       // renew abo every 3 sec
732
                                // request OSD Data from NC every 100ms
733
                                //      RS232_request_mk_data (1, 'o', 100);
734
                                tmp_dat = 10;
735
                                SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
736
 
737
                                abo_timer = ABO_TIMEOUT;
738
                        }
739
                }
1518 - 740
            if (!timer)
741
              {
742
                OSD_Timeout(flag);
743
                flag = 0;
744
              }
1517 - 745
        }
746
 
1518 - 747
        while (!get_key_press (1 << KEY_ESC));
748
//        while (!get_key_press (1 << KEY_ESC) && timer);
749
//      get_key_press(KEY_ALL);
750
//
751
//
752
//      // disable OSD Data from NC
753
//      //      RS232_request_mk_data (1, 'o', 0);
754
//      tmp_dat = 0;
755
//      SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
756
//
757
//      mode = 0;
758
//      rxd_buffer_locked = FALSE;
759
//
760
//
761
//      // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
762
//      if (!timer)
763
//      {       // timeout occured
764
//              if (flag)
765
//              {
766
//                      // Falls Spannungswarnung an war Beeper aus//
767
//                      BeepTime = 0;
768
//                      BeepMuster = 0xFFFF;
769
//
770
//                      lcd_cls ();
771
//                      WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
772
//                      lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
773
//
774
////                    lcd_printp_at (0, 0, PSTR(" ERROR: Datenverlust "), 2);
775
//
776
////                    lcd_printp_at (0, 2, PSTR("Letzte bekannte"), 0);
777
////                    lcd_printp_at (0, 3, PSTR("Position gespeichert."), 0);
778
//                        lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
779
//                        lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
780
////                    lcd_printp_at (19, 7, PSTR("OK"), 0);
781
//                        lcd_puts_at(19, 7, strGet(OK), 0);
782
////                    lcd_printp_at (0, 5, PSTR(" Breitengr  Längengr "), 0);
783
//
784
//                      lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
785
//
786
//                      lcd_puts_at(12, 7, strGet(ENDE), 0);
787
//
788
//                      BeepTime = 1500;
789
//                      BeepMuster = 0x0040;
790
//                      error = 1;
791
//
792
//                      uint32_t lon = last5pos[0].Longitude;
793
//                      write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
794
//                      lcd_printp_at (3, 6, PSTR("."), 0);
795
//                      write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
796
//                      write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
797
//
798
//                      uint32_t lat = last5pos[0].Latitude;
799
//                      write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
800
//                      lcd_printp_at (14, 6, PSTR("."), 0);
801
//                      write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
802
//                      write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
803
//
804
//                      while (!get_key_press (1 << KEY_ENTER));
805
//
806
//                      timer = TIMEOUT;
807
//                      lcd_cls();
808
//                      return;
809
//
810
//              }
811
//      }
1517 - 812
}
813