/Designs/GPSnavigator/SW/GPS/GPS.c
0,0 → 1,1106
/* mija 2008
demo for LCD NOKIA5110 and MCP9800 and GPS modul
 
CPU ATMEGA644P
fcpu = 1MHz
 
!! define PIN,PORT,DDR for IOpin !!
*/
 
 
//************************************************************************
// defines
 
#define KEY_TIME_DEAD 5 //cca 50ms 8*5
//#define KEY_TIME_START_REPEAT 100 //cca 1s
//#define KEY_TIME_REPEAT 20 //cca 240ms
#define KEY_TIME_FIRST 50
 
#define TEMP_TIME_REPEAT 100
 
#define OFF_TIME 200
 
#define REFRESH_TIME 100
 
#define STATUS_REFRESH_TIME 100
 
#define CLOCK1S 100
#define CLOCK2S 200
#define CLOCK5S 255;
#define CLOCK50MS 5
 
#define DEBUG
 
//************************************************************************
//including
 
#include <avr/io.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <stdio.h>
#include <math.h>
//#include "ascii_table.h"
#include "lcd.h" //define PINs LCD
#include "GPS.h" //define PINs GPS,TL,LED,REF,I2C
#include "nmea_scan.h"
 
//************************************************************************
// pomocne
#define WIDTH_CHAR_SIGNALL 8
prog_uint8_t CHAR_SIGNALL[WIDTH_CHAR_SIGNALL]={127,12,30,51,51,30,12,127};
 
#define WIDTH_CHAR_SIGNALL_D 8
prog_uint8_t CHAR_SIGNALL_D[WIDTH_CHAR_SIGNALL_D]={127,12,30,63,63,30,12,127};
 
#define WIDTH_CHAR_SIGNALL_2D 7
prog_uint8_t CHAR_SIGNALL_2D[WIDTH_CHAR_SIGNALL_2D]={1,2,4,127,4,2,1};
 
#define WIDTH_CHAR_SIGNALL_3D 7
prog_uint8_t CHAR_SIGNALL_3D[WIDTH_CHAR_SIGNALL_3D]={124,68,71,69,125,17,31};
 
#define WIDTH_CHAR_LIGHT 5
prog_uint8_t CHAR_LIGHT[WIDTH_CHAR_LIGHT]={127,65,95,95,127};
 
 
 
//***********************************************************************
// global variables
extern uint8_t video_buf[504];
extern uint8_t *offset_text;
 
uint8_t id_mod;
char scan_buf[MAX_NMEA_LOAD];
POINT_T now,max,min;
DATA_GPS gps;
DATA_GPS *pgps;
 
enum {ID_TIME,ID_LOCATION,ID_COURSE,ID_ALL_POSITION,ID_ALL_SERVICE,ID_SERVICE,ID_TEMP,ID_SATELITES,ID_NORTH,ID_NAV};
 
 
//static int lcd_put(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(lcd_put, NULL,_FDEV_SETUP_WRITE);
//static int lcd_put2(char c, FILE *stream);
static FILE mystdout2 = FDEV_SETUP_STREAM(lcd_put2, NULL,_FDEV_SETUP_WRITE);
 
//************************************************************************
// general cpu init
 
void general_cpu_init(void)
{
//*** IO_PIN ***
TL1_INIT;
TL1_PULLUP;
TL2_INIT;
TL2_PULLUP;
TL3_INIT;
TL3_PULLUP;
 
RX_INIT;
RX_PULLUP;
 
GPS_INIT;
GPS_OFF;
REF_INIT;
REF_OFF;
 
nSCLK_INIT;
nSDIN_INIT;
nDC_INIT;
nCS_INIT;
nRESET_INIT;
 
SCL_INIT;
SDA_FLOAT;
 
LED_INIT;
LED_OFF;
 
//*** EXTERNAL PIN INTERRUPTS
EICRA = _BV(ISC21); //pin INT2 - TL2
EIMSK = _BV(INT2); //pin INT2 - TL2
//PCICR = _BV(PCIE1); //pin change TL1,TL2,TL3
//PCMSK1 = _BV(PCINT10) | _BV(PCINT11) |_BV(PCINT12); //pin change TL1,TL2,TL3
 
//*** TIMER1 *** tik for TL fosc/8 /1024(TCNT1) cca 8ms
TCNT1 = 0;
OCR1A = 1024;
TCCR1A = _BV(WGM11) | _BV(WGM10);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11) ; // TIMER1 fast PWM
TIMSK1 = _BV(TOIE1);
 
