Subversion Repositories Projects

Rev

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

/*****************************************************************************
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
 *   Copyright (C) 2011 Harald Bongartz                                      *
 *                                                                           *
 *   This program is free software; you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation; either version 2 of the License.          *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program; if not, write to the                           *
 *   Free Software Foundation, Inc.,                                         *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
 *                                                                           *
 *                                                                           *
 *   Credits to:                                                             *
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
 *                          http://www.mikrokopter.de                        *
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
 *   Thomas Kaiser "thkais" for the original project. See                    *
 *                          http://www.ft-fanpage.de/mikrokopter/            *
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
 *                          http://www.mylifesucks.de/oss/c-osd/             *
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
 *****************************************************************************/


//############################################################################
//# HISTORY  osd.c
//#
//# 12.03.2013 OG
//# - add: Get_BL_Data() - BL-Ctrl via NC auslesen (BETA) (siehe dort auch Kommentare im func-Header)
//# - add: neuer Screen "Electric"
//# - chg: Layout von Screen "Navigation" - Pixelverschiebungen
//# - chg: Layout von Screen "MK-Status" - Pixelverschiebungen und Anzeige 'Strom' ersetzt durch 'entn. Kapazitaet'
//# - add: in osd() LiPO-Cell Erkennung hinzugefuegt (fuer Screen "Electric")
//#
//# 10.03.2013 OG
//# - fix: doppelte Degree-Anzeige in OSD_Element_CompassDegree()
//# - add: neuer Screen "MK-Status"
//# - add: 7 neue OSD-Flags
//# - chg: Screen-Refresh Zeit via timer2 (einstellbar durch define OSD_REFRESH_TIME)
//# - chg: mit define OSD_DEBUG_SCREEN kann ein zusaetzlicher Screen verwendet werden zum testen/entwickeln
//# - del: entfernt CFG2_HEIGHT_LIMIT in OSD_Element_AltitudeControl() (bis bessere Loesung gefunden ist)
//#
//# 08.03.2013 OG
//# - del: OSD_Screen_Element() und cleanup in osd.h
//# - add: OSD_Element_UpDown() (steigend/sinken via Pfeilen)
//# - chg: OSD_Element_UpDown() in Screen "General" und "Navigation" hinzugefuegt (rechts neben der Hoehenanzeige)
//# - chg: Screen "General" die Sat-Warnung wurde auf OSD_Element_Flag(OSD_FLAG_S0) geaendert
//# - chg: Anzeige von Flag 'nicht genug GPS-Sateliten' (OSD_FLAG_S0) auf "S!" geändert
//#
//# 07.03.2013 OG
//# - Hinweis bzgl. LowBatt-Anzeige in den Screens "General" und "Navigation":
//#      Es gibt zwei unabhängige LowBatt-Warnungen.
//#      1. die PKT LowBatt-Warnung: sie arbeitet mit der im PKT hinterlegten
//#         LowBatt Spannung und stellt den Spannungswert inkl. der Einheit "V"
//#         invers dar wenn der Warnwert erreicht wurde (inkl. lautem PKT-Peepen)
//#      2. die MK-LowBatt Warnung: hierbeit wird das Flag "BA" angezeigt wenn
//#         der MK eine LowBatt Warnung sendet
//#      Dadurch hat man nun zwei verschiedene LowBatt Warnungen die man auf Wunsch
//#      verschieden einstellen kann. Bei mir ist die PKT-LowBatt etwas niedriger  
//#      eingestellt als die MK-Warnung und bedeutet "es ist aller hoechste Zeit zu landen".
//#      Die Spannung der MK-LowBat ist ein wenig hoeher eingestellt und
//#      zeigt mir "es ist bald Zeit zu landen".
//# - del: Kommunikation zu FC - siehe Kommentare in osd()
//# - chg: Kommunikation zu NC - siehe Kommentare in osd()
//# - add: neuer Screen "Navigation"
//# - chg: Layout Screen "Statistics" - Einheiten um zwei Pixel nach rechts verschoben
//# - chg: Layout von Screen "General" modifiziert (u.a. xoffs,yoffs Pixelverschiebungen)
//# - add: OSD_FLAG_BA in Screen "General"
//# - add: die OSD_Element_xyz() Funktionen in osd.h aufgenommen
//# - chg: an verschiedenen Stellen die Char-Drawmode defines MNORMAL, MINVERS, usw. eingebaut
//# - del: Kompatibilitaetscode fuer "3D-Lage" ueber Hauptmenue entfernt
//# - chg: die Funktionen OSD_Element_Switch() und OSD_Element_SwitchLabel() heissen
//#        nun OSD_Element_Flag() und OSD_Element_Flag_Label()
//# - chg: die defines OSD_SWITCH_xy heissen jetzt OSD_FLAG_xy
//# - fix: letzte GPS-Koordinaten werden jetzt permanent Config.LastLatitude, Config.LastLongitude gespeichert
//#
//# 03.03.2013 OG
//# - add: delay in Mainloop von osd() um springende Werte abzudaempfen (TEST)
//# - add: Startverzoegerung der Screens bis NaviData sich etwas stabilisiert hat (TEST)
//# - add: OSD Startup Message "connecting MK..."
//# - add: 'Emergency Landing' (EL) Anzeige in Screen "General"
//# - del: OUT1/OUT2 Anzeige in Screen "General"
//# - add: RC-Quality in Screen "General"
//# - add: func: draw_symbol_rc() (alternative RC-Quality Symbol)
//# - fix: Hoehenanzeige fuer Screens "OSD0" und "OSD1"
//# - fix: OSD_Element_SwitchLabel() angepasst fuer x=0 und y=0
//# - add: OSD_Element_Switch/Label() erweitert um OSD_SWITCH_FS
//# - fix: Screen-Redraw nach OSD_Timeout() und anderen Fehlermeldungen
//# - chg: messages.c: STATS_ITEM_0 bis STATS_ITEM_6 angepasst (1 char kuerzer)
//# - chg: Layout von OSD_Info() - mehr background-clear und etwas kleiner
//#
//# 02.03.2013 OG
//# - chg: keine internal func in Screen's wegen warnings bei anderen
//# - del: Screen "OSD3"
//# - fix: Hoehenanzeige in Screen "General" (Minuszeichen)
//# - add: MK LowBat Warning in Screen "General"
//# - add: neues Degree Symbol (als func) in Screen General (kleiner als das Char 0x1E)
//# - add: weitere Flags in OSD_Element_Flag()
//#
//# 01.03.2013 OG
//# - Reskrukturierung Code (+ neuer OSD-Screens und einiges mehr)
//############################################################################


//############################################################################
//# HINWEISE:
//#
//# 1. define: OSD_DEMO
//#    mit define OSD_DEMO wird ein Demo-Modus bei den neuen Screens einge-
//#    schaltet - damit werden u.a. alle Flag's angezeigt fuer Scree-Fotos
//#
//# 2. define: OSD_DEBUG_SCREEN
//#    mit diesem define wird ein zusaetzlicher Screen "Debug" einkompiliert
//#    fuer Test / Experimente / Debug von OSD-Elementen
//#
//# 3. Informationen zum Display
//#    DOG: 128 x 64 Pixel with 6x8 Font => 21 x 8
//#
//# 4. MK-Kommunikationsprotokoll Referenz
//#    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
//############################################################################


#include "../cpu.h"
#include <avr/io.h>
#include <inttypes.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <string.h>


#include "../main.h"
#include "../osd/osd.h"
#include "../lcd/lcd.h"
#include "../timer/timer.h"
#include "../uart/usart.h"
#include "../eeprom/eeprom.h"
#include "../messages.h"
#include "../parameter.h"
#include "../sound/pwmsine8bit.h"
#include "../mk-data-structs.h"


//#define OSD_DEMO                              // zeigt Demo-Daten in den OSD-Screens (sofern vom Screen unterstuetzt)
//#define OSD_DEBUG_SCREEN              // zusaetzlichen Debug-Screen aktivieren

#define OSD_REFRESH_TIME        45      // Screen Refresh; ein Wert von 100 entspricht ca. 1 Sekunde (Steuerung via timer2)

#define COSD_WASFLYING          4
#define TIMEOUT                         200     // 2 sec


// Hier Höhenanzeigefehler Korrigieren
#define AltimeterAdjust 1.5


// global definitions and global vars
NaviData_t                      *naviData;
mk_param_struct_t       *mk_param_struct;
uint8_t                         Flags_ExtraConfig;
uint8_t                         Flags_GlobalConfig;
uint8_t                         Flags_GlobalConfig3;
unsigned char           Element;
uint16_t                        heading_home;
uint8_t                         drawmode;

// flags from last round to check for changes
uint8_t  old_FCFlags            = 0;
uint8_t  old_AngleNick          = 0;
uint8_t  old_AngleRoll          = 0;
uint16_t old_hh                         = 0;

// stats for after flight
int16_t  max_Altimeter          = 0;
uint16_t max_GroundSpeed        = 0;
int16_t  max_Distance           = 0;
uint8_t  min_UBat                       = 255;
uint16_t max_FlyingTime         = 0;
uint16_t max_Current            = 0;
uint16_t max_Capacity           = 0;

// cache old vars for blinking attribute, checkup is faster than full
// attribute write each time
volatile uint8_t last_UBat                      = 255;
volatile uint8_t last_RC_Quality        = 255;

volatile uint16_t ftimer                        = 0;
volatile uint8_t OSD_active;

uint8_t Vario_Beep_Up                           = 0;
uint8_t Vario_Beep_Down                         = 0;
uint8_t Vario_Beep_Up_Interval          = 9;
uint8_t Vario_Beep_Down_Interval        = 6;
uint8_t Vario_Threshold                         = 0;
uint8_t Vario_Threshold_Value           = 7;
uint8_t OldWP                                           = 0;
uint8_t NextWP                                          = 0;



//char* rose = "-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W";
const char rose[48] PROGMEM = {
        0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S',
        0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O',
        0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N',
        0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W',
};

// the center is char 19 (north), we add the current heading in 8th
// which would be 22.5 degrees, but float would bloat up the code
// and *10 / 225 would take ages... so we take the uncorrect way

const char str_NE[] PROGMEM = "NE";
const char str_E[] PROGMEM  = "E ";
const char str_SE[] PROGMEM = "SE";
const char str_S[] PROGMEM  = "S ";
const char str_SW[] PROGMEM = "SW";
const char str_W[] PROGMEM  = "W ";
const char str_NW[] PROGMEM = "NW";
const char str_N[] PROGMEM  = "N ";
const char *directions_p[8] PROGMEM = {
        str_NE,
        str_E,
        str_SE,
        str_S,
        str_SW,
        str_W,
        str_NW,
        str_N
};


#define MAX_CELL_VOLTAGE 43 // max cell voltage for LiPO
#define MIN_CELL_VOLTAGE 32 // min cell voltage for LiPO

// Flags
GPS_Pos_t last5pos[7];
uint8_t COSD_FLAGS2                     = 0;
volatile uint8_t error                  = 0;
uint8_t cells                                   = 0;
uint8_t BattLowVoltageWarning   = 0;
uint8_t CellIsChecked                   = 0;
uint8_t AkkuWarnThreshold               = 0;
uint16_t duration                               = 0;


//-----------------------------------------------------------
// BL-Ctrl
//
// TODO: typedef BLData_t und var blData ist in der osd.c
//       nicht an der richtigen Stelle
//-----------------------------------------------------------
#define MAX_MOTORS               8              // max. Anzahl vom PKT unterstuetzer Motoren (absolut MAX ist 12 da der MK nicht mehr unterstuetzt)
#define BL_READ_TIME    25              // Zeit via timer (n*10 = ms)

typedef struct
{
            unsigned char Index;            // address of BL-Ctrl
            unsigned char Current;                      // in 0.1 A steps, read back from BL
            unsigned char Temperature;      // old BL-Ctrl will return a 255 here, the new version (>= V2.0) the temp. in °C
            unsigned char MaxPWM;                       // EVENTUELL: read back from BL -> is less than 255 if BL is in current limit, not running (250) or starting (40)
            unsigned char Status;                       // EVENTUELL: 7 bit for I2C error counter, highest bit indicates if motor is present
}  BLData_t;

BLData_t        blData[MAX_MOTORS];
//uint16_t      blDataCounter[MAX_MOTORS];              // debug


//###########################################################
//###########################################################


