/*****************************************************************************
* 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;
}