//*** TIMER2 *** RTC
ASSR = _BV(AS2);
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
TIMSK2 = _BV(TOIE2);
 
//*** SLEEP ***
SMCR = _BV(SM1) | _BV(SM0) | _BV(SE);
 
//*** WDT ***
//WDTCSR = _BV(WDCE) | _BV(WDE);
//WDTCSR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0);
 
//*** USART0 *** RX PD0, TX PD1, GPS
UBRR0 = 12;
//UCSR0A =
UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
 
//*** USART1 *** RX PD2, TX PD3 PC
UBRR1 = 12;
//UCSR0A =
UCSR1B = _BV(RXCIE1) | _BV(RXEN0) | _BV(TXEN1);
 
//*** ADC ***
ADMUX = _BV(REFS1) | _BV(MUX0);
ADCSRA = _BV(ADPS1) | _BV(ADPS0);
 
}
 
//************************************************************************
// interrupts + RTC / clock 8s ... TIMER2 /
 
volatile uint8_t RTC_flag;
volatile uint8_t sRTC,mRTC,hRTC,dRTC,mdRTC,yRTC;
 
uint8_t modulo(uint8_t h,uint8_t m) //pomocna fce pro modulo x
{
if (h<m) return (h);
return(h-m);
}
 
void set_date(void) //citac datumu
{
dRTC++;
switch (mdRTC)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: if(dRTC>=32) {dRTC=1;mdRTC++;if(mdRTC==13) {mdRTC =1;yRTC=modulo(yRTC++,100);}} break;
case 4:
case 6:
case 9:
case 11: if(dRTC>=31) {dRTC=1;mdRTC++;} break;
case 2: if (dRTC >= 30) {dRTC=1;mdRTC++;break;}
if (dRTC ==29) {if (!(yRTC & 0x03)) break;dRTC=1;mdRTC++;}
}
}
 
 
volatile uint8_t timer1_ovf;
 
ISR(TIMER1_OVF_vect)
{
timer1_ovf ++;
}
 
 
ISR(TIMER2_OVF_vect)
{
sRTC += 8;
if (sRTC >= 60)
{
sRTC=modulo(sRTC,60); //1min
if (++mRTC>=60)
{
mRTC=0; //1hod
if (++hRTC>=24)
{
hRTC=0;
set_date(); //1den
}
}
}
}
 
char rx_buf[MAX_RX_BUF];
volatile uint8_t rx_shift;
 
ISR(USART0_RX_vect)
{
if (++rx_shift >= MAX_RX_BUF) rx_shift =0;
rx_buf[rx_shift]=UDR0;
UDR1 = UDR0;
}
 
ISR(USART1_RX_vect)
{
UDR0 = UDR1;
}
 
EMPTY_INTERRUPT(INT0_vect)
EMPTY_INTERRUPT(INT2_vect)
EMPTY_INTERRUPT(PCINT1_vect)
EMPTY_INTERRUPT(WDT_vect)
 
//************************************************************************
// delay_ms functions /define fcpu /
 
void delay_ms(uint16_t time)
{
while(time--) _delay_ms(1);
}
//************************************************************************
// static navigation
 
void gps_put(char c)
{
while ( !( UCSR0A & _BV(UDRE0)) );
UDR0 = c;
}
 
void set_static_navigation(uint8_t static_nav)
{
char chsum[3];
char SWITCH_TO_SIRF[]="$PSRF100,0,4800,8,1,0" ;
uint8_t SET_STATIC_NAV[10]={0xa0,0xA2,0x00,0x02,0x8f,0x00,0x00,0x8f,0xB0,0xB3};
uint8_t SWITCH_TO_NMEA[10]={0xa0,0xA2,0x00,0x02,0x87,0x02,0x00,0x89,0xB0,0xB3};
uint8_t chksum;
uint8_t i;
 
chksum=0;
for (i=0;i<21;i++)
{
gps_put(SWITCH_TO_SIRF[i]);
chksum +=SWITCH_TO_SIRF[i];
}
gps_put('*');
sprintf(chsum,"%02X",chksum);
gps_put(chsum[0]);
gps_put(chsum[1]);
gps_put('\r');
gps_put('\n');
if (static_nav)
{
}
else
{
for (i=0;i<10;i++) gps_put(SET_STATIC_NAV[i]);
}
//for (i=0;i<10;i++) gps_put(SWITCH_TO_NMEA[i]);
}
 