//--------------------------------------------------------------
// Get_BL_Data()
//
// Holt Daten der BL-Ctrl via NC.
//
// Die Werte der BL's 1-12 kommen in mehr oder weniger beliebiger
// Reihenfolge an. Die Daten fuer vorhandene BL's werden oefter
// gesendet als die von nicht vorhandenen BL's.
//
// Diese Funktioen liest fuer die Zeit BL_READ_TIME die BL-Daten
// vom MK ein und ordnet diese der PKT-internen Speichstruktur zu.
//
// Hierbei ist nicht gewaehrleistet, dass die Daten von jedem BL
// in einem festen Zeitrahmen ermittelt werden. Die Folge ist
// ein 'zufaelliger' Aufbau der Anzeige der BL-Daten und auch
// eine nicht exakt bestimmbare Refreshtime der Werte.
//
// Optimieren kann man ggf. die Refreshzeit aller BL-Werte durch
// tx_intervall fuer Kommando "k" und durch BL_READ_TIME.
// Brauchbare Startwerte sind (noch experimentell):
//   tx_interval  = 5 (fuer "k")        =  50 ms
//   BL_READ_TIME = 25                          = 250 ms
//
// Wenn dieses Verhalten verbessert werden soll muss ggf.
// die ISR() (usart.c) fuer Kommando "k" angepasst werden um
// in einem Schwung mehrere gesendete BL-Pakete aufeinmal
// aufzunehmen und als Paket zur Verfuegung zu stellen.
//--------------------------------------------------------------
void Get_BL_Data()
{
        uint8_t         tx_interval;
        BLData_t        *rx_blData;

        //------------------------
        // switch to: BL-Data
        //------------------------
        tx_interval = 5;                                                                        // = 50 ms (send packet every n*10 ms)
        mode            = 'K';                                                                  // read: BL Ctrl Status
        SendOutData ('k', ADDRESS_ANY, 1, &tx_interval, 1);     // request: BL Ctrl Status

        rxd_buffer_locked = FALSE;     
        //_delay_ms(50);

        //------------------------
        // read: BL-Data
        //------------------------
        timer = BL_READ_TIME;                                                           // fuer x Zeit versuchen BL-Daten zu lesen

        while( timer>0 )                                                                        // lese blData Pakete fuer die angegebene Zeit
        {
                if( rxd_buffer_locked )
                {
                        Decode64 ();
                        rx_blData = (BLData_t *) (pRxData);
                       
                        // die BL-Daten kommen in beliebiger Reihenfolge an
                        // Hier werden sie entsprechend ihres Index gesichert
                        if( rx_blData->Index >=0 && rx_blData->Index < MAX_MOTORS )
                        {      
                                memcpy( &blData[ rx_blData->Index ], rx_blData, sizeof(BLData_t));  // sichern...
                                //blDataCounter[ rx_blData->Index ]++;                                                          // Debug
                        }
                        rxd_buffer_locked = FALSE;     
                }
        }

        //------------------------
        // back to: OSD-Data
        //------------------------
        tx_interval  = 10;                                                                      // = 100 ms (send packet every n*10 ms)
        mode             = 'O';                                                                 // read: OSD-Data
        SendOutData( 'o', ADDRESS_NC, 1, &tx_interval, 1);      // request: OSD-Data

        rxd_buffer_locked       = FALSE;                                                // ready to receive new data
        timer                           = TIMEOUT;                                              // reset osd timeout timer
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void variobeep(int16_t vario)
{
  { //start Beep

    if (vario >0 )          // MK steigt
      {
       Vario_Beep_Down = 0;                 // Down Beep freischalten
       Vario_Threshold++;

       if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value))
        {
//         set_beep ( 100, 0xffff, BeepNormal);
         duration = 52 -vario;
//         if (duration =0); duration = 1;

//         write_ndigit_number_u (0,6,duration,5,0);

         playTone(300+vario*2,duration,Config.Volume);
//         playTone(300,duration,volume);
         Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
        }
       Vario_Beep_Up++;                 // Interval hochzählen in dem nicht gepiept wird
       if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0;
      }

    if (vario <0)          // MK fällt
      {
       Vario_Beep_Up = 0;                 // Up Beep freischalten
       Vario_Threshold++;
       if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value))
        {
         duration = 50 -vario;
//         write_ndigit_number_u (0,7,duration,5,0);
//         if (duration < vario) ; duration = 0;
//         playTone(300,50,volume);


         playTone(300+vario*2,duration,Config.Volume);
         Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
        }
       Vario_Beep_Down++;                 // Interval hochzählen in dem nicht gepiept wird
       if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0;
      }

    if (vario == 0) Vario_Threshold = 0;  //Startverzögerung löschen
  }  // end Beep

}


//--------------------------------------------------------------
// Diese Funktion Beept unabhaengig von der Einstellung Config.OSD_VarioBeep
// Aufruf ggf. mit: if( Config.OSD_VarioBeep ) Beep_Vario();
//
// Ansonten:
// -> hier noch aufräumen in Zusammenhang mit func variobeep()
//--------------------------------------------------------------
void Beep_Vario(void)
{
        if ( (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN) && (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL))
    { //start Beep
      if (naviData->Variometer <0)          // MK fällt
        {
         Vario_Beep_Up = 0;                 // Up Beep freischalten
         Vario_Threshold++;
         if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value))
          {

          if (!Config.HWSound) set_beep ( 300, 0xffff, BeepNormal);
               else  variobeep(naviData->Variometer);

           Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
          }
         Vario_Beep_Down++;                 // Interval hochzählen in dem nicht gepiept wird
         if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0;
        }

      if (naviData->Variometer == 0) Vario_Threshold = 0;  //Startverzögerung löschen

      if (naviData->Variometer >0 )          // MK steigt
        {
         Vario_Beep_Down = 0;                 // Down Beep freischalten
         Vario_Threshold++;

         if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value))
          {
           if (!Config.HWSound) set_beep ( 100, 0xffff, BeepNormal);
           else  variobeep(naviData->Variometer);
           Vario_Threshold = Vario_Threshold_Value;     // auf Maximalwert begrenzen
          }
         Vario_Beep_Up++;                 // Interval hochzählen in dem nicht gepiept wird
         if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0;
        }
    }  // end Beep
}            


//--------------------------------------------------------------
// Quelle Mikrokopter FC-Software Holger + Ingo
//--------------------------------------------------------------
void CheckMKLipo(void)
{
    if(Config.MK_LowBat < 50) // automatische Zellenerkennung
    {
       if (CellIsChecked <= 2)   //Nur beim Start 1x prüfen
       {
                // up to 6s LiPo, less than 2s is technical impossible
                for(cells = 2; cells < 7; cells++)
                {
                        if(naviData->UBat < cells * MAX_CELL_VOLTAGE) break;
                }
                BattLowVoltageWarning = cells * Config.MK_LowBat;
                CellIsChecked++;
       }
    }
    else BattLowVoltageWarning = Config.MK_LowBat;

    if (naviData->UBat < BattLowVoltageWarning)
    {
        if (AkkuWarnThreshold <= 4) AkkuWarnThreshold++;
        else
        { //Beeper ein
                set_beep ( 1000, 0x0020, BeepSevere);
//               BeepTime = 3000;
//               BeepMuster = 0x0020;
        }
    }
}


//--------------------------------------------------------------
// convert the <heading> gotton from NC into an index
uint8_t heading_conv (uint16_t heading)
{
        if (heading > 23 && heading < 68)
                return 0;               //direction = "NE";
        else if (heading > 67 && heading < 113)
                return 1;               //direction = "E ";
        else if (heading > 112 && heading < 158)
                return 2;               //direction = "SE";
        else if (heading > 157 && heading < 203)
                return 3;               //direction = "S ";
        else if (heading > 202 && heading < 248)
                return 4;               //direction = "SW";
        else if (heading > 247 && heading < 293)
                return 5;               //direction = "W ";
        else if (heading > 292 && heading < 338)
                return 6;               //direction = "NW";

        return 7;       //direction = "N ";
}


//--------------------------------------------------------------
// draw a compass rose at <x>/<y> for <heading>
void draw_compass (uint8_t x, uint8_t y, uint16_t heading, int8_t xoffs, int8_t yoffs)
{
        uint8_t front = 19 + (heading / 22);
        for (uint8_t i = 0; i < 9; i++)
                lcdx_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), MNORMAL, xoffs,yoffs);
}


//--------------------------------------------------------------
// variometer
// x, y in Pixel!
//--------------------------------------------------------------
void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
{
        lcd_rect (x, y - ((hight) / 2), width, hight, 1);
        lcd_frect (x + 1, y - ((hight) / 2) + 1, width - 2, hight - 2, 0);
        lcd_line (x, y, x + width, y, 1);

        if (variometer > 0)  // steigend
        {
                switch (variometer / 5)
                {
                        case 0:
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
                        break;

                        case 1:
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
                        break;

                        case 2:
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
                        break;

                        default:
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);  //  1 >  4
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
                                lcd_frect (x + 1, y - 6, 8, 1, 1);                      // 15 >
                        break;
                }
        }
        else if (variometer < 0)  // fallend
        {
                switch ((variometer) / -5)
                {
                        case 0:
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
                        break;

                        case 1:
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
                        break;

                        case 2:
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
                        break;

                        default:
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
                                lcd_frect (x + 1, y + 5, 8, 1, 1);                      // -15 >
                        break;
                }
        }
}


//--------------------------------------------------------------
// variometer 2
//
// x, y in Pixel
// x, y top, left
//--------------------------------------------------------------
/*
void draw_variometer2( uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
{
        uint8_t max = 5;        // max: 5 m/sec == 100%

        lcd_rect (x, y, width, hight, 1);
        lcd_frect(x + 1, y + 1, width - 2, hight - 2, 0);
        lcd_line (x, y + ((hight) / 2), x + width, y + ((hight) / 2), 1);

}
*/



//--------------------------------------------------------------
// Home symbol
// draw Homesymbol at <x>/<y>
//--------------------------------------------------------------
void draw_homesymbol (uint8_t x, uint8_t y)
{
        x *= 6;
        y *= 8;
        y += 7;

        lcd_plot (x,y-4,1);
        lcd_line (x+1,y-1,x+1,y-5,1);
        lcd_plot (x+2,y-6,1);
        lcd_plot (x+3,y-7,1);
        lcd_plot (x+4,y-6,1);
        lcd_line (x+5,y-1,x+5,y-5,1);
        lcd_plot (x+6,y-4,1);
        lcd_plot (x+3,y-1,1);
        lcd_plot (x+3,y-2,1);
        lcd_line (x+1,y,x+5,y,1);

}

//--------------------------------------------------------------
// Target symbol
// draw Targetsymbol at <x>/<y>
//--------------------------------------------------------------
void draw_targetsymbol (uint8_t x, uint8_t y)
{
        x *= 6;
        y *= 8;
        y += 7;

        lcd_circle (x+3, y-3, 4, 1);
        lcd_line (x,y-3,x+6,y-3,1);
        lcd_line (x+3,y,x+3,y-6,1);
        lcd_circle (x+3, y-3, 2, 1);
}


//--------------------------------------------------------------
// Degree symbol
// draw Degreesymbol at <x>/<y>
//
// Ein etwas kleineres Degeree als Char 0x1E
//--------------------------------------------------------------
void draw_symbol_degree (uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs)
{
        x *= 6;
        y *= 8;
            lcd_rect (x+1+xoffs, y+yoffs, 2, 2, 1);
}


//--------------------------------------------------------------
// RC symbol
// alternatives Symbol fuer RC-Quality
//--------------------------------------------------------------
void draw_symbol_rc (uint8_t x, uint8_t y)
{
        x *= 6;
        y *= 8;
                y += 1;
                x += 1;
               
        lcd_plot  ( x+3, y+4, 1);
        lcd_line  ( x+2, y+2, x+4, y+2, 1);
        lcd_line  ( x+1, y+0, x+5, y+0, 1);
}


//--------------------------------------------------------------
void print_position (void)
{
        lcd_cls ();
        lcd_puts_at(0, 0, strGet(START_LASTPOS1), 2);   // Breitengr  Längengr
        lcd_puts_at(12, 7, strGet(ENDE), 0);
        uint8_t ij =0;

        for(ij=0;ij<6;ij++)
        {
                uint32_t lon = last5pos[ij].Latitude;
                write_ndigit_number_u (1, ij+1, (uint16_t)(lon/10000000), 2, 0,0);
                lcd_printp_at (3, ij+1, PSTR("."), 0);
                write_ndigit_number_u (4, ij+1, (uint16_t)((lon/1000) % 10000), 4, 1,0);
                write_ndigit_number_u (8, ij+1, (uint16_t)((lon/10) % 100), 2, 1,0);

                uint32_t lat = last5pos[ij].Longitude;
                write_ndigit_number_u (12, ij+1, (uint16_t)(lat/10000000), 2, 0,0);
                lcd_printp_at (14, ij+1, PSTR("."), 0);
                write_ndigit_number_u (15, ij+1, (uint16_t)((lat/1000) % 10000), 4, 1,0);
                write_ndigit_number_u (19, ij+1, (uint16_t)((lat/10) % 100), 2, 1,0);
        }

        while (!get_key_press (1 << KEY_ESC))
                timer = TIMEOUT;

        get_key_press(KEY_ALL);
        lcd_cls();
}


//--------------------------------------------------------------
void Show_LastPosition(void)
{
        lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
        lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
        lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
        uint32_t lon = last5pos[0].Latitude;
        write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0);
        lcd_printp_at (3, 6, PSTR("."), 0);
        write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0);
        write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0);

        uint32_t lat = last5pos[0].Longitude;
        write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0);
        lcd_printp_at (14, 6, PSTR("."), 0);
        write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0);
        write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0);

}


//--------------------------------------------------------------
void OSD_Timeout(uint8_t flag)
{

//      uint8_t flag;
        uint8_t tmp_dat;
//      flag = 0;
        timer = TIMEOUT;
        // disable OSD Data from NC
//      RS232_request_mk_data (1, 'o', 0);
//      tmp_dat = 0;
//      SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);

        mode = 0;
        rxd_buffer_locked = FALSE;


        // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
        if( flag )
        {
                // Falls Spannungswarnung an war Beeper aus//

                set_beep ( 0, 0, BeepOff);

                lcd_cls ();
                WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
                lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);                                                // ERROR: Datenverlust
                lcd_puts_at(0, 2, strGet(OSD_POS1), 0);                                                 // Letzte bekannte
                lcd_puts_at(0, 3, strGet(OSD_POS2), 0);                                                 // Position gespeichert.
                lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);                                   // Breitengr  Längengr
//              lcd_puts_at(12, 7, strGet(ENDE), 0);
//              lcd_puts_at(19, 7, strGet(OK), 0);
//              if (OSD_RCErrorbeep==true)
//              {
                        set_beep ( 250, 0x0040, BeepNormal);
