Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************
* Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de *
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net *
* Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
* Copyright (C) 2011 Harald Bongartz *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* *
* Credits to: *
* Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN *
* http://www.mikrokopter.de *
* Gregor "killagreg" Stobrawa for his version of the MK code *
* Thomas Kaiser "thkais" for the original project. See *
* http://www.ft-fanpage.de/mikrokopter/ *
* http://forum.mikrokopter.de/topic-4061-1.html *
* Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
* http://www.mylifesucks.de/oss/c-osd/ *
* Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
*****************************************************************************/
//############################################################################
//# HISTORY mkgpsinfo.c
//#
//# 04.06.2014 OG
//# - chg: MK_Gps_Info() umgestellt auf PKT_Message_Datenverlust()
//#
//# 14.05.2014 OG
//# - chg: Code-Redesign; neues Screen-Layout; Code-Reduzierung;
//# Anpassungen an neue PKT-Funktionen
//# - chg: umbenannt von 'gps.c' zu 'mkgpsinfo.c'
//# - chg: gps() ist jetzt MK_Gps_Info()
//# - add: Source-Historie ergaenzt
//############################################################################
#include <avr/io.h>
#include <inttypes.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <stdbool.h>
#include <util/delay.h>
#include "../main.h"
#include "../lcd/lcd.h"
#include "../timer/timer.h"
#include "../uart/usart.h"
#include "../lipo/lipo.h"
#include "../pkt/pkt.h"
#include "../mk/mkbase.h"
#include "../messages.h"
//##############################################################
//##############################################################
//#define DEBUG_MKGPS // erweiterte Anzeigen zum debuggen
#define GPSTIMEOUT 300 // 3 Sekunden
#define UBX_BUFFER_SIZE 100 // 100 Byte Buffer fuer GPS-Daten
uint8_t ck_a = 0;
uint8_t ck_b = 0;
union long_union
{
uint32_t dword;
uint8_t byte[4];
} longUnion;
union int_union
{
uint16_t dword;
uint8_t byte[2];
} intUnion;
//##############################################################
//##############################################################
//--------------------------------------------------------------
//--------------------------------------------------------------
uint32_t join_4_bytes(uint8_t Buffer[])
{
longUnion.byte[0] = *Buffer;
longUnion.byte[1] = *(Buffer+1);
longUnion.byte[2] = *(Buffer+2);
longUnion.byte[3] = *(Buffer+3);
return (longUnion.dword);
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void checksum(uint8_t data)
{
ck_a += data;
ck_b += ck_a;
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void MK_Gps_Info( void )
{
uint8_t UBX_buffer[UBX_BUFFER_SIZE];
uint8_t UBX_payload_counter = 0;
uint8_t UBX_class = 0;
uint8_t UBX_id = 0;
uint8_t UBX_ck_a = 0;
uint8_t data = 0;
uint8_t length = 0;
uint8_t state = 0;
uint8_t redraw = true;
uint8_t refresh = false;
uint8_t yoffs = 1; // Anzeige-Verschiebung: der obere Bereich
uint8_t yoffs2 = 4; // Anzeige-Verschiebung: GPS-Koordinaten
int16_t v_16; // tmp-Variable
int32_t v_32; // tmp-Variable
#ifdef DEBUG_MKGPS
uint8_t maxlen = 0;
#endif
MK_SwitchToNC(); // Anmerkung OG: warum auch immer es besser ist erst auf die NC
MK_SwitchToGPS(); // umzuschalten... es laeuft so scheinbar zuverlaessiger
MK_SwitchToGPS();
timer_mk_timeout = GPSTIMEOUT;
do
{
//------------------------
// REDRAW
//------------------------
if( redraw )
{
ShowTitle_P( PSTR("MK GPS Info"), true);
lcdx_printp_at( 0,1, PSTR("Fix:"), MNORMAL, 0,yoffs );
lcdx_printp_at( 0,2, PSTR("Sat:"), MNORMAL, 0,yoffs );
lcdx_printp_at( 0,3, PSTR("Alt:"), MNORMAL, 0,yoffs );
lcdx_printp_at( 9,1, PSTR("PDOP:"), MNORMAL, 3,yoffs );
lcdx_printp_at( 9,2, PSTR("Accu:"), MNORMAL, 3,yoffs );
lcdx_printp_at( 9,3, PSTR("Sped:"), MNORMAL, 3,yoffs );
lcd_frect( 0, (4*7)+4+yoffs2, 127, 7, 1); // GPS: Rect: Invers
lcdx_printp_at(1, 3, strGet(START_LASTPOS1), MINVERS, 0,8+yoffs2); // GPS: "Breitengr Längengr"
lcd_rect( 0, (3*8)+7+yoffs2, 127, (2*8)+4, 1); // GPS: Rahmen
lcdx_printp_at(12,7, strGet(ENDE), MNORMAL, 0,1); // KEYLINE
redraw = false;
}
//------------------------
// REFRESH
//------------------------
if( refresh )
{
if((UBX_class == 1) && (UBX_id == 6)) // GPS: SVINFO
{
//--------------
// GPS Status
//--------------
switch( UBX_buffer[10] )
{
case 4:
case 3: lcdx_printp_at( 5, 1, PSTR("3D"), MNORMAL, 1,yoffs); break;
case 2: lcdx_printp_at( 5, 1, PSTR("2D"), MNORMAL, 1,yoffs); break;
default: lcdx_printp_at( 5, 1, PSTR("no"), MNORMAL, 1,yoffs);
}
// GPS ok => ein Haken wird angezeigt
if( (UBX_buffer[11] & 1) == 1 ) lcdx_putc( 7, 1, SYMBOL_CHECK, MNORMAL, 3,yoffs );
else lcdx_putc( 7, 1, ' ', MNORMAL, 3,yoffs );
//---
// Anzeige von "D" - evtl. DGPS (Differential GPS)?
// aktuell nicht mehr unterstuetzt da kein Platz auf dem Screen
//---
//if( (UBX_buffer[11] & 3) == 3 ) lcd_printp_at (10,0, PSTR("D"), 0);
//else lcd_printp_at (10,0, PSTR(" "), 0);
//--------------
// Sat
//--------------
lcdx_printf_at_P( 5, 2, MNORMAL, 0,yoffs, PSTR("%2u"), UBX_buffer[47] );
//--------------
// PDOP
//--------------
v_16 = UBX_buffer[44]+UBX_buffer[45]*255;
lcdx_printf_at_P( 15, 1, MNORMAL, 0,yoffs, PSTR("%2.2d"), v_16 );
//--------------
// Accuracy
//--------------
v_32 = (int32_t)join_4_bytes(&UBX_buffer[24]);
lcdx_printf_at_P( 15, 2, MNORMAL, 0,yoffs, PSTR("%2.2ldm"), v_32 );
}
if((UBX_class == 1) && (UBX_id == 18)) // GPS: VELNED
{
//--------------
// Speed
//--------------
v_16 = (int16_t)((join_4_bytes(&UBX_buffer[20])*60*60)/100000);
lcdx_printf_at_P( 15, 3, MNORMAL, 0,yoffs, PSTR("%3dkmH"), v_16 );
//uint16_t speed = (uint16_t)((join_4_bytes(&UBX_buffer[20])*60*60)/100000);
//write_ndigit_number_u (11, 4, speed, 3, 0,0);
//lcd_printp_at (15,4, PSTR("km/h"), 0);
}
if((UBX_class == 1) && (UBX_id == 2)) // GPS: POSLLH
{
//--------------
// Altitude
//--------------
v_16 = (int16_t)(join_4_bytes(&UBX_buffer[16])/1000);
//v_16 = v_16 + 3000;
lcdx_printf_at_P( 4, 3, MNORMAL, 1,yoffs, PSTR("%4d"), v_16 );
//uint16_t height = (uint16_t)(join_4_bytes(&UBX_buffer[16])/1000);
//write_ndigit_number_u (11, 7, height, 4, 0,0);
//lcd_printp_at(16,7, PSTR("m"), 0);
//--------------
// Breitengrad - Lat (51.)
//--------------
v_32 = join_4_bytes(&UBX_buffer[8]);
writex_gpspos( 1, 4, v_32 , MNORMAL, 0,10+yoffs2); // Anzeige: Breitengrad
//write_ndigit_number_u ( 0, 7, (uint16_t)(lat/10000000), 2, 0,0);
//lcd_printp_at ( 2, 7, PSTR("."), 0);
//write_ndigit_number_u ( 3, 7, (uint16_t)((lat/1000) % 10000), 4, 1,0);
//write_ndigit_number_u ( 7, 7, (uint16_t)((lat/10) % 100), 2, 1,0);
//--------------
// Laengengrad - Long (7.)
//--------------
v_32 = join_4_bytes(&UBX_buffer[4]);
writex_gpspos( 12, 4, v_32, MNORMAL, -1,10+yoffs2); // Anzeige: Laengengrad
//write_ndigit_number_u (10, 7, (uint16_t)(lon/10000000), 2, 0,0);
//lcd_printp_at (12, 7, PSTR("."), 0);
//write_ndigit_number_u (13, 7, (uint16_t)((lon/1000) % 10000), 4, 1,0);
//write_ndigit_number_u (17, 7, (uint16_t)((lon/10) % 100), 2, 1,0);
}
//------------------------
// PKT-LiPo Anzeige
//------------------------
show_Lipo();
refresh = false;
} // end: if( refresh )
//--------------------------
// PROCESS DATA
//--------------------------
if( uart_getc_nb( &data ) )
{
switch( state )
{
case 0: if( data == 0xB5 ) // GPS: init 1
{
UBX_payload_counter = 0;
UBX_id = 0;
UBX_class = 0;
ck_a = 0;
ck_b = 0;
state++;
}
break;
case 1: if( data == 0x62 ) // GPS: init 2
state++;
else
state = 0;
break;
case 2: if( data != 1 ) // GPS: class
state = 0;
else
{
checksum(data);
UBX_class = data;
state++;
}
break;
case 3: if( (data != 48) // GPS: id
&&(data != 6 )
&&(data != 18)
&&(data != 2 ))
{
state = 0;
}
else
{
UBX_id = data;
checksum(data);
state++;
}
break;
case 4: if( data >= UBX_BUFFER_SIZE ) // GPS: length lo
state = 0;
else
{
checksum(data);
length = data;
state++;
}
#ifdef DEBUG_MKGPS
// DEBUG - Anzeige der Paketgroesse
if( data > maxlen )
{
// groesstes gemessenes Paket lag bei 181
// ob man das Paket braucht ist eine andere Frage
maxlen = data;
lcdx_printf_at_P( 1, 7, MNORMAL, 0,1, PSTR("%3u"), maxlen );
set_beep( 25, 0xffff, BeepNormal ); // kurzer Beep
}
#endif
break;
case 5: if( data != 0 ) // GPS: length hi
state = 0;
else
{
checksum(data);
state++;
}
break;
case 6: UBX_buffer[UBX_payload_counter] = data; // GPS: data
checksum(data);
UBX_payload_counter++;
length--;
if( length == 0 )
{
state++;
};
break;
case 7: state++; // GPS: check lo
UBX_ck_a = data;
break;
case 8: state = 0; // GPS: check hi
if((UBX_ck_a == ck_a) && (data == ck_b))
{
timer_mk_timeout = GPSTIMEOUT;
refresh = true;
}
} // end: switch( state )
} // end: if( uart_getc_nb(&data) )
//------------------------------------------
// Pruefe PKT-Update oder andere PKT-Aktion
//------------------------------------------
/*
// funktioniert hier nicht - warum auch immer
if( PKT_CtrlHook() ) // Update vom Updatetool angefordert?
{
redraw = true;
}
*/
} while( !get_key_press(1 << KEY_ESC) && timer_mk_timeout );
//--------------------------
// in den Timeout gelaufen?
//--------------------------
if( !timer_mk_timeout )
{
//PKT_Message_Datenverlust( timeout, beep)
PKT_Message_Datenverlust( 500, true); // 500 = 5 Sekunden
}
clear_key_all();
SwitchToNC();
}