//************************************************************************
// key + timer1_ovf
 
 
volatile uint8_t key_press;
volatile uint8_t key_flag;
volatile uint8_t timer_key;
volatile uint8_t timer_temp;
volatile uint8_t timer_off;
volatile uint8_t timer_refresh;
volatile uint8_t timer_status;
 
void timer1_tik(void)
{
uint8_t key_temp;
timer1_ovf--;
{
if (timer_status) timer_status--;
if (timer_refresh) timer_refresh--;
if (timer_off) timer_off--;
if (timer_temp) timer_temp--;
if (timer_key) timer_key--;
else
{
if (!TL1_INPUT) key_temp = _BV(KEY1); else key_temp = 0;
if (!TL2_INPUT) key_temp |= _BV(KEY2); else key_temp &= ~(_BV(KEY2));
if (!TL3_INPUT) key_temp |= _BV(KEY3); else key_temp &= ~(_BV(KEY3));
if (key_temp != key_press)
{
timer_key = KEY_TIME_DEAD;
key_press = key_temp;
if (!key_flag) key_flag = key_press;
timer_off= OFF_TIME;
}
}
}
}
 
uint8_t key_read(void)
{
uint8_t key_send;
 
key_send = key_flag;
key_flag = 0;
return key_send;
}
 
//************************************************************************
// SW I2C /define SDA, SCL; tested for fosc 1Mhz/
 
void I2C_start(void)
{
SDA_OUT;
SDA_L;
SCL_L;
}
 
void I2C_stop(void)
{
SCL_H;
SDA_OUT;
SDA_H;
SDA_FLOAT;
}
 
void I2C_write(uint8_t data)
{
uint8_t a;
SDA_OUT;
for(a=0;a<8;a++)
{
SCL_L;
if (data & 0x80) SDA_H;
else SDA_L;
SCL_H;
data <<= 1;
}
SCL_L;
SDA_FLOAT;
SCL_H;
SCL_L;
}
 
uint8_t I2C_read(uint8_t ack)
{
uint8_t a;
uint8_t data;
 
SDA_IN;
data=0;
for(a=0;a<8;a++)
{
SCL_H;
if (SDA_INPUT) data |=1;
SCL_L;
if (a != 7)data <<= 1;
}
if (ack) {SDA_OUT;SDA_L;}
else SDA_FLOAT;
SCL_H;
SCL_L;
SDA_FLOAT;
return data;
}
 
//************************************************************************
// temperature sensor MCP9800 of MICROCHIP
 
void start_MCP9800(void)
{
I2C_start();
I2C_write(0x90);
I2C_write(0x1); // configuration pointer MCP9800
//I2C_write(0xE1); // 12bit + only 1 convert and then sleep
I2C_write(0x81); // 9bit + only 1 convert and then sleep
I2C_stop();
I2C_start();
I2C_write(0x90);
I2C_write(0x0); // temperature pointer
I2C_stop();
}
 
uint16_t read_temp(void)
{
uint16_t temp;
 
I2C_start();
I2C_write(0x91);
temp = I2C_read(1) << 8;
temp |= I2C_read(0);
I2C_stop();
return temp;
}
 
//************************************************************************
// templota
 
void print_temp(int16_t teplota)
{
printf("%d.%01dC",((teplota>>8) & 0x807F) | (teplota & 0x8000),5*((teplota>>7)& 0x1));
}
 