//              }

                uint32_t lon = last5pos[0].Latitude;
                write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0);
                lcd_printp_at (3, 6, PSTR("."), 0);
                write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0);
                write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0);

                uint32_t lat = last5pos[0].Longitude;
                write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0);
                lcd_printp_at (14, 6, PSTR("."), 0);
                write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0);
                write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0);

//              while (!get_key_press (1 << KEY_ENTER));
//              _delay_ms(1000);
                timer = TIMEOUT;
//              lcd_cls();
//              return;
        }
        else
        {
                lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
                Show_LastPosition();
                if (Config.OSD_RCErrorbeep==true) set_beep ( 200, 0x0080, BeepNormal);
//              _delay_ms(2000);
        }

    rxd_buffer_locked = FALSE;  // 07.03.2013 OG: fix
                                                        //   es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den
                                                        //   OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt'

        SwitchToNC();

        mode = 'O';

        // disable debug...
//      RS232_request_mk_data (0, 'd', 0);
        tmp_dat = 0;
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);

        // request OSD Data from NC every 100ms
//      RS232_request_mk_data (1, 'o', 100);
        tmp_dat = 10;
        SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);

        //_delay_ms(100);
        //rxd_buffer_locked = FALSE;
}




//-----------------------------------------------------------
//
void lcd_o_circle (uint16_t x, uint16_t y, int16_t breite, uint8_t mode, int8_t xoffs, int8_t yoffs)
{
        breite *= 6;
        int16_t radius = breite / 2;
        x += 2;
        x *= 6;
        x += 2;
        y += 1;
        y *= 8;
        y += 3;

        // 04.03.2012 OG: chg: x-radius von -3 auf -2 (runder auf dem display)
        //lcd_ellipse (x, y, radius - 3, radius - 5, mode);
        lcd_ellipse( x+xoffs, y+yoffs, radius - 2, radius - 5, mode);
}


//-----------------------------------------------------------
// lcd_o_circ_line( x, y, breite, deg, rOffset, mode)
//
// x, y   : in Chars
// breite : in Chars
// deg    : in Pixel
// rOffset: Beeinflusst den Schluss der Linie zum Huellkreis
//          0 = Standard
//          >0 naeher zum Huellkreis
//          <0 entfernter vom Huellkreis
// mode   : siehe: lcd_ellipse_line()
//-----------------------------------------------------------
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)
{
        breite *= 6;
        int16_t radius = breite / 3;
        x += 2;
        x *= 6;
        x += 2;
        y += 1;
        y *= 8;
        y += 3;

    // 04.03.2013 OG: der Radius kann mit rOffset >0 vergroessert werden um zum Kreis aufzuschliessen
        lcd_ellipse_line( x+xoffs, y+yoffs, radius+rOffset, radius+rOffset, deg, mode);
}


//--------------------------------------------------------------
void draw_icon_home(uint8_t x, uint8_t y)
{
        //lcd_plot( x+0, y+0, 1);                       // Referenz 0,0
        lcd_rect( x+0, y+5, 10, 8, 1);          // Mitte
        lcd_line( x+5, y+0, x+0, y+5, 1);       // Dach Links
        lcd_line( x+5, y+0, x+10, y+5, 1);  // Dach Rechts
        lcd_rect( x+4, y+10, 2, 3, 1);          // Tuere
       
}


//--------------------------------------------------------------
void draw_icon_sat(uint8_t x, uint8_t y)
{
        //lcd_plot( x+0, y+0, 1);                        // Referenz 0,0
        lcd_rect( x+0, y+2, 4, 2, 1);            // linker Fluegel
        lcd_rect( x+8, y+2, 4, 2, 1);            // rechter Fluegel
        lcd_rect( x+4, y+0, 4, 6, 1);            // Mitte, oben
        lcd_line( x+6, y+7, x+2, y+11, 1);       // Strahl Links
        lcd_line( x+6, y+7, x+10, y+11, 1);  // Strahl Rechts
        lcd_line( x+1, y+12, x+11, y+12, 1); // Strahl Unten
}


//--------------------------------------------------------------
void draw_icon_battery(uint8_t x, uint8_t y)
{
        //lcd_plot( x+0, y+0, 1);                       // Referenz 0,0
    lcd_rect( x+2, y+0, 2, 2,  1);              // der kleine Knubbel oben
    lcd_rect( x+0, y+2, 6, 15, 1);              // body
}



//##############################################################
//# OSD-ELEMENTS
//##############################################################

//--------------------------------------------------------------
// OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs, yoffs)
//
// xC, yC               : x,y in Characters
// item                 : OSD_FLAG_AH, OSD_FLAG_PH, usw.
// lOn                  : true / false
// xoffs,yoffs  : x,y Pixelverschiebung
//--------------------------------------------------------------
void OSD_Element_Flag_Label( uint8_t xC, uint8_t yC, uint8_t item, uint8_t lOn, int8_t xoffs, int8_t yoffs)
{
        int8_t  x = (xC*6)-2;
        int8_t  y = (yC*8)-1;
        uint8_t w = 14;
        uint8_t h = 8;

        const char *labels[OSD_FLAG_COUNT] =
        {
                PSTR("AH"),  // OSD_FLAG_AH  Altitue Hold
                PSTR("PH"),  // OSD_FLAG_PH  Position Hold
                PSTR("CF"),  // OSD_FLAG_CF  Care Free
                PSTR("CH"),  // OSD_FLAG_CH  Coming Home
                PSTR("o1"),  // OSD_FLAG_O1  Out1
                PSTR("o2"),  // OSD_FLAG_O2  Out2
                PSTR("BA"),  // OSD_FLAG_BA  LowBat warning (MK)
                PSTR("CA"),  // OSD_FLAG_CA  Calibrate
                PSTR("ST"),  // OSD_FLAG_ST  Start
                PSTR("MR"),  // OSD_FLAG_MR  Motor Run
                PSTR("FY"),  // OSD_FLAG_FY  Fly
                PSTR("EL"),  // OSD_FLAG_EL  Emergency Landing
                PSTR("FS"),      // OSD_FLAG_FS  RX Failsave Active
                PSTR("GP"),  // OSD_FLAG_GP  GPS Ok
                PSTR("S!"),  // OSD_FLAG_S0  GPS-Sat not ok (GPS NOT ok)
                PSTR("TU"),  // OSD_FLAG_TU  Vario Trim Up
                PSTR("TD"),  // OSD_FLAG_TD  Vario Trim Down
                PSTR("FR"),  // OSD_FLAG_FR  Free
                PSTR("RL"),  // OSD_FLAG_RL  Range Limit
                PSTR("SL"),  // OSD_FLAG_SL  No Serial Link
                PSTR("TR"),  // OSD_FLAG_TR  Target Reached
                PSTR("MC")   // OSD_FLAG_MC  Manual Control            
        };

        //lcd_plot( x-2, y-2, 1);                                               // Referenz
       
        if( yC==0 )     {       y = 0;  h = 7;  }
        if( xC==0 )     {       x = 0;  w = 12; }
               
        if( lOn )
        {              
        lcd_frect( x+xoffs, y+yoffs, w, h, 1);                                          // Filler
                lcdx_printp_at(  xC, yC, labels[item], MINVERS, xoffs,yoffs);   // Label
    }
    else
        {              
        lcd_frect( x+xoffs, y+yoffs, w, h, 0);                                          // clear
    }    
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_Flag( uint8_t xC, uint8_t yC, uint8_t item, int8_t xoffs, int8_t yoffs)
{
        uint8_t lOn = 0;

        // FC_StatusFlags 0.88
        switch( item )
    {
        // Altitue Hold
        case OSD_FLAG_AH :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL);
                                                        break;

                // Position Hold
        case OSD_FLAG_PH :      lOn = (naviData->NCFlags & NC_FLAG_PH);
                                                        break;

                // Coming Home
        case OSD_FLAG_CH :      lOn = (naviData->NCFlags & NC_FLAG_CH);
                                                        break;

                // Care Free
        case OSD_FLAG_CF :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE);
                                                        break;

                // Out1
        case OSD_FLAG_O1 :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE);
                                                        break;

                // Out2
        case OSD_FLAG_O2 :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT2_ACTIVE);
                                                        break;

                //  LowBat warning (MK)
        case OSD_FLAG_BA :      lOn = (naviData->FCStatusFlags & FC_STATUS_LOWBAT);
                                                        break;

                //  Calibrate
        case OSD_FLAG_CA :      lOn = (naviData->FCStatusFlags & FC_STATUS_CALIBRATE);
                                                        break;

                //  Start
        case OSD_FLAG_ST :      lOn = (naviData->FCStatusFlags & FC_STATUS_START);
                                                        break;

                //  Motor Run
        case OSD_FLAG_MR :      lOn = (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN);
                                                        break;

                //  Fly
        case OSD_FLAG_FY :      lOn = (naviData->FCStatusFlags & FC_STATUS_FLY);
                                                        break;

                //  Emergency Landing
        case OSD_FLAG_EL :      lOn = (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING);
                                                        break;

                //  RC Failsave Active
        case OSD_FLAG_FS :      lOn = (naviData->FCStatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE);
                                                        break;
                                                       
                //  GPS ok
        case OSD_FLAG_GP :      lOn = (naviData->NCFlags & NC_FLAG_GPS_OK);
                                                        break;

                //  GPS-Sat not ok (GPS NOT ok)
        case OSD_FLAG_S0 :      lOn = !(naviData->NCFlags & NC_FLAG_GPS_OK);
                                                        break;

                //  Vario Trim Up
        case OSD_FLAG_TU :      lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_UP);
                                                        break;
               
                //  Vario Trim Down
        case OSD_FLAG_TD :      lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_DOWN);
                                                        break;

                //  Free
        case OSD_FLAG_FR :      lOn = (naviData->NCFlags & NC_FLAG_FREE);
                                                        break;

                //  Range Limit
        case OSD_FLAG_RL :      lOn = (naviData->NCFlags & NC_FLAG_RANGE_LIMIT);
                                                        break;

                //  No Serial Link
        case OSD_FLAG_SL :      lOn = (naviData->NCFlags & NC_FLAG_NOSERIALLINK);
                                                        break;

                //  Target Reached
        case OSD_FLAG_TR :      lOn = (naviData->NCFlags & NC_FLAG_TARGET_REACHED);
                                                        break;

                //  Manual Control
        case OSD_FLAG_MC :      lOn = (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL);
                                                        break;

        }
               
        OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs,yoffs);
}


//--------------------------------------------------------------
// OSD_Element_AltitudeControl( x, y)
//--------------------------------------------------------------
void OSD_Element_AltitudeControl( uint8_t x, uint8_t y )
{
                //---------------------------------------------------------
                // 10.03.2013 OG:
                //   CFG2_HEIGHT_LIMIT im Augenblick nicht unterstuetzt
                //   Siehe Anmerkungen in osd()
                //---------------------------------------------------------
                /*
                if (Flags_ExtraConfig & CFG2_HEIGHT_LIMIT)
                {
                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
                                lcd_puts_at (x, y, strGet(OSD_ALTI_1), 0);      // Höhe begr.
                        else
                                lcd_puts_at (x, y, strGet(OSD_ALTI_0), 0);      // Höhe aus
                }
                else
                {
                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
                                lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0);     // Vario Höhe
                        else
                                lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0);     // Vario aus
                }
                */


                        if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)
                                lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0);     // Vario Höhe
                        else
                                lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0);     // Vario aus

}


//--------------------------------------------------------------
// Anzeige von Steigen / Sinken
//--------------------------------------------------------------
void OSD_Element_UpDown( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs)
{
        x = (x*6) + xoffs;
        y = (y*8) + yoffs;

    lcd_frect( x, y, 6, 7, 0);                  // clear
   
    if( naviData->Variometer > 2 )              // steigen mehr als 0.2 m/sec (ein guter Wert muss noch in der Praxis ermittelt werden)
    {
                lcd_line( x+2, y+0, x+0, y+2, 1);
                lcd_line( x+2, y+0, x+4, y+2, 1);
    }
    else if( naviData->Variometer < -2 )        // sinken  mehr als 0.2 m/sec
    {
                lcd_line( x+2, y+6, x+0, y+4, 1);
                lcd_line( x+2, y+6, x+4, y+4, 1);
    }

}


//--------------------------------------------------------------
// OSD_Element_Altitude( x, y, nStyle)
// nStyle entspricht dem ehemaligen 'Mode'
//--------------------------------------------------------------
void OSD_Element_Altitude( uint8_t x, uint8_t y, uint8_t nStyle )
{
        switch( nStyle )
        {
                case 0 :
                case 1 :        //note:lephisto:according to several sources it's /30
                    if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))        // above 10m only write full meters
                             write_ndigit_number_s (x, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL);
                    else        // up to 10m write meters.dm
                             write_ndigit_number_s_10th (x, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MNORMAL);

                    lcd_printp_at (x+4, y, PSTR("m"), MNORMAL);
                    lcd_putc (x+5, y, 0x09, 0);  // Hoehensymbol
                    break;

                case 2 :        //note:lephisto:according to several sources it's /30
                        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))        // above 10m only write full meters
                        write_ndigit_number_s (x+4, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MBIG);
                        else        // up to 10m write meters.dm
                        write_ndigit_number_s_10th (x+4, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MBIG);
                        lcd_putc( x+8, y, 'm', MBIG);
                        lcd_printp_at (x, y, PSTR("Höhe"), MNORMAL);
                        break;
        }      
}