void print_time(TIME_T time)
{
uint8_t temp;
temp = time.hour/10;
if (temp == 0) lcd_put(' ',0);
else lcd_put(temp + 0x30,0);
lcd_put(time.hour%10 + 0x30,0);
//put_lcd(':');
*(offset_text++) = 0x36;
offset_text++;
lcd_put(time.min/10 + 0x30,0);
lcd_put(time.min%10 + 0x30,0);
//put_lcd(':');
//put_lcd(sRTC/10 + 0x30);
//put_lcd(sRTC%10 + 0x30);
}
 
void print_date(DATE_T date)
{
uint8_t temp;
temp = date.day/10;
if (temp == 0) lcd_put(' ',0);
else lcd_put(temp + 0x30,0);
lcd_put(date.day%10 + 0x30,0);
//put_lcd('/');
*(offset_text++) = 0x60;
offset_text++;
temp = date.mon/10;
if (temp != 0) lcd_put(temp + 0x30,0);
lcd_put(date.mon%10 + 0x30,0);
if (temp == 0)
{
*(offset_text++) = 0x60;
offset_text++;
}
//put_lcd('/');
//put_lcd(yRTC/10 + 0x30);
//put_lcd(yRTC%10 + 0x30);
}
 
TIME_T actual_time(void)
{
TIME_T time;
 
time.sec=sRTC;
time.min=mRTC;
time.hour=hRTC;
return time;
}
 
DATE_T actual_date(void)
{
DATE_T date;
 
date.day=dRTC;
date.mon=mdRTC;
date.year=yRTC;
return date;
}
 
//*********************************************************************
//status
 
void status(void)
{
uint8_t a,b;
uint8_t *ptr;
start_MCP9800();
REF_ON;
ADC_ON;
ADCSRA |= _BV(ADSC);
while (!(ADCSRA & _BV(ADIF)));
gotoxy(1,1);
printf("%0.1fV %2d",1024.0*25/ADC/10,read_temp()>>8);
offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT - 2*CHAR_WIDTH - WIDTH_CHAR_SIGNALL_3D - WIDTH_CHAR_SIGNALL - 2;
if (gps.fix_position)
{
switch (gps.fix_position)
{
case 1: ptr= CHAR_SIGNALL;b=WIDTH_CHAR_SIGNALL;break;
case 2: ptr= CHAR_SIGNALL_D;b=WIDTH_CHAR_SIGNALL_D;break;
case 0:
default:ptr= CHAR_SIGNALL;b=0;
}
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;offset_text++;
if (gps.mode2 == '3')
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
offset_text++;
}
offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT-2*CHAR_WIDTH;
printf("%d",gps.satelites_used);
if (LED_INPUT)
{
ptr= CHAR_LIGHT;b=WIDTH_CHAR_LIGHT;
offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT;
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
}
}
 
//************************************************************************
// mod
 
void displ_time(void)
{
GPS_ON;
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(1,2);
printf("time & date");
gotoxy(1,3);
fprintf(&mystdout2," %2d:%02d:%02d",gps.hour+2,gps.minute,gps.second);
gotoxy(1,5);
fprintf(&mystdout2," %2d.%02d.20%02d",gps.day,gps.month,gps.year);
lcd_refresh();
}
}
 
void displ_location(void)
{
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(1,2);
printf("location");
gotoxy(1,3);
//gps.latitude = 14.5;
fprintf(&mystdout2,"%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
gotoxy(1,5);
//gps.longitude = 48.25;
fprintf(&mystdout2,"%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
lcd_refresh();
}
}
 
void displ_speed(void)
{
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(1,2);
printf("speed");
gotoxy(1,4);
fprintf(&mystdout2," %3.1f km/h",gps.speed);
lcd_refresh();
}
}
 
void displ_course(void)
{
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
//gotoxy(1,2);
//printf("course");
gotoxy(1,3);
fprintf(&mystdout2," %3.1f km/h",gps.speed);
gotoxy(6,5);
fprintf(&mystdout2,"%3.0f",gps.course);
lcd_refresh();
}
}
 