//--------------------------------------------------------------
// fuer: Config.OSD_LipoBar==1
//--------------------------------------------------------------
void OSD_Element_BatteryLevel_Bar( uint8_t x, uint8_t y )
{
        uint16_t Balken = 0;

        drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0);
       
        if( cells > 0 )  // LipobargraphAnzeige nur wenn Anzahl der Lipozellen bekannt sind
        {
        write_ndigit_number_u (x+6, y, cells, 1, 0, drawmode);
        lcd_printp_at (x+7, y, PSTR("S"), drawmode);

            if( cells==3 )
        {
                lcd_rect(x*6, y*8, 28, 7, 1);  // Rahmen
            Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/12;
            if((Balken > 0) && (Balken <28)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1);         // Fuellung
            if(Balken <= 26) lcd_frect(Balken+(x*6)+1, (y*8)+1, 26-Balken, 5, 0);                       // loeschen
        }

            if( cells==4 ||cells==5 )
        {
           lcd_rect(x*6, y*8, 30, 7, 1);  // Rahmen
           if (cells == 4) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/15;
           if (cells == 5) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/19;
           if ((Balken > 0) && (Balken <=29)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1);        // Fuellung
           if (Balken <= 27) lcd_frect(Balken+(x*6)+1, (y*8)+1, 28-Balken, 5, 0);                       // loeschen
        }

          } // end if: cells > 0   (TODO: Anzeige fuer cells==0 implementieren)
}



//--------------------------------------------------------------
// fuer die neuen OSD-Screens
//--------------------------------------------------------------
void OSD_Element_BattLevel2( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs )
{
        drawmode = (naviData->UBat < BattLowVoltageWarning ? MINVERS : MNORMAL);
    writex_ndigit_number_u_10th( x, y, naviData->UBat, 3, 0, drawmode, xoffs,yoffs);
        lcdx_printp_at( x+4, y, PSTR("V"), drawmode, xoffs+1,yoffs);                            // Einheit
    lcd_line( (x+4)*6, y*8, (x+4)*6, y*8+7, (drawmode==MINVERS ? 1 : 0) );              // filler zwischen Spannung und "V"
       
}


//--------------------------------------------------------------
// fuer: Config.OSD_LipoBar==0
// nStyle entspricht dem ehemaligen 'Mode'
//--------------------------------------------------------------
void OSD_Element_BatteryLevel_Text( uint8_t x, uint8_t y, uint8_t nStyle )
{
        if( nStyle <= 1)
                drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0);  // Normal-Schrift
        else           
                drawmode = (naviData->UBat < BattLowVoltageWarning ? 4 : 3);  // Fett-Schrift

        if( nStyle <= 1)
        {
        write_ndigit_number_u_10th (x, y, naviData->UBat, 3, 0, drawmode);
        lcd_printp_at (x+4, y, PSTR("V"), drawmode);
        }
        else           
        {
        write_ndigit_number_u_10th (x-2, y, naviData->UBat, 3, 0, drawmode);
        lcd_printp_at (x+2, y, PSTR("V"), drawmode);
        }      
}


//--------------------------------------------------------------
// nStyle entspricht dem ehemaligen 'Mode'
//--------------------------------------------------------------
void OSD_Element_BatteryLevel( uint8_t x, uint8_t y, uint8_t nStyle )
{
        if( Config.OSD_LipoBar )
                OSD_Element_BatteryLevel_Bar( x, y);
        else
                OSD_Element_BatteryLevel_Text( x, y, nStyle);
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_Capacity( uint8_t x, uint8_t y )
{
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? 2 : 0);
       
        write_ndigit_number_u (x, y, naviData->UsedCapacity, 5, 0, drawmode);
        lcd_printp_at (x+5, y, PSTR("mAh"), drawmode);
        // BeepTime = 3000;
        // BeepMuster = 0x0020;
}


//--------------------------------------------------------------
// OSD_Element_CareFree( x, y)
//--------------------------------------------------------------
void OSD_Element_CareFree( uint8_t x, uint8_t y )
{
        lcd_puts_at (x, y, strGet( naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE ? OSD_CARE_FREE_1 : OSD_CARE_FREE_0 ), 0);
}


//--------------------------------------------------------------
// OSD_Element_CompassDegree( x, y, nStyle)
// nStyle entspricht dem ehemaligen 'Mode'
//--------------------------------------------------------------
void OSD_Element_CompassDegree( uint8_t x, uint8_t y, uint8_t nStyle )
{
        switch( nStyle )
    {
        case 0 :
        case 1 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MNORMAL);
                     x += 3;
                 break;
                 
        case 2 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MBIG);
                     x += 8;
                 break;
        }
    lcd_putc( x, y, 0x1E, MNORMAL);     // degree symbol
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_CompassDirection( uint8_t x, uint8_t y )
{
        lcd_printp_at (x, y, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_CompassRose( uint8_t x, uint8_t y )
{
        draw_compass (x, y, naviData->CompassHeading, 0,0);
}

//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_Current( uint8_t x, uint8_t y )
{
        write_ndigit_number_u_10th (x, y, naviData->Current, 3, 0,0);
        lcd_printp_at (x+4, y, PSTR("A"), 0);
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_FlyingTime( uint8_t x, uint8_t y )
{
        write_time (x, y, naviData->FlyingTime);
        lcd_printp_at (x+5, y, PSTR("m"), 0);  
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_GroundSpeed( uint8_t x, uint8_t y )
{
        write_ndigit_number_u (x, y, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,0);
        lcd_printp_at (x+3, y, PSTR("Kmh"), 0);
}



//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_HomeCircle( uint8_t x, uint8_t y, uint8_t breite, int8_t rOffset, int8_t xoffs, int8_t yoffs )
{
        lcd_o_circle( x, y, breite, 1, xoffs,yoffs);

    if (Config.OSD_HomeMKView==1)
        heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
    else
        heading_home = (naviData->CompassHeading- naviData->HomePositionDeviation.Bearing + 360 ) % 360;

    lcd_o_circ_line( x, y, breite, old_hh      , rOffset, 0, xoffs,yoffs);
    lcd_o_circ_line( x, y, breite, heading_home, rOffset, 1, xoffs,yoffs);
   
    old_hh = heading_home;
}




//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_HomeDegree( uint8_t x, uint8_t y )
{
        write_ndigit_number_u (x, y, heading_home, 3, 0,0);
        lcd_putc (x+3, y, 0x1e, 0);     // degree symbol
}


//--------------------------------------------------------------
// OSD_Element_HomeDistance( x, y, nStyle)
//--------------------------------------------------------------
void OSD_Element_HomeDistance( uint8_t x, uint8_t y, uint8_t nStyle )
{
        switch( nStyle )
    {
        case 0 :
        case 1 : write_ndigit_number_u (x, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0);
                                 lcd_putc (x+3, y, 'm', 0);
                                 draw_homesymbol(x+4, y);
                 break;
                 
        case 2 : lcd_printp_at (x, y, PSTR("Home"), 0);
                 write_ndigit_number_u (x+5, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0);
                 lcd_printp_at (x+8, y, PSTR("m -"), 0);
                 break;
        }              
}


//--------------------------------------------------------------
// OSD_Element_LEDOutput( x, y, bitmask)
//
// bitmask: LED1 = FC_STATUS2_OUT1_ACTIVE
//          LED2 = FC_STATUS2_OUT2_ACTIVE
//--------------------------------------------------------------
void OSD_Element_LEDOutput( uint8_t x, uint8_t y, uint8_t bitmask )
{
        uint8_t lOn;
       
        lOn = (naviData->FCStatusFlags2 & bitmask ? 1 : 0);   // Bit gesetzt?
        lOn = (Config.OSD_InvertOut ? !lOn : lOn);            // Invertieren?
        lOn = (lOn ? 1 : 0);                                  // auf 0 oder 1 setzen (hmm, geht auch besser...).
       
    lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, lOn);
    lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);

  /*
    if (!Config.OSD_InvertOut)
    {
        if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE)
        {
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0);
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
        }
        else
        {
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 1);
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
        }
    }
    else
    {
        if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE)
        {
            lcd_fcircle (x * 6 + 5, y * 8 + 3,Config.OSD_LEDform, 1);
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
        }
        else
        {
            lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0);
            lcd_circle  (x * 6 + 5, y * 8 + 3, 3, 1);
        }
    }
    break;  
  */

}


//--------------------------------------------------------------
// OSD_Element_LED1Output( x, y)
//--------------------------------------------------------------
void OSD_Element_LED1Output( uint8_t x, uint8_t y )
{
        OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT1_ACTIVE );
}


//--------------------------------------------------------------
// OSD_Element_LED2Output( x, y)
//--------------------------------------------------------------
void OSD_Element_LED2Output( uint8_t x, uint8_t y )
{
        OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT2_ACTIVE );
}


//--------------------------------------------------------------
// OSD_Element_Manuell( x, y)
//--------------------------------------------------------------
void OSD_Element_Manuell( uint8_t x, uint8_t y )
{
        if (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL)
                lcd_putc (x, y, 'M', 0); // rc transmitter
        else
                lcd_putc (x, y, 'X', 0); // clear      
}


//--------------------------------------------------------------
// OSD_Element_NaviMode( x, y)
//--------------------------------------------------------------
void OSD_Element_NaviMode( uint8_t x, uint8_t y )
{
        if (naviData->NCFlags & NC_FLAG_FREE)
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_0), 0); // Navi aus
        else if (naviData->NCFlags & NC_FLAG_PH)
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_1), 0); // Pos. Hold
        else if (naviData->NCFlags & NC_FLAG_CH)
                lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_2), 0); // Coming Home
}


//--------------------------------------------------------------
// OSD_Element_RCIntensity( x, y)
//--------------------------------------------------------------
void OSD_Element_RCIntensity( uint8_t x, uint8_t y )
{
        write_ndigit_number_u (x, y, naviData->RC_Quality, 3, 0,0);
        lcd_printp_at (x+3, y, PSTR("\x1F"), 0);                // RC-transmitter
        if (naviData->NCFlags & NC_FLAG_NOSERIALLINK)
        {
                lcd_printpns_at(x+3, y, PSTR("  "), 0);         // Clear
        }
        else
        {
                lcd_printpns_at(x+3, y, PSTR("PC"), 0);
        }
}


//--------------------------------------------------------------
// OSD_Element_SatsInUse( x, y, nStyle)
//
// nStyle == 0: "00s"
// nStyle == 1: wie 0
// nStyle == 2: "00 Sat"
//
// nStyle entspricht dem ehemaligen 'Mode'
//--------------------------------------------------------------
void OSD_Element_SatsInUse( uint8_t x, uint8_t y, uint8_t  nStyle )
{
        drawmode = (naviData->NCFlags & NC_FLAG_GPS_OK ? 0 : 2);
       
        switch( nStyle )
    {
        case 0 :
        case 1 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode);
                 lcd_putc (x+2, y, 0x08, drawmode);
                 break;
                 
        case 2 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode);
                 lcd_printp_at (x+2, y, PSTR(" Sat"), drawmode);
                 break;
        }
}


//--------------------------------------------------------------
// OSD_Element_StatusFlags( x, y)
//--------------------------------------------------------------
void OSD_Element_StatusFlags( uint8_t x, uint8_t y )
{
        // FC_StatusFlags 0.88
        // #define FC_STATUS_MOTOR_RUN           0x01
        // #define FC_STATUS_FLY                 0x02
        // #define FC_STATUS_CALIBRATE           0x04
        // #define FC_STATUS_START               0x08
        // #define FC_STATUS_EMERGENCY_LANDING   0x10
        // #define FC_STATUS_LOWBAT              0x20
        // #define FC_STATUS_VARIO_TRIM_UP       0x40
        // #define FC_STATUS_VARIO_TRIM_DOWN     0x80

        if (naviData->FCStatusFlags & FC_STATUS_CALIBRATE)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_1), 0);     // Calibrate
        else if (naviData->FCStatusFlags & FC_STATUS_START)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_2), 0);     // Start
        else if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_3), 0);     // Run
        else if (naviData->FCStatusFlags & FC_STATUS_FLY)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_4), 0);     // Fly
        else if (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_5), 0);     // Landing
        else if (naviData->FCStatusFlags & FC_STATUS_LOWBAT)
                lcd_puts_at (x, y, strGet(OSD_FLAGS_6), 0);     // LowBat
        else
    //  lcd_printp_at (x, y, PSTR("         "), 0);     // Clear
                lcd_puts_at (x, y, strGet(OSD_FLAGS_0), 0);     // Clear
}


//--------------------------------------------------------------
// OSD_Element_Variometer( x, y)
//--------------------------------------------------------------
void OSD_Element_Variometer( uint8_t x, uint8_t y )
{
        x *= 6;
        y *= 8;
        y += 7;
       
        draw_variometer (x, y, 10, 14, naviData->Variometer);
}


//--------------------------------------------------------------
// OSD_Element_Target( x, y, nStyle)
//
// nStyle entspricht dem ehemaligen 'Mode'
// nStyle = 0,1: "000m"
// nStyle = 2,3: "Ziel 000m -"
//--------------------------------------------------------------
void OSD_Element_Target( uint8_t x, uint8_t y, uint8_t nStyle )
{
        if( nStyle <= 1 )
        {
                write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0);
                lcd_putc (x+3, y, 'm', 0);
                draw_targetsymbol(x+4,y);
        }
        else   
        {
        lcd_printp_at (x, y, PSTR("Ziel"), 0);
        write_ndigit_number_u (x+5, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0);
        lcd_printp_at (x+8, y, PSTR("m -"), 0);
        }
}


//--------------------------------------------------------------
// TODO:
// - pruefen ob beep hier an richtiger Stelle ist
//--------------------------------------------------------------
void OSD_Element_VarioWert( uint8_t x, uint8_t y )
{
        uint8_t FC_Fallspeed;
       
    FC_Fallspeed = (unsigned int)naviData->Variometer;
    FC_Fallspeed = 255-FC_Fallspeed;

        drawmode = ( (naviData->Variometer < 0) && (FC_Fallspeed > Config.OSD_Fallspeed) ? 2 : 0);
               

        if( Config.OSD_VarioBeep )
                Beep_Vario();                                                           // Beep ???

    if( drawmode == 2 )
        {
        if( !Config.HWSound )  
                set_beep ( 1000, 0x0060, BeepNormal);   // muss ein Beep hier hin????
        else  
                variobeep(naviData->Variometer);        // muss ein Beep hier hin????
    }

    write_ndigit_number_s_10th (x, y, naviData->Variometer, 3,0, drawmode);
    lcd_printpns_at(x+4, y, PSTR("ms"), drawmode);     
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_WayPoint( uint8_t x, uint8_t y )
{
        if (!OldWP == naviData->WaypointIndex)
        {
                // BeepTime = 500;
                // BeepMuster = 0x0080;
        OldWP = naviData->WaypointIndex;
        NextWP = true;
    }
   
    if ((NextWP==true)&& naviData->NCFlags & NC_FLAG_TARGET_REACHED)
    {
        set_beep ( 500, 0x0080, BeepNormal);
        NextWP = false;
    }
   
    write_ndigit_number_u (x+2, y, naviData->WaypointIndex , 2, 0,0);

    lcd_printp_at (x, y, PSTR("WP"), 0);
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void OSD_Element_TargetDegree( uint8_t x, uint8_t y )
{
        write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Bearing/ 10, 3, 0,0);
        lcd_putc (x+3, y, 0x1e, 0);     // degree symbol
}



//##############################################################
//# OSD-SCREENS
//##############################################################

//--------------------------------------------------------------
// OSD-Screen "General"
//
// nRefreshMode:        0 = update values
//                              1 = redraw labels and update values  
//--------------------------------------------------------------
const char * OSD_Screen_General( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("General");

        //-----------------------------------------
        // REDRAW
        // statische Screen Elemente die nicht
        // jedesmal neu gezeichnet werden muessen
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
        // Display: 128 x 64 with 6x8 Font => 21 x 8

                // Linien: Horizontal
                lcd_line (0, 28, 127, 28, 1);  // mitte
            lcd_line (0, 51, 127, 51, 1);  // unten
 
                // Linien: Vertikal
        lcd_line (65, 0, 65, 50, 1);   // mitte
               
                //-----------------------------------------
                // Block: Oben - Links
                //-----------------------------------------            
                draw_icon_battery(0,4);
                //lcdx_printp_at( 6, 0, PSTR("V")        , MNORMAL, 1,0);       // Spannung (Volt)
                lcdx_printp_at( 7, 2, PSTR(" mA"), MNORMAL, 0,2);

                //-----------------------------------------
                // Block: Oben - Rechts
                //-----------------------------------------
                lcdx_printp_at( 12, 0, PSTR("Alt:")     , MNORMAL, 0,0);
                lcdx_printp_at( 12, 1, PSTR("Dir:")     , MNORMAL, 0,1);
        draw_symbol_degree( 20, 1, 1,1);
                lcdx_printp_at( 12, 2, PSTR("  I:")     , MNORMAL, 0,2);
                lcdx_printp_at( 20, 2, PSTR("A")        , MNORMAL, 2,2);

                //-----------------------------------------
                // Block: Unten - Links
                //-----------------------------------------
                draw_icon_sat(0,33);
                lcdx_printp_at( 6, 5, PSTR(" kmh"), MNORMAL, 0,1);

                //-----------------------------------------
                // Block: Unten - Rechts
                //-----------------------------------------
                draw_icon_home( 70, 32);
                lcdx_printp_at( 20, 4, PSTR("m"), MNORMAL, 2,0);
                draw_symbol_degree( 20, 5, 1,1);
        //lcd_putc( 20, 5, 0x1E, 0);     // alternativ: degree symbol  
       
                //-----------------------------------------
                // unterste Zeile
                //-----------------------------------------
                draw_symbol_rc(20,7);                   // RC-transmitter
        }
       
    //-----------------
    // Batt Level (Volt)
    //-----------------
        OSD_Element_BattLevel2( 2, 0, 0,0 );

    //-----------------
    // LowBat Warnung MK
    //-----------------
        OSD_Element_Flag( 8, 0, OSD_FLAG_BA, 0,0 );

    //-----------------
    // Flugzeit
    //-----------------
        writex_time(2, 1, naviData->FlyingTime, MNORMAL, 0,1);

    //-----------------
        // entnommene Kapazitaet (mAh)
    //-----------------
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL);
        writex_ndigit_number_u( 2, 2, naviData->UsedCapacity, 5, 0, drawmode, 0,2);
       
    //-----------------
    // Höhe
    //-----------------
        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
        write_ndigit_number_s ( 16, 0, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, MNORMAL);
        else                                                                                                                                                                                                    // up to 10m write meters.dm
        write_ndigit_number_s_10th( 16, 0, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, MNORMAL);

    //-----------------
    // steigen / sinken
    //-----------------
        OSD_Element_UpDown( 20, 0, 2,0);

    //-----------------
        // Compass Degree
    //-----------------
    writex_ndigit_number_u (17, 1, naviData->CompassHeading, 3, 0,MNORMAL, 0,1);

    //-----------------
    // Strom
    //-----------------
        //write_ndigit_number_u_10th( 16, 2, naviData->Current, 3, 0,0);  // alternativ mit Nachkomma
        writex_ndigit_number_u( 17, 2, naviData->Current/10, 3, 0,MNORMAL, 0,2);

    //-----------------
        // Sat Anzahl
    //-----------------
        write_ndigit_number_u (4, 4, naviData->SatsInUse, 2, 0,MNORMAL);

    //-----------------
        // Sat Warnung "!"
    //-----------------
        /*
        if( naviData->NCFlags & NC_FLAG_GPS_OK )
                lcd_printp_at( 9, 4, PSTR(" "), MNORMAL);
        else
                lcd_printp_at( 9, 4, PSTR("!"), MNORMAL);
        */
     
        OSD_Element_Flag(  8, 4, OSD_FLAG_S0, -1,0 );  // Sat Warnung (GPS not ok)

    //-----------------
        // Geschwindigkeit
    //-----------------
        writex_ndigit_number_u( 3, 5, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL, 0,1);

    //-----------------
        // Home Distance
    //-----------------
        write_ndigit_number_u( 17, 4, naviData->HomePositionDeviation.Distance / 10, 3, 0,MNORMAL);

    //-----------------
        // Home Winkel
    //-----------------
    writex_ndigit_number_u( 16, 5, heading_home, 4, 0,MNORMAL, 0,1);

    //-----------------
    // Flags
    //-----------------
        OSD_Element_Flag(  1, 7, OSD_FLAG_CF, 0,0 );  // Care Free
        OSD_Element_Flag(  4, 7, OSD_FLAG_AH, 0,0 );  // Altitude Hold
        OSD_Element_Flag(  7, 7, OSD_FLAG_PH, 0,0 );  // Position Hold
        OSD_Element_Flag( 10, 7, OSD_FLAG_CH, 0,0 );  // Coming Home
        OSD_Element_Flag( 13, 7, OSD_FLAG_EL, 0,0 );  // Emergency Landing

    //-----------------
    // RC-Quality (MK)
    //-----------------
        write_ndigit_number_u( 17, 7, naviData->RC_Quality, 3, 0,MNORMAL);

        #ifdef OSD_DEMO
        //-----------------
        // Flags
        //-----------------
                OSD_Element_Flag_Label(  8, 0, OSD_FLAG_BA, true, 0,0 );        // DEMO: Batterie Warnung
                OSD_Element_Flag_Label(  8, 4, OSD_FLAG_S0, true, -1,0 );       // DEMO: Sat Warnung (GPS not ok)

                OSD_Element_Flag_Label(  1, 7, OSD_FLAG_CF, true, 0,0 );        // DEMO
                OSD_Element_Flag_Label(  4, 7, OSD_FLAG_AH, true, 0,0 );        // DEMO
                OSD_Element_Flag_Label(  7, 7, OSD_FLAG_PH, true, 0,0 );        // DEMO
                OSD_Element_Flag_Label( 10, 7, OSD_FLAG_CH, true, 0,0 );        // DEMO
                OSD_Element_Flag_Label( 13, 7, OSD_FLAG_EL, true, 0,0 );        // DEMO
    #endif     


        return( ScreenName );
}


//--------------------------------------------------------------
// OSD-Screen "Navigation"
//
// nRefreshMode:        0 = update values
//                              1 = redraw labels and update values  
//--------------------------------------------------------------
const char * OSD_Screen_Navigation( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("Navigation");
        int8_t xoffs, yoffs;

        //-----------------------------------------
        // REDRAW
        // statische Screen Elemente die nicht
        // jedesmal neu gezeichnet werden muessen
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
               
        lcd_line ((6*6-3), 0, (6*6-3), 9, 1);                                           // Linie Vertikal links
        lcd_line ((15*6+5), 0, (15*6+5), 9, 1);                                         // Linie Vertikal rechts
        lcd_line (0, 10, 127, 10, 1);                                                           // Linie Horizontal

                lcdx_printp_at( 0, 2, PSTR("Alt:"), MNORMAL, 0,2);              // Hoehe
                lcdx_printp_at( 0, 5, PSTR("Home:"), MNORMAL, 0,3);             // Home Distance
    }


    //-----------------
    // Oben: Batt Level (Volt)
    //-----------------
        OSD_Element_BattLevel2( 0, 0, 0,0 );

    //-----------------
    // Oben: Kompass Rose
    //-----------------
    draw_compass( 6, 0, naviData->CompassHeading, 2,0);

    //-----------------
    // Oben: Flugzeit
    //-----------------
        writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0);

    //-----------------
    // Hoehe
    //-----------------
    xoffs = 0;
    yoffs = 3;
        drawmode = MNORMAL;
        if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
        writex_ndigit_number_s ( 0, 3, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, drawmode, xoffs,yoffs);
        else                                                                                                                                                                                                    // up to 10m write meters.dm
        writex_ndigit_number_s_10th( 0, 3, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, drawmode, xoffs,yoffs);

    //-----------------
    // Steigen / Sinken
    //-----------------
        OSD_Element_UpDown( 4, 3, 1,yoffs);

    //-----------------
    // Home Distance
    //-----------------
    yoffs = 3;
        writex_ndigit_number_u( 0, 6, naviData->HomePositionDeviation.Distance / 10, 4, 0,MNORMAL, 0,yoffs+1);
        lcdx_printp_at( 4, 6, PSTR("m"), MNORMAL, 2,yoffs+1);           // Home
       
    //-----------------
    // Home Circle
    //-----------------
    xoffs = 2;
    yoffs = 3;
        OSD_Element_HomeCircle(  8, 3, 9, 4, xoffs,yoffs);                                              // Home Circle
        lcd_frect( (9*6)-3+xoffs, (4*8)-2+yoffs, (3*6)+4, (1*8)+2, 0);                  // inner clear
        lcd_rect ( (9*6)-4+xoffs, (4*8)-3+yoffs, (3*6)+6, (1*8)+4, 1);                  // inner rect
        lcd_frect ( 61+xoffs, 57+yoffs, 2, 2, 1);                                                               // bottom mini rect
    writex_ndigit_number_u( 9, 4, heading_home, 3, 0,MNORMAL, xoffs,yoffs);     // Degree (Winkel)

    //-----------------
    // Variometer
    //-----------------
    // OG: nein, Variometer wird erstmal nicht angezeigt weil es den Screen zu voll macht
    //     wenn doch muessen erst grafische Anpassungen an den Variometer-Code gemacht
    //     werden
        //void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
        //draw_variometer( 95, 38,  7, 30, naviData->Variometer);
        //draw_variometer( 94, 38,  7, 21, naviData->Variometer);
        //draw_variometer2( 94, 28,  7, 21, naviData->Variometer);

    //-----------------
    // Flags
    //-----------------
        OSD_Element_Flag(  16, 2, OSD_FLAG_BA, -3, 0);  // MK Batt Warning
        OSD_Element_Flag(  19, 2, OSD_FLAG_CF,  0, 0);  // Carefree
        OSD_Element_Flag(  19, 4, OSD_FLAG_AH,  0,-3);  // Altitude Hold
        OSD_Element_Flag(  19, 6, OSD_FLAG_PH,  0,-6);  // Position Hold
        OSD_Element_Flag(  19, 7, OSD_FLAG_CH,  0,-1);  // Coming Home
        OSD_Element_Flag(  16, 7, OSD_FLAG_S0, -3,-1);  // GPS-Sat not ok (GPS NOT ok)


    #ifdef OSD_DEMO
        //-----------------
        // Flags
        //-----------------
                OSD_Element_Flag_Label(  16, 2, OSD_FLAG_BA, true, -3,0);       // DEMO
               
                OSD_Element_Flag_Label(  19, 2, OSD_FLAG_CF, true, 0,0);        // DEMO
                OSD_Element_Flag_Label(  19, 4, OSD_FLAG_AH, true, 0,-3);       // DEMO
                OSD_Element_Flag_Label(  19, 6, OSD_FLAG_PH, true, 0,-6);       // DEMO
                OSD_Element_Flag_Label(  19, 7, OSD_FLAG_CH, true, 0,-1);       // DEMO

                OSD_Element_Flag_Label(  16, 7, OSD_FLAG_S0, true, -3,-1);      // DEMO
    #endif     


        return( ScreenName );
}