void displ_satelites(void)
{
#define WIDTH_REC 60
 
uint8_t a,x,y,b;
static uint8_t d = 0;
static uint8_t c = 0;
double elevace,azimut;
 
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
if (c--) return;
c=3;
buffer_clr();
//status();
#ifdef DEBUG
if(gps.gsv_satelites_view > 12)
{
printf("error view satelites");
lcd_refresh();
c=20;
return;
}
#endif
if (++d >= gps.gsv_satelites_view) d = 0;
gotoxy(12,1);
printf("%d",gps.gsv_satelites_view);
gotoxy(12,2);
printf("%d",gps.satelit_detail[d].id);
gotoxy(12,3);
printf("%d",gps.satelit_detail[d].azimut);
gotoxy(12,4);
printf("%d",gps.satelit_detail[d].elevation);
gotoxy(12,5);
printf("%d",gps.satelit_detail[d].SNR);
gotoxy(12,6);
 
for (a=0;a<gps.gsv_satelites_view;a++)
{
azimut = (double)gps.satelit_detail[a].azimut;
elevace = (double)gps.satelit_detail[a].elevation;
x=(uint8_t)((WIDTH_REC-4)/2.0/90.0*(90.0-elevace)*sin(M_PI/180*azimut) + WIDTH_REC/2.0);
y=(uint8_t)((LCD_HEIGHT-4)/2.0/90.0*(90.0-elevace)*cos(M_PI/180*azimut) + LCD_HEIGHT/2.0);
if (gps.satelit_detail[a].SNR)
{
lcd_plot(x-1,y);lcd_plot(x+1,y);lcd_plot(x,y-1);lcd_plot(x,y+1);
for (b=0;b<gps.satelites_used;b++)
if (gps.satelit_detail[a].id == gps.satelite_id[b])
lcd_plot(x,y);
}
else lcd_plot(x,y);
if (d == a)
{
lcd_line(x-2,y-2,x-2,y+2);
lcd_line(x+2,y+2,x+2,y-2);
lcd_line(x+2,y+2,x-2,y+2);
lcd_line(x-2,y-2,x+2,y-2);
}
}
 
lcd_line(0,0,WIDTH_REC,0);
lcd_line(0,LCD_HEIGHT-1,WIDTH_REC,LCD_HEIGHT-1);
lcd_line(0,0,0,LCD_HEIGHT-1);
lcd_line(WIDTH_REC,0,WIDTH_REC,LCD_HEIGHT-1);
 
lcd_refresh();
}
}
 
void displ_all_position()
{
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(1,2);
printf("%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
gotoxy(1,3);
printf("%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
gotoxy(1,4);
printf("alt%4.0fm V%2.1f",gps.altitude,gps.VDOP);
gotoxy(1,5);
printf("geo%4.0fm H%2.1f",gps.geoid,gps.HDOP);
gotoxy(1,6);
printf("%3.0fkm/h %3.0f",gps.speed,gps.course);
lcd_refresh();
}
}
 
void displ_nav(void)
{
uint8_t a;
double lon,lat,temp;
double course;
uint8_t x,y,xl,yl,xp,yp;
 
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
const float gc_lat=48*60+57.7647,gc_lon=14*60+28.0836; // DOMA
 
lon=(gc_lon-gps.longitude*60)*1214;
lat=(gc_lat-gps.latitude*60)*1854;
temp = sqrt((lon*lon) + (lat*lat));
gotoxy(9,3);
if (temp < 10000)
{
if (temp<1000) fprintf(&mystdout2,"%.1f ",temp);
else
{
fprintf(&mystdout2,"%.3f ",temp/1000);
gotoxy(12,5);
printf("k");
}
gotoxy(13,5);
printf("m");
}
else
{
temp=temp/1000;
if (temp < 1000)
{
if (temp < 100)
{
fprintf(&mystdout2,"%.2f ",temp);
}
else
{
fprintf(&mystdout2,"%.1f ",temp);
}
}
else fprintf(&mystdout2,"%5.0f ",temp);
gotoxy(12,5);
printf("km");
}
 
if (lat==0) lat=0.001;
lon=M_PI/2.0-(atan2(lat,lon));
if (lon<0) lon+=2*M_PI;
if (lon>(2*M_PI)) lon-=2*M_PI;
//printf(lcd_putc,"BE%2.0g*",lon);
lat=M_PI/180*gps.course;
lon=lon-lat;
if (lon<0) lon+=2*M_PI;
if (lon>2*M_PI) lon-=2*M_PI;
//printf(lcd_putc,"HE%2.0g*AZ%2.0g* ",lon,lat);
#define WIDTH_REC_NAV 43
#define LCD_HEIGHT_NAV 35
course = lon;
x=(uint8_t)(WIDTH_REC_NAV/2.0*sin(course) +WIDTH_REC_NAV/2);
y=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos(course) +(LCD_HEIGHT_NAV)/2);
 
xl=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course-2.62))+WIDTH_REC_NAV/2 );
yl=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course-2.62))+(LCD_HEIGHT_NAV)/2 );
 
xp=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course+2.62))+WIDTH_REC_NAV/2 );
yp=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course+2.62)) +(LCD_HEIGHT_NAV)/2);
 
//xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
//ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
 
lcd_line( x,y,xl,yl);
lcd_line( x,y,xp,yp);
//lcd_line( xp,yp,xl,yl);
lcd_line(xl,yl,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
lcd_line(xp,yp,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
//lcd_line(xl,yl,xs,ys);
//lcd_line(xp,yp,xs,ys);
lcd_refresh();
}
}
 
void displ_service(char *buf)
{
uint8_t a;
 
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
for (a = 0; a<80; a++) putchar(*(buf++));
lcd_refresh();
}
}
 
void displ_north(void)
{
//uint8_t a;
uint8_t x,y;
uint8_t xp,yp;
uint8_t xl,yl;
//uint8_t xs,ys;
double course;
 
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(9,3);
fprintf(&mystdout2,"%3.1f",gps.speed);
gotoxy(10,5);
printf("km/h");
#define WIDTH_REC_NORTH 43
#define LCD_HEIGHT_NORTH 35
 
course = 360-gps.course;
x=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*course) +WIDTH_REC_NORTH/2);
y=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*course) +(LCD_HEIGHT_NORTH)/2);
 
xl=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course-150.0))+WIDTH_REC_NORTH/2 );
yl=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course-150.0))+(LCD_HEIGHT_NORTH)/2 );
 
xp=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course+150.0))+WIDTH_REC_NORTH/2 );
yp=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course+150.0)) +(LCD_HEIGHT_NORTH)/2);
 
//xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
//ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
 
lcd_line( x,y,xl,yl);
lcd_line( x,y,xp,yp);
//lcd_line( xp,yp,xl,yl);
lcd_line(xl,yl,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
lcd_line(xp,yp,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
//lcd_line(xl,yl,xs,ys);
//lcd_line(xp,yp,xs,ys);
lcd_refresh();
}
}
 
void displ_all_service(void)
{
uint8_t a;
 
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
 
gotoxy(1,2);
printf("d=%d %ds",gps.diff_id,gps.age_diff_corr);
gotoxy(1,3);
printf("%c st=%cD ",gps.mode1,gps.mode2);
switch (gps.fix_position)
{
case 0: printf("nofix");break;
case 1: printf("SPSfix");break;
case 2: printf(" Dfix");break;
default: printf("nopref");
}
gotoxy(1,4);
printf("GSV %d %d %d",gps.gsv_num_msg,gps.gsv_msg,gps.gsv_satelites_view);
gotoxy(1,5);
for(a=0;a<6;a++)
{
printf("%2d",gps.satelite_id[a]);
offset_text+=2;
}
gotoxy(1,6);
for(a=6;a<12;a++)
{
printf("%2d",gps.satelite_id[a]);
if (a != 11) offset_text+=2;
}
lcd_refresh();
}
}
 
void displ_temp()
{
//GPS_OFF;
//ADC_OFF;
//REF_OFF;
 
if(!timer_temp)
{
timer_temp = TEMP_TIME_REPEAT;
now.temperature=read_temp();
now.time=actual_time();
now.date=actual_date();
buffer_clr();
gotoxy(1,1);
stdout = &mystdout2;
print_temp(now.temperature);
stdout = &mystdout;
gotoxy(11,1);
offset_text-= 2;
print_time(now.time);
gotoxy(11,2);
offset_text-= 2;
print_date(now.date);
gotoxy(1,4);
if (now.temperature > max.temperature) max=now;
print_temp(max.temperature);
gotoxy(11,4);
offset_text-= 2;
print_date(max.date);
gotoxy(6,3);
printf("max");
gotoxy(11,3);
offset_text-= 2;
print_time(max.time);
gotoxy(1,6);
if (now.temperature < min.temperature) min=now;
print_temp(min.temperature);
gotoxy(11,6);
offset_text-= 2;
print_date(min.date);
gotoxy(6,5);
printf("min");
gotoxy(11,5);
offset_text-= 2;
print_time(min.time);
lcd_refresh();
start_MCP9800();
}
}
 