//--------------------------------------------------------------
// OSD-Screen "Status"
//
// nRefreshMode:        0 = update values
//                              1 = redraw labels and update values  
//--------------------------------------------------------------
const char * OSD_Screen_MKStatus( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("MK-Status");
        int8_t          xoffs, yoffs;

        //-----------------------------------------
        // REDRAW
        // statische Screen Elemente die nicht
        // jedesmal neu gezeichnet werden muessen
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
               
        lcd_line(  (6*6-3), 0, (6*6-3), 9, 1);                                          // Linie vertikal oben, links
        lcd_line( (15*6+3), 0, (15*6+3), 9, 1);                                         // Linie vertikal oben, rechts
        lcd_line( 0, 10, 127, 10, 1);                                                           // Linie horizontal oben

                //lcdx_printp_at( 8, 0, PSTR("Status"), MNORMAL, -3,0);         // oben, mitte Text
                //lcdx_printp_at( 13, 0, PSTR("A"), MNORMAL, -4,0);                     // oben, mitte "A"
                lcdx_printp_at( 12,0 , PSTR("mAh"), MNORMAL, -1,0);                     // "mAh" (entnommene Kapazität)

        lcd_line(   0, 10,   0, 63, 1);                                                         // Linie vertikal unten, links
        lcd_line( 127, 10, 127, 63, 1);                                                         // Linie vertikal unten, rechts
        lcd_line( 0, 63, 127, 63, 1);                                                           // Linie horizontal unten

    }


    //-----------------
    // Oben: Batt Level (Volt)
    //-----------------
        OSD_Element_BattLevel2( 0, 0, 0,0 );

    //-----------------
    // Strom
    //-----------------
        //writex_ndigit_number_u_10th( 7, 0, naviData->Current, 4, 0,MNORMAL, 1,0);  // Strom mit Nachkomma

    //-----------------
        // entnommene Kapazitaet (mAh)
    //-----------------
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL);
        //writex_ndigit_number_u( 7, 0, naviData->UsedCapacity * 10, 5, 0, drawmode, -3,0);  // DEBUG
        writex_ndigit_number_u( 7, 0, naviData->UsedCapacity, 5, 0, drawmode, -3,0);

    //-----------------
    // Oben: Flugzeit
    //-----------------
        writex_time( 16, 0, naviData->FlyingTime, MNORMAL, 2,0);
       
    //-----------------
    // Flags
    //-----------------
        yoffs = -2;
    xoffs = -7;
        OSD_Element_Flag(  19, 2, OSD_FLAG_CF,  0+xoffs, 0+yoffs);      // Carefree
        OSD_Element_Flag(  19, 4, OSD_FLAG_AH,  0+xoffs,-3+yoffs);      // Altitude Hold
        OSD_Element_Flag(  19, 6, OSD_FLAG_PH,  0+xoffs,-6+yoffs);      // Position Hold
        OSD_Element_Flag(  19, 7, OSD_FLAG_CH,  0+xoffs,-1+yoffs);      // Coming Home
                                                           
    xoffs -= 4;                                            
        OSD_Element_Flag(  16, 2, OSD_FLAG_BA, -3+xoffs, 0+yoffs);      // MK Batt Warning
        OSD_Element_Flag(  16, 4, OSD_FLAG_EL, -3+xoffs,-3+yoffs);      // Emergency Landing
        OSD_Element_Flag(  16, 6, OSD_FLAG_RL, -3+xoffs,-6+yoffs);      // Range Limit
        OSD_Element_Flag(  16, 7, OSD_FLAG_S0, -3+xoffs,-1+yoffs);      // GPS-Sat not ok (GPS NOT ok)
                                                           
    xoffs -= 4;                                            
        OSD_Element_Flag(  12, 2, OSD_FLAG_CA,  0+xoffs, 0+yoffs);      // Calibrate
        OSD_Element_Flag(  12, 4, OSD_FLAG_ST,  0+xoffs,-3+yoffs);      // Start
        OSD_Element_Flag(  12, 6, OSD_FLAG_MR,  0+xoffs,-6+yoffs);      // Motor Run
        OSD_Element_Flag(  12, 7, OSD_FLAG_FY,  0+xoffs,-1+yoffs);      // Fly
                                                           
    xoffs -= 4;                                            
        OSD_Element_Flag(   9, 2, OSD_FLAG_O1, -2+xoffs, 0+yoffs);      // Out1
        OSD_Element_Flag(   9, 4, OSD_FLAG_O2, -2+xoffs,-3+yoffs);      // Out2
        OSD_Element_Flag(   9, 6, OSD_FLAG_TR, -2+xoffs,-6+yoffs);      // Target Reached
        OSD_Element_Flag(   9, 7, OSD_FLAG_MC, -2+xoffs,-1+yoffs);      // Manual Control
                                                           
    xoffs -= 4;                                            
        OSD_Element_Flag(   6, 2, OSD_FLAG_TU, -4+xoffs, 0+yoffs);      // Vario Trim Up
        OSD_Element_Flag(   6, 4, OSD_FLAG_TD, -4+xoffs,-3+yoffs);      // Vario Trim Down
        OSD_Element_Flag(   6, 6, OSD_FLAG_FR, -4+xoffs,-6+yoffs);      // Free
        OSD_Element_Flag(   6, 7, OSD_FLAG_SL, -4+xoffs,-1+yoffs);      // No Serial Link


    #ifdef OSD_DEMO
        //-----------------
        // Flags
        //-----------------
 /*
                PSTR("AH"),  // OSD_FLAG_AH  Altitue Hold
                PSTR("PH"),  // OSD_FLAG_PH  Position Hold
                PSTR("CF"),  // OSD_FLAG_CF  Care Free
                PSTR("CH"),  // OSD_FLAG_CH  Coming Home
                PSTR("o1"),  // OSD_FLAG_O1  Out1
                PSTR("o2"),  // OSD_FLAG_O2  Out2
                PSTR("BA"),  // OSD_FLAG_BA  LowBat warning (MK)
                PSTR("CA"),  // OSD_FLAG_CA  Calibrate
                PSTR("ST"),  // OSD_FLAG_ST  Start
                PSTR("MR"),  // OSD_FLAG_MR  Motor Run
                PSTR("FY"),  // OSD_FLAG_FY  Fly
                PSTR("EL"),  // OSD_FLAG_EL  Emergency Landing
                PSTR("FS"),      // OSD_FLAG_FS  RX Failsave Active
                PSTR("GP"),  // OSD_FLAG_GP  GPS Ok
                PSTR("S!")       // OSD_FLAG_S0  GPS-Sat not ok (GPS NOT ok)
                PSTR("TU"),  // OSD_FLAG_TU  Vario Trim Up
                PSTR("TD"),  // OSD_FLAG_TD  Vario Trim Down
                PSTR("FR"),  // OSD_FLAG_FR  Free
                PSTR("RL"),  // OSD_FLAG_RL  Range Limit
                PSTR("SL"),  // OSD_FLAG_SL  No Serial Link
                PSTR("TR"),  // OSD_FLAG_TR  Target Reached
                PSTR("MC")   // OSD_FLAG_MC  Manual Control            
*/

                yoffs = -2;
        xoffs = -7;    
                OSD_Element_Flag_Label(  19, 2, OSD_FLAG_CF, true,  0+xoffs, 0+yoffs);  // DEMO: Carefree
                OSD_Element_Flag_Label(  19, 4, OSD_FLAG_AH, true,  0+xoffs,-3+yoffs);  // DEMO: Altitude Hold
                OSD_Element_Flag_Label(  19, 6, OSD_FLAG_PH, true,  0+xoffs,-6+yoffs);  // DEMO: Position Hold
                OSD_Element_Flag_Label(  19, 7, OSD_FLAG_CH, true,  0+xoffs,-1+yoffs);  // DEMO: Coming Home

        xoffs -= 4;
                OSD_Element_Flag_Label(  16, 2, OSD_FLAG_BA, true, -3+xoffs, 0+yoffs);  // DEMO: MK Batt Warning
                OSD_Element_Flag_Label(  16, 4, OSD_FLAG_EL, true, -3+xoffs,-3+yoffs);  // DEMO: Emergency Landing
                OSD_Element_Flag_Label(  16, 6, OSD_FLAG_RL, true, -3+xoffs,-6+yoffs);  // DEMO: Range Limit
                OSD_Element_Flag_Label(  16, 7, OSD_FLAG_S0, true, -3+xoffs,-1+yoffs);  // DEMO: GPS-Sat not ok (GPS NOT ok)

        xoffs -= 4;
                OSD_Element_Flag_Label(  12, 2, OSD_FLAG_CA, true,  0+xoffs, 0+yoffs);  // DEMO: Calibrate
                OSD_Element_Flag_Label(  12, 4, OSD_FLAG_ST, true,  0+xoffs,-3+yoffs);  // DEMO: Start
                OSD_Element_Flag_Label(  12, 6, OSD_FLAG_MR, true,  0+xoffs,-6+yoffs);  // DEMO: Motor Run
                OSD_Element_Flag_Label(  12, 7, OSD_FLAG_FY, true,  0+xoffs,-1+yoffs);  // DEMO: Fly

        xoffs -= 4;
                OSD_Element_Flag_Label(   9, 2, OSD_FLAG_O1, true, -2+xoffs, 0+yoffs);  // DEMO: Out1
                OSD_Element_Flag_Label(   9, 4, OSD_FLAG_O2, true, -2+xoffs,-3+yoffs);  // DEMO: Out2
                OSD_Element_Flag_Label(   9, 6, OSD_FLAG_TR, true, -2+xoffs,-6+yoffs);  // DEMO: Target Reached
                OSD_Element_Flag_Label(   9, 7, OSD_FLAG_MC, true, -2+xoffs,-1+yoffs);  // DEMO: Manual Control

        xoffs -= 4;
                OSD_Element_Flag_Label(   6, 2, OSD_FLAG_TU, true, -4+xoffs, 0+yoffs);  // DEMO: Vario Trim Up
                OSD_Element_Flag_Label(   6, 4, OSD_FLAG_TD, true, -4+xoffs,-3+yoffs);  // DEMO: Vario Trim Down
                OSD_Element_Flag_Label(   6, 6, OSD_FLAG_FR, true, -4+xoffs,-6+yoffs);  // DEMO: Free
                OSD_Element_Flag_Label(   6, 7, OSD_FLAG_SL, true, -4+xoffs,-1+yoffs);  // DEMO: No Serial Link

    #endif     


        return( ScreenName );
}



//##############################################################
#ifdef OSD_DEBUG_SCREEN
//##############################################################

//**************************************************************
//* OSD_DEBUG_SCREEN - Experimental-Code usw.
//* - nicht fuer die Oeffentlichkeit bestimmt
//* - gesteuert ueber define OSD_DEBUG_SCREEN
//**************************************************************

//--------------------------------------------------------------
//--------------------------------------------------------------
const char * OSD_Screen_Debug( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("Debug");
       
        static s16              min_debug = 0;
        static s16              max_debug = 0;
        static uint16_t debug_count = 0;
        uint8_t y;

        //uint8_t status;               // FC Kommunikation

        //-----------------------------------------
        // REDRAW
        // statische Screen Elemente die nicht
        // jedesmal neu gezeichnet werden muessen
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
                min_debug = 0;
                max_debug = 0;
                lcd_printp_at( 0, 0, PSTR("Debug"), 0);
               
                memset( blData,                 0, sizeof(BLData_t) * MAX_MOTORS );
                //memset( blDataCounter,        0, sizeof(uint16_t) * MAX_MOTORS );
    }


    debug_count++;
   
    write_ndigit_number_u ( 16, 0, (debug_count), 4, 0,MNORMAL);   //  


    Get_BL_Data();
   

    y = 1;
    write_ndigit_number_u ( 0,  y+0, ( blData[0].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+0, ( blData[1].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+0, ( blData[2].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+0, ( blData[3].Temperature), 3, 0,MNORMAL);   //  

    write_ndigit_number_u ( 0,  y+1, ( blData[4].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+1, ( blData[5].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+1, ( blData[6].Temperature), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+1, ( blData[7].Temperature), 3, 0,MNORMAL);   //  


//Current
    y = 4;
    write_ndigit_number_u ( 0,  y+0, ( blData[0].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+0, ( blData[1].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+0, ( blData[2].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+0, ( blData[3].Current), 3, 0,MNORMAL);   //  

    write_ndigit_number_u ( 0,  y+1, ( blData[4].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+1, ( blData[5].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+1, ( blData[6].Current), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+1, ( blData[7].Current), 3, 0,MNORMAL);   //  

/*
    y = 4;
    write_ndigit_number_u ( 0,  y+0, ( blDataCounter[0]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+0, ( blDataCounter[1]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+0, ( blDataCounter[2]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+0, ( blDataCounter[3]), 3, 0,MNORMAL);   //  

    write_ndigit_number_u ( 0,  y+1, ( blDataCounter[4]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 5,  y+1, ( blDataCounter[5]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 10, y+1, ( blDataCounter[6]), 3, 0,MNORMAL);   //  
    write_ndigit_number_u ( 15, y+1, ( blDataCounter[7]), 3, 0,MNORMAL);   //  
*/


        return( ScreenName );
}
//##############################################################
#endif  // OSD_DEBUG_SCREEN
//##############################################################




//--------------------------------------------------------------
// OSD_Screen_Electric( nRefreshMode )
//--------------------------------------------------------------
const char * OSD_Screen_Electric( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("Electric");
       
        uint8_t x, y, x0, y0;
        int8_t  yoffs;

        //-----------------------------------------
        // REDRAW
        // statische Screen Elemente die nicht
        // jedesmal neu gezeichnet werden muessen
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....            
        lcd_line (0, 19, 127, 19, 1);                                                           // Linie horizontal oben
        lcd_line (0, 41, 127, 41, 1);                                                           // Linie horizontal mitte
        lcd_line (0, 63, 127, 63, 1);                                                           // Linie horizontal unten

        lcd_line (33, 0, 33, 19, 1);                                                            // Linie vertikal oben, links
        lcd_line (93, 0, 93, 19, 1);                                                            // Linie vertikal oben, rechts

        lcd_line (  0, 19,   0, 64, 1);                                                         // Linie vertikal nach unten, links
        lcd_line (127, 19, 127, 64, 1);                                                         // Linie vertikal nach unten, rechts

                lcdx_printp_at( 12,0 , PSTR("mAh"), MNORMAL, -1,0);                     // entnommene Kapazität
                lcdx_printp_at( 12,1 , PSTR("A")  , MNORMAL, -1,1);                     // aktueller Strom

                writex_ndigit_number_u( 3, 1, cells, 1, 0, drawmode, 0,1);      // LiPO Cells Wert
                lcdx_printp_at( 4,1 , PSTR("S")  , MNORMAL, 1,1);                       // LiPO Cells "S"
               
    } // end: if( nRefreshMode == OSD_SCREEN_REDRAW )
        //-----------------------------------------


    //-----------------
    // Oben: Batt Level (Volt)
    //-----------------
        OSD_Element_BattLevel2( 0, 0, 0,0 );

    //-----------------
        // Oben: entnommene Kapazitaet (mAh)
    //-----------------
        drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL);
        writex_ndigit_number_u( 7, 0, naviData->UsedCapacity, 5, 0, drawmode, -3,0);

    //-----------------
    // Oben: Flugzeit
    //-----------------
        //writex_time(16, 0, naviData->FlyingTime+900, MNORMAL, 2,0);  // DEBUG
        writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0);

    //-----------------
    // Strom
    //-----------------
        writex_ndigit_number_u_10th( 7, 1, naviData->Current, 4, 0,MNORMAL, -3,1);  // Strom mit Nachkomma

    //-----------------
    // MK-BattLow Warnung
    //-----------------
        OSD_Element_Flag( 19, 1, OSD_FLAG_BA, 0,1);     // MK-BattLow

    //-----------------
    // BL 1-8 Temp & Strom
    //-----------------
        //for( y=0; y<MAX_MOTORS; y++)          // DEBUG                       
        //      blData[y].Temperature = 0;      }

    x0 = 1;
    y0 = 4;
        for( y=0; y<2; y++)                                                                     // 2 Zeilen (mit je 4 BL's/Motoren)
        {
                if( y==0 )      yoffs = -9;
                else            yoffs = -3;
                       
                for( x=0; x<4; x++)                                                             // und 4 BL's/Motoren pro Zeile
                {
                        if( blData[y*4+x].Status & 0xf0 )                       // BL/Motor vorhanden?
                        {      
                                if( blData[y*4+x].Temperature != 0 )    // Anzeige nur wenn Temp != 0 wegen BL-Ctrl v1 die keine Temperatur senden
                                {      
                                writex_ndigit_number_u ( (x*5)+x0,   (y*2)+y0+0, ( blData[y*4+x].Temperature    ), 3, 0,MNORMAL, 0,yoffs);      // Temperatur
                                        draw_symbol_degree         ( (x*5)+3+x0, (y*2)+y0+0,                                                                                             1,yoffs);      // Label (Temperatur)
                                }
                        writex_ndigit_number_u (   (x*5)+x0, (y*2)+y0+1, ( blData[y*4+x].Current / 10), 3, 0, MNORMAL, 0,yoffs);                // Strom
                                lcdx_printp_at         ( (x*5)+3+x0, (y*2)+y0+1, PSTR("A")                                                      , MNORMAL, 2,yoffs);            // Label (Strom)
                }
                }
        }

    #ifdef OSD_DEMO
                OSD_Element_Flag_Label(  19, 1, OSD_FLAG_BA, true, 0,1);        // DEMO
    #endif


    //-----------------
    // GET: BL-Data
    //-----------------
    Get_BL_Data();
   
        return( ScreenName );
}


//--------------------------------------------------------------
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 0
//--------------------------------------------------------------
const char * OSD_Screen_OSD0( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("OSD0");
        //uint8_t xoffs;

        //-----------------------------------------
        // REDRAW static screen elements
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
    }

        OSD_Element_AltitudeControl ( 0, 3);
        OSD_Element_Altitude        ( 11, 3, 0);
        OSD_Element_BatteryLevel    (  0, 7, 0);
        OSD_Element_Capacity        ( 13, 7);
        OSD_Element_Current         (  8, 7);
        OSD_Element_CareFree        (  0, 5);
        OSD_Element_CompassDegree   ( 13, 0, 0);
        OSD_Element_CompassDirection( 18, 0);
        OSD_Element_CompassRose     ( 12, 1);
        OSD_Element_FlyingTime      (  0, 1);
        OSD_Element_GroundSpeed     (  0, 0);
        OSD_Element_HomeCircle      ( 16, 4, 5, 0, 0,0);
        OSD_Element_HomeDegree      ( 12, 4);
        OSD_Element_HomeDistance    ( 10, 5, 0);
        OSD_Element_Target          ( 10, 6, 0);
        //OSD_Element_TargetDegree  (  x, y);
        OSD_Element_WayPoint        (  5, 6);
        OSD_Element_LED1Output      (  0, 6);
        OSD_Element_LED2Output      (  3, 6);
        //OSD_Element_Manuell       (  x, y);
        OSD_Element_NaviMode        (  0, 4);
        //OSD_Element_RCIntensity   (  x, y);
        OSD_Element_VarioWert       ( 12, 2);
        OSD_Element_SatsInUse       ( 18, 2, 0);
        OSD_Element_StatusFlags     (  0, 2);
        OSD_Element_Variometer      (  9, 0);

        return( ScreenName );
}




//--------------------------------------------------------------
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 1
//--------------------------------------------------------------
const char * OSD_Screen_OSD1( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("OSD1");
        //uint8_t xoffs;

        //-----------------------------------------
        // REDRAW static screen elements
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
    }

        //OSD_Element_AltitudeControl( x, y);
        OSD_Element_Altitude        (  1, 1, 1);
        OSD_Element_BatteryLevel    (  0, 7, 1);
        OSD_Element_Capacity        ( 13, 7);
        OSD_Element_Current         (  8, 7);
        //OSD_Element_CareFree      (  x, y);
        OSD_Element_CompassDegree   ( 13, 0, 1);
        OSD_Element_CompassDirection( 18, 0);
        OSD_Element_CompassRose     ( 12, 1);
        OSD_Element_FlyingTime      (  7, 6);
        OSD_Element_GroundSpeed     (  0, 0);
        OSD_Element_HomeCircle      (  1, 3, 7, 0, 0,0);
        OSD_Element_HomeDegree      (  8, 3);
        OSD_Element_HomeDistance    (  7, 2, 1);
        //OSD_Element_Target        (  x, y, 1);
        //OSD_Element_TargetDegree  (  x, y);
        //OSD_Element_WayPoint      (  x, y);
        //OSD_Element_LED1Output    (  x, y);
        //OSD_Element_LED2Output    (  x, y);
        //OSD_Element_Manuell       (  x, y);
        OSD_Element_NaviMode        (  8, 5);
        OSD_Element_RCIntensity     ( 15, 6);
        OSD_Element_VarioWert       ( 15, 2);
        OSD_Element_SatsInUse       (  8, 4, 1);
        //OSD_Element_StatusFlags   (  x, y);
        OSD_Element_Variometer      (  9, 0);

        return( ScreenName );
}


//--------------------------------------------------------------
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 2
//--------------------------------------------------------------
const char * OSD_Screen_OSD2( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("OSD2");
        //uint8_t xoffs;

        //-----------------------------------------
        // REDRAW static screen elements
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
    }
               
        OSD_Element_AltitudeControl ( 0, 1);   
        OSD_Element_Altitude        (  0, 4, 2);
        OSD_Element_BatteryLevel    ( 13, 7, 2);
        OSD_Element_Capacity        (  0, 7);
        OSD_Element_Current         (  8, 7);
        OSD_Element_CareFree        (  0, 3);
        OSD_Element_CompassDegree   ( 12, 3, 2);
        //OSD_Element_CompassDirection( x, y);
        //OSD_Element_CompassRose   ( x, y);
        OSD_Element_FlyingTime      ( 15, 5);
        //OSD_Element_GroundSpeed   (  x, y);
        OSD_Element_HomeCircle      ( 16, 0, 5, 0, 0,0);
        OSD_Element_HomeDegree      ( 11, 5);
        OSD_Element_HomeDistance    (  0, 5, 2);
        OSD_Element_Target          (  0, 6, 2);
        OSD_Element_TargetDegree    ( 11, 6);
        //OSD_Element_WayPoint      (  x, y);
        OSD_Element_LED1Output      ( 12, 2);
        OSD_Element_LED2Output      ( 14, 2);
        //OSD_Element_Manuell       (  x, y);
        OSD_Element_NaviMode        (  0, 2);
        //OSD_Element_RCIntensity   (  x, y);
        OSD_Element_VarioWert       ( 15, 4);
        OSD_Element_SatsInUse       ( 10, 0, 2);
        OSD_Element_StatusFlags     (  0, 0);
        //OSD_Element_Variometer    (  x, y);

        return( ScreenName );
}


//--------------------------------------------------------------
//--------------------------------------------------------------
const char * OSD_Screen_3DLage( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("3D Lage");
        uint16_t head_home;
        uint8_t Nick;
        uint8_t Roll;

        //-----------------------------------------
        // REDRAW static screen elements
        //-----------------------------------------
        if( nRefreshMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
    }

        head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;

        //lcd_cls ();

        lcd_line(26,32,100,32,1);  // horizontal //
        lcd_line(63,0,63,63,1);    //  vertical  //
        //lcd_puts_at(12, 7, strGet(KEYLINE5), 0);

        // 45' Angel
        lcd_line(61,11,65,11,1);   //    --    //
        lcd_line(40,30,40,34,1);   //  |       //
        lcd_line(86,30,86,34,1);   //       |  //
        lcd_line(61,53,65,53,1);   //    --    //

        lcd_puts_at(9, 0, strGet(OSD_3D_V), 0);  // V
        lcd_puts_at(3, 3, strGet(OSD_3D_L), 0);  // L
        lcd_puts_at(17, 3, strGet(OSD_3D_R), 0); // R
        lcd_puts_at(9, 7, strGet(OSD_3D_H), 0);  // H

        lcd_puts_at(0, 0, strGet(OSD_3D_NICK), 0);      // Ni
        write_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0,0);
        lcd_putc (5, 0, 0x1e, 0);       // degree symbol

        lcd_puts_at(0, 7, strGet(OSD_3D_ROLL), 0);      // Ro
        write_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0,0);
        lcd_putc (5, 7, 0x1e, 0);       // degree symbol

        lcd_puts_at(13, 0, strGet(OSD_3D_COMPASS), 0);
    //write_ndigit_number_s (15, 0,head_home, 3, 0);
        write_ndigit_number_u (15, 0, naviData->CompassHeading, 3, 0,0);
        lcd_putc (18, 0, 0x1e, 0);      // degree symbol
        lcd_printp_at (19, 0, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);

        Nick = ((-naviData->AngleNick/2)+32);
        Roll = ((-naviData->AngleRoll/2)+63);

        lcd_ellipse     ( old_AngleRoll, old_AngleNick, 9, 8, 0);
        lcd_ellipse_line( old_AngleRoll, old_AngleNick, 8, 7, old_hh, 0);

        lcd_ellipse     ( Roll, Nick, 9, 8, 1);
        lcd_ellipse_line( Roll, Nick, 8, 7, head_home, 1);

        // remember last values (3DL)
        old_hh                  = head_home;
        old_AngleNick   = Nick;
        old_AngleRoll   = Roll;
                               
        return( ScreenName );
}


//--------------------------------------------------------------
//--------------------------------------------------------------
const char * OSD_Screen_Statistics( uint8_t nRefreshMode )
{
        const char *ScreenName = PSTR("Statistics");
        uint8_t line = 0;

        //-----------------------------------------
        // REDRAW static screen elements
        //-----------------------------------------
        /*
        if( nMode == OSD_SCREEN_REDRAW )
        {      
                // do things here for static screen elements like labels and so....
    }
    */

   
        //---------------------------
        // max Altitude
        lcd_puts_at (0, line, strGet(STATS_ITEM_0), MNORMAL);
        write_ndigit_number_s (14, line, max_Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL);
        lcdx_putc (18, line, 'm', MNORMAL, 2,0);
       
        //---------------------------
        // max Speed
        // max_GroundSpeed = 1;
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_1), MNORMAL);
        write_ndigit_number_u (15, line, (uint16_t) (((uint32_t) max_GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL);
        lcdx_printp_at(18, line, PSTR("kmh"), MNORMAL, 2,0);

        //---------------------------
        // max Distance
        // max_Distance = 64512;
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_2), MNORMAL);
        write_ndigit_number_u (14, line, max_Distance / 10, 4, 0,MNORMAL);
        lcdx_putc (18, line, 'm', MNORMAL, 2,0);
       
        //---------------------------
        // max time
        // max_FlyingTime = 3600;
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_4), MNORMAL);
        write_time (13, line, max_FlyingTime);

        //---------------------------
        // min voltage
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_3), MNORMAL);
        if( min_UBat==255 )
                lcd_printp_at(14, line, PSTR("   0"), MNORMAL);
        else
                write_ndigit_number_u_10th (14, line, min_UBat, 3, 0,MNORMAL);
        lcdx_putc (18, line, 'V', MNORMAL, 2,0);

        //---------------------------
        // max Current
        // max_Current = 1000;
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_5), MNORMAL);
        write_ndigit_number_u_10th (13, line, max_Current, 4, 0,MNORMAL);
        lcdx_putc (18, line, 'A', MNORMAL, 2,0);

        //---------------------------
        // Used Capacity
        lcd_puts_at (0, ++line, strGet(STATS_ITEM_6), MNORMAL);
        write_ndigit_number_u (14, line, max_Capacity, 4, 0,MNORMAL);
        lcdx_printp_at(18, line, PSTR("mAh"), MNORMAL, 2,0);
                               
        return( ScreenName );
}
               