void displ_start(void)
{
buffer_clr();
gotoxy(6,3);
fprintf(&mystdout2,"GPS");
lcd_refresh();
delay_ms(1000);
id_mod = ID_TEMP;
 
}
 
void all_off(void)
{
if (!timer_refresh)
{
buffer_clr();
gotoxy(6,3);
fprintf(&mystdout2,"OFF");
lcd_refresh();
timer_refresh = CLOCK1S;
return;
}
if (timer_refresh < CLOCK50MS)
{
timer_refresh = 0;
LED_OFF;
GPS_OFF;
REF_OFF;
N5110_send_command(POWER_DOWN);
while (TL2_INPUT)
sleep_cpu();
 
LCD_N5110_INIT();
id_mod = ID_START;
}
}
 
//************************************************************************
// spol key
 
uint8_t key(uint8_t mod)
{
if(key_press)
{
if (!timer_off)
{
if (key_read() == _BV(KEY2))
{
timer_refresh = 0;
timer_key = CLOCK2S;
key_read();
return ID_OFF;
}
}
}
else
{
if (key_flag == _BV(KEY1))
{
timer_key = KEY_TIME_FIRST;
key_read();
timer_refresh = 0;
++mod;
}
if (key_flag == _BV(KEY2))
{
if (LED_INPUT) LED_OFF;
else LED_ON;
timer_key = KEY_TIME_FIRST;
key_read();
}
if (key_flag == _BV(KEY3))
{
max.temperature=0x8000;
min.temperature=0x7FFF;
if (GPS_INPUT && (gps.status == 'A'))
{
sRTC=gps.second;
mRTC=gps.minute;
hRTC=gps.hour+2;
 
dRTC=gps.day;
mdRTC=gps.month;
yRTC=gps.year;
}
 
timer_key = KEY_TIME_FIRST;
key_read();
}
}
return mod;
}
 
//************************************************************************
// main
 
int main(void)
{
uint8_t temp;
 
pgps = &gps;
max.temperature=0x8000;
min.temperature=0x7FFF;
id_mod = ID_NORTH;
general_cpu_init();
//GPS_ON;
LCD_N5110_INIT();
 
//set_static_navigation(0);
sRTC=0;
mRTC=15;
hRTC=17;
 
dRTC=25;
mdRTC=7;
yRTC=8;
stdout = &mystdout;
sei();
for (;;)
{
switch(id_mod)
{
case ID_TIME: displ_time(); break;
case ID_LOCATION: id_mod++;break;displ_location();break;
//case ID_SPEED: displ_speed(); break;
case ID_SATELITES: displ_satelites();break;
case ID_COURSE: id_mod++;break;displ_course(); break;
case ID_ALL_POSITION:displ_all_position(); break;
case ID_ALL_SERVICE:displ_all_service();break;
case ID_SERVICE: id_mod++; break;displ_service(scan_buf);break;
case ID_TEMP: displ_temp(); break;
case ID_OFF: all_off(); break;
case ID_START: displ_start(); break;
case ID_NAV: displ_nav();break;
case ID_NORTH: displ_north();break;
default : id_mod = 0;
}
 
id_mod = key(id_mod);
while(timer1_ovf)timer1_tik();
 
switch (load_nmea(rx_shift,rx_buf,scan_buf))
{
case RETURN_GGA: nmea_gga(scan_buf,pgps);break;
case RETURN_GSA: nmea_gsa(scan_buf,pgps);break;
case RETURN_GSV: nmea_gsv(scan_buf,pgps);break;
case RETURN_RMC: nmea_rmc(scan_buf,pgps);break;
case RETURN_VTG: nmea_vtg(scan_buf,pgps);break;
}
}
return 0;
}