//--------------------------------------------------------------
//--------------------------------------------------------------
void print_statistics (void)
{
        lcd_cls ();
        lcd_puts_at(12, 7, strGet(ENDE), 0);

    OSD_Screen_Statistics( OSD_SCREEN_REDRAW );

        while (!get_key_press (1 << KEY_ESC))
                timer = TIMEOUT;

        COSD_FLAGS2 &= ~COSD_WASFLYING;
        get_key_press(KEY_ALL);
        lcd_cls();
}


//-----------------------------------------------------------
//-----------------------------------------------------------
void OSD_Info( uint8_t ScreenNum, const char *ScreenName)
{
    lcd_frect(     0, 36, 127, 10, 0);  // clear
    lcd_frect(     0, 34,   4,  4, 0);  // clear links
    lcd_frect(     0, 40, 127, 24, 1);  // Box
    lcd_frect(    10, 36, 108, 4, 1);   // Filler oben
    lcd_fcircle(   8, 39,   7, 1);              // Links
    lcd_fcircle( 121, 41,   5, 1);      // Rechts

        lcd_line (     4, 51, 122, 51, 0);  // Linie mitte

    //-----------------------
    // ScreenNummer: ScreenName
    //-----------------------
    write_ndigit_number_s ( 1, 5, ScreenNum, 2,  1,2);
    lcd_printp_at( 3, 5, PSTR(":"), 2);
    lcd_printp_at( 5, 5, ScreenName, 2);

    //-----------------------
    // Key's
    //-----------------------
    lcd_puts_at(0, 7, strGet(KEYLINE3), 2);
        lcd_printp_at (17, 7, PSTR("Info"), 2);
       
        do
        {
                timer = TIMEOUT;
                _delay_ms(50);
        } 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))  ) );
}



//##############################################################
//# OSD MAIN LOOP
//##############################################################

//--------------------------------------------------------------
// OSD MAIN LOOP
//--------------------------------------------------------------
void osd( uint8_t ShowMode )
{
        uint8_t flag;
        uint8_t tmp_dat;
        uint8_t ScreenRefresh;
        uint8_t MAX_OSD_Screens;
        //uint8_t status;               // FC Kommunikation
       
        const char *ScreenName = PSTR("");

        lcd_cls();     

    //----------------------------------------
    // NC Hardware needed
    //----------------------------------------
        if( hardware == FC )
        {
                lcd_puts_at(0, 3, strGet(ONLY_NC), 0);  // Nur mit NC
                timer = 100;
                while (timer > 0);
                return;
        }

   
    /*
    //-----------------------------------------------------------------------------------------------
    // 07.03.2013 OG: del
    //   Dieser Teil hat immer wieder Probleme bereitet bei der Verbindung des PKT-OSD zum MK da
    //   Timeouts zustande kamen. Eine Recherche im Code ergab, dass die Nutzdaten die
    //   hierueber bezogen werden sich lediglich auf Flags_ExtraConfig beschraenkten (CFG2_HEIGHT_LIMIT).
    //   Siehe dazu untere Kommentare.
    //   
    //   Der negative Effekt moeglicher Timeouts und Verzoegerungen sind es aktuell nicht Wert
    //   CFG2_HEIGHT_LIMIT zu unterstuetzen. Dieses Feature ist erstmal raus.
    //
    //   Falls gewuenscht wird, dass CFG2_HEIGHT_LIMIT wieder in das PKT-OSD kommt muss
    //   es zuverlaessig an anderer Stelle implementiert werden - und zwar nicht in osd.c
    //   weil es eine statische FC-Information ist (ggf. beim Verbindungsaufbau PKT <-> MK).
    //
    //   Hat auch aktuell Auswirkung auf den Code OSD_Element_AltitudeControl()
    //
        lcd_printp_at( 0, 3, PSTR("connecting MK..."), 0);

    SwitchToFC();

        status = load_setting(0xff);
       
        if( status == 255 )
        {
                lcd_puts_at(0, 0, strGet(NO_SETTINGS), 0);      // Keine Settings
                _delay_ms(2000);
        }
        Flags_ExtraConfig       = mk_param_struct->ExtraConfig;         // OG: wird in osd.c nur verwendet von: OSD_Element_AltitudeControl()
        Flags_GlobalConfig      = mk_param_struct->GlobalConfig;        // OG: wird nicht in osd.c verwendet
        Flags_GlobalConfig3 = mk_param_struct->GlobalConfig3;   // OG: wird nicht in osd.c verwendet
        */

       

    rxd_buffer_locked = FALSE;  // 07.03.2013 OG: fix
                                                        //   es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den
                                                        //   OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt'
   
        SwitchToNC();

        mode = 'O';

        // disable debug...
        //      RS232_request_mk_data (0, 'd', 0);
        tmp_dat         = 0;
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);

        // request OSD Data from NC every 100ms
        //      RS232_request_mk_data (1, 'o', 100);
    OSD_active  = true;              // benoetigt für Navidata Ausgabe an SV2
        tmp_dat         = 10;
        SendOutData( 'o', ADDRESS_NC, 1,  &tmp_dat, 1);
       

        //-------------------------
        // Clear statistics
        //-------------------------
        max_Altimeter     = 0;
        max_GroundSpeed   = 0;
        max_Distance      = 0;
        min_UBat          = 255;
        max_FlyingTime    = 0;
        CellIsChecked     = 0;
        cells             = 0;
        AkkuWarnThreshold = 0;
        OldWP             = 0;
        NextWP            = false;

        //-------------------------
        // Init BL-Data
        //-------------------------
        memset( blData, 0, sizeof(BLData_t) * MAX_MOTORS );
       
        //-------------------------
        //-------------------------
        MAX_OSD_Screens = 9;

        #ifdef OSD_DEBUG_SCREEN
                MAX_OSD_Screens += 1;
    #endif
       
        if( Config.OSD_ScreenMode >= MAX_OSD_Screens ) Config.OSD_ScreenMode = 0;


        //-------------------------
        // Timer & Flags
        //-------------------------
        ScreenRefresh   = OSD_SCREEN_REDRAW;
        flag                    = 0;
        timer                   = TIMEOUT;
        abo_timer               = ABO_TIMEOUT;
        timer2                  = OSD_REFRESH_TIME;

               
        do
        {
                if( rxd_buffer_locked )
                {
                        timer = TIMEOUT;
                        Decode64 ();
                        naviData = (NaviData_t *) pRxData;

                        //----------------------------------
                        // LiPo Cell Check
                        //----------------------------------
                        if( cells == 0 ) // Zellenzahl noch nicht ermittelt?
                        {
                // up to 6s LiPo, less than 2s is technical impossible
                for(cells = 2; cells < 7; cells++)
                {
                        if( naviData->UBat < cells * MAX_CELL_VOLTAGE ) break;
                }
            }
           
               
                        //----------------------------------
                // Winkel zu Home
                        //----------------------------------
                if( Config.OSD_HomeMKView == 1 )
                        heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
                else
                        heading_home = (naviData->CompassHeading - naviData->HomePositionDeviation.Bearing + 360 ) % 360;


                        //----------------------------------
                        // speichere letzte GPS-Positionen
                        //----------------------------------
                        GPS_Pos_t currpos;
                        currpos.Latitude  = naviData->CurrentPosition.Latitude;
                        currpos.Longitude = naviData->CurrentPosition.Longitude;

                        if((currpos.Latitude != last5pos[0].Latitude)&&(currpos.Longitude != last5pos[0].Longitude))
                        {
                                last5pos[6] = last5pos[5];
                                last5pos[5] = last5pos[4];
                                last5pos[4] = last5pos[3];
                                last5pos[3] = last5pos[2];
                                last5pos[2] = last5pos[1];
                                last5pos[1] = last5pos[0];
                                last5pos[0] = currpos;
                        }

                        // 07.03.2013 OG: Speichere permanent letzte Position in Config
                        //   wurde vorher nur in OSD_TimeOut() gemacht
                        Config.LastLatitude  = currpos.Latitude;        // speichere letzte Position in Config
                        Config.LastLongitude = currpos.Longitude;       // speichere letzte Position in Config

                        flag = 1;

                        if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN)
                        { // should be engines running
                                // motors are on, assume we were/are flying
                                COSD_FLAGS2 |= COSD_WASFLYING;
                        }


                        //----------------------------------
                        // remember statistics (only when engines running)
                        //----------------------------------
                        if( naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN )
                        {
                                if (naviData->Altimeter > max_Altimeter)                                                max_Altimeter   = naviData->Altimeter;
                                if (naviData->GroundSpeed > max_GroundSpeed)                                    max_GroundSpeed = naviData->GroundSpeed;
                                if (naviData->HomePositionDeviation.Distance > max_Distance)    max_Distance    = naviData->HomePositionDeviation.Distance;
                                if (naviData->FlyingTime > max_FlyingTime)                                              max_FlyingTime  = naviData->FlyingTime;
                                if (naviData->UBat < min_UBat)                                                                  min_UBat                = naviData->UBat;
                                if (naviData->Current > max_Current)                                                    max_Current     = naviData->Current;
                                if (naviData->UsedCapacity > max_Capacity)                                              max_Capacity    = naviData->UsedCapacity;
                        }


                        //-----------------------
                        // Akku Warnung
                        //-----------------------
            CheckMKLipo();

//                      if (naviData->UBat > MK_LowBat)  //bei kurzzeitigen Schwankungen Beeper erst wieder aus wenn UBat 0,2 V höher als Warnschwelle
//                      { //Beeper aus
//                              BeepTime = 0;
//                              BeepMuster = 0xFFFF;
//                      }
//                       Akku Warnung Ende


                        //-----------------------
                        // remember last values
                        //-----------------------
                        last_RC_Quality = naviData->RC_Quality;
                        last_UBat               = naviData->UBat;
                        old_FCFlags     = naviData->FCStatusFlags;

                               
                        //----------------------------------
                        // OSD-Screens
                        //----------------------------------
                        if( ScreenRefresh == OSD_SCREEN_REDRAW )        lcd_cls();

                        if( timer2 == 0 || ScreenRefresh == OSD_SCREEN_REDRAW)
                        {      
                                if(      Config.OSD_ScreenMode == 0)    ScreenName = OSD_Screen_General( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 1)    ScreenName = OSD_Screen_Navigation( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 2)    ScreenName = OSD_Screen_Electric( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 3)    ScreenName = OSD_Screen_MKStatus( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 4)    ScreenName = OSD_Screen_OSD0( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 5)    ScreenName = OSD_Screen_OSD1( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 6)    ScreenName = OSD_Screen_OSD2( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 7)    ScreenName = OSD_Screen_3DLage( ScreenRefresh );
                                else if( Config.OSD_ScreenMode == 8)    ScreenName = OSD_Screen_Statistics( ScreenRefresh );

                #ifdef OSD_DEBUG_SCREEN
                                else if( Config.OSD_ScreenMode == (MAX_OSD_Screens-1) ) ScreenName = OSD_Screen_Debug( ScreenRefresh );
                #endif
                               
            }
                        ScreenRefresh = OSD_SCREEN_REFRESH;
                       
                        if( timer2 == 0 ) timer2 = OSD_REFRESH_TIME;
                       

                        //-----------------------
                        // Key-Handler
                        //-----------------------

                        //if (get_key_press (1 << KEY_PLUS))
                        //{
                        //      print_position ();
                        //}
                         
                        if( get_key_press (1 << KEY_ENTER) )            // info
                        {
                                OSD_Info( Config.OSD_ScreenMode, ScreenName);
                                ScreenRefresh = OSD_SCREEN_REDRAW;
                        }
                         
                        if (get_key_press (1 << KEY_MINUS))             // previous screen
            {
                                if( Config.OSD_ScreenMode == 0 )
                                  Config.OSD_ScreenMode = MAX_OSD_Screens-1;
                                else  
                                  Config.OSD_ScreenMode--;                             
                                ScreenRefresh = OSD_SCREEN_REDRAW;
                        }

                        if (get_key_press (1 << KEY_PLUS))              // next Screen
            {
                                Config.OSD_ScreenMode++;
                                Config.OSD_ScreenMode = ( Config.OSD_ScreenMode >= MAX_OSD_Screens ? 0 : Config.OSD_ScreenMode );
                                ScreenRefresh = OSD_SCREEN_REDRAW;
                        }

                        rxd_buffer_locked = FALSE;


                        //-----------------------
                        // abo_timer
                        //-----------------------
                        if (!abo_timer)
                        {       // renew abo every 3 sec
                                // request OSD Data from NC every 100ms
                                //      RS232_request_mk_data (1, 'o', 100);
                                tmp_dat = 10;
                                SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
                                abo_timer = ABO_TIMEOUT;
                        }
                       
                } //if (rxd_buffer_locked)
               
                if (!timer)
                {
                        OSD_Timeout(flag);
                        flag  = 0;
                        ScreenRefresh = OSD_SCREEN_REDRAW;
                }
               
        } while (!get_key_press (1 << KEY_ESC));
       
        OSD_active = false;
}