/* mija 2008
demo for LCD NOKIA5110 and MCP9800 and GPS modul
CPU ATMEGA644P
fcpu = 7372800
!! define PIN,PORT,DDR for IOpin !!
*/
//************************************************************************
// defines
#define POINTNAME " DOMOV"
#define MY_LAT 48*60+57.7647
#define MY_LON 14*60+28.0836
/*
// 50°7'38.768"N, 13°32'43.132"E
#define POINTNAME " ORACOV"
#define MY_LAT 50*60+7.64613
#define MY_LON 13*60+32.7189
*/
/*
// 50°7'38.768"N, 13°32'43.132"E
#define POINTNAME " ZAMEK"
#define MY_LAT 50*60+6.191
#define MY_LON 13*60+32.118
*/
#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 TIME_KEY_LONG 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};
#define BOOT() (((void(*)(void))(char *)0x7C00)())
#define RESET() (((void(*)(void))(char *)0x0000)())
//***********************************************************************
// 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 FILE mystdout = FDEV_SETUP_STREAM(lcd_put, NULL,_FDEV_SETUP_WRITE); // in lcd.h
static FILE mystdout2 = FDEV_SETUP_STREAM(lcd_put2, NULL,_FDEV_SETUP_WRITE); // in lcd.h
//************************************************************************
// prototypes
//(*bootloader)(void) = 0x7C00;
void delay_ms(uint16_t time);
void null_variables(void);
//************************************************************************
// general cpu init
void general_cpu_init(void)
{
//*** IO_PIN ***
TL1_INIT;
TL1_PULLUP;
TL2_INIT;
TL2_PULLUP;
TL3_INIT;
TL3_PULLUP;
USB_INIT;
//USB_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
//*** PIN CHANGE INTERRUPTS PCINT29
PCICR = _BV(PCIE1);
PCMSK1 = _BV(PCINT10) | _BV(PCINT11) |_BV(PCINT12); //pin change TL1,TL2,TL3
PCICR |= _BV(PCIE3);
PCMSK3 = _BV(PCINT29); // pin USB
//*** TIMER1 *** tik for TL fosc/64 /1024(TCNT1) cca 8ms
TCNT1 = 0;
OCR1A = 1024;
TCCR1A = _BV(WGM11) | _BV(WGM10);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11) | _BV(CS10) ; // 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 = 95;
//UCSR0A =
UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
//*** USART1 *** RX PD2, TX PD3 PC
DDRD |= _BV(PD3);
PORTD &= (~(_BV(PD3)));
#ifndef DEBUG
UBRR1 = 95;
#else
UBRR1 = 3;
#endif
//UCSR0A =
UCSR1B = _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1);
//*** ADC ***
ADMUX = _BV(REFS1) | _BV(MUX0);
ADCSRA = _BV(ADPS1) | _BV(ADPS2);
}
//************************************************************************
// 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;
}
uint8_t first_char_usart1 = 0;
ISR(USART1_RX_vect)
{
#ifndef DEBUG
UDR0 = UDR1;
#else
if (TL1_INPUT && TL3_INPUT) BOOT();
//bootloader();
#endif
}
ISR(PCINT1_vect)
{
if ((!TL3_INPUT) && (!TL1_INPUT)) RESET();
}
ISR(PCINT3_vect)
{
if (USB_PIN) USART_PC_ON;
else USART_PC_OFF;
if (!TL2_INPUT && USB_INPUT)
{
cli();
buffer_clr();
gotoxy(2,3);
fprintf(&mystdout2,"update");
gotoxy(2,5);
fprintf(&mystdout2,"firmware");
lcd_refresh();
delay_ms(1000);
BOOT();
}
}
//EMPTY_INTERRUPT(INT0_vect)
//EMPTY_INTERRUPT(INT2_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;
}
//************************************************************************
// 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;
volatile uint8_t timer_key_long;
void timer1_tik(void)
{
uint8_t key_temp;
while (timer1_ovf)
{
timer1_ovf--;
if (timer_status) timer_status--;
if (timer_refresh) timer_refresh--;
if (timer_off) timer_off--;
if (timer_key_long) timer_key_long--;
if (timer_temp) timer_temp--;
if (timer_key) timer_key--;
else
{
key_temp = 0;
if (!TL1_INPUT) key_temp = _BV(KEY1);
if (!TL2_INPUT) key_temp |= _BV(KEY2);
if (!TL3_INPUT) key_temp |= _BV(KEY3);
//if (key_temp != key_press)
{
if (key_temp != key_press)
{
timer_off= OFF_TIME;
timer_key_long=TIME_KEY_LONG;
}
timer_key = KEY_TIME_DEAD;
key_press = key_temp;
if (!key_flag) key_flag = key_press;
}
}
}
}
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;
}
//*********************************************************************
// key
uint8_t test_key(void)
{
static uint8_t key_next = 0;
if (key_press)
{
if (key_next)
{
key_read();
return 0;
}
if(!timer_key_long)
{
key_next = 1;
timer_key = KEY_TIME_FIRST;
switch(key_read())
{
case _BV(KEY1): return KEY1_LONG;
case _BV(KEY2): return KEY2_LONG;
case _BV(KEY3): return KEY3_LONG;
}
}
return 0;
}
key_next=0;
switch(key_read())
{
case _BV(KEY1): return KEY1_SHORT;
case _BV(KEY2): return KEY2_SHORT;
case _BV(KEY3): return KEY3_SHORT;
}
return 0;
}
//*********************************************************************
//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)
{
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 = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT - 2*CHAR_WIDTH - WIDTH_CHAR_SIGNALL_3D - 2;
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++);
}
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;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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)
{
uint8_t a,b;
uint8_t *ptr;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(8,2);
offset_text -=2;
ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;//offset_text++;
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
//gotoxy(9,2);
printf("%4.0fm",gps.altitude);
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)
{
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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)
{
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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;
switch(test_key())
{
case KEY1_LONG:if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: c=0;id_mod=ID_OFF;return;
case KEY3_LONG: c=0;return;
case KEY1_SHORT:c=0;timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:c=0;d++;timer_refresh = 0;break;
case KEY3_SHORT: break;
}
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
if (c--) return;
c=5;
buffer_clr();
//status();
#ifdef DEBUG
if(gps.gsv_satelites_view > 12)
{
printf("error view satelites");
lcd_refresh();
c=5;
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()
{
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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.1fm 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)
{
double lon,lat,temp;
double course;
uint8_t x,y,xl,yl,xp,yp;
uint8_t a,b;
uint8_t *ptr;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
const float gc_lat= MY_LAT,gc_lon=MY_LON; // DOMA
lon=(gc_lon-gps.longitude*60)*1214;
lat=(gc_lat-gps.latitude*60)*1854;
temp = sqrt((lon*lon) + (lat*lat));
gotoxy(9,3);
offset_text -=2;
ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
//offset_text++;
//gotoxy(10,3);
printf("%4.0fm",gps.altitude);
gotoxy(7,2);
printf(POINTNAME);
gotoxy(9,4);
if (temp < 10000)
{
if (temp<1000) fprintf(&mystdout2,"%.1f ",temp);
else
{
fprintf(&mystdout2,"%.3f ",temp/1000);
gotoxy(12,6);
printf("k");
}
gotoxy(13,6);
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,6);
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;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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,b;
uint8_t *ptr;
uint8_t x,y;
uint8_t xp,yp;
uint8_t xl,yl;
//uint8_t xs,ys;
double course;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
if (!timer_refresh)
{
timer_refresh = CLOCK1S;
buffer_clr();
status();
gotoxy(9,3);
offset_text -=2;
ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;//offset_text++;
for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
//gotoxy(10,3);
printf("%4.0fm",gps.altitude);
gotoxy(9,2);
printf("north");
gotoxy(9,4);
fprintf(&mystdout2,"%3.1f",gps.speed);
gotoxy(10,6);
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;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;++id_mod;return;
case KEY2_SHORT:
case KEY3_SHORT:break;
}
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 temp(void)
{
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_temp()
{
//GPS_OFF;
//ADC_OFF;
//REF_OFF;
switch(test_key())
{
case KEY1_LONG: timer_refresh = 0;if (LED_INPUT) LED_OFF;else LED_ON;break;
case KEY2_LONG: id_mod=ID_OFF;return;
case KEY3_LONG: return;
case KEY1_SHORT:timer_refresh = 0;id_mod++;return;
case KEY2_SHORT:timer_temp = 0; 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;
}break;
case KEY3_SHORT: break;
}
if(!timer_temp)
{
temp();
}
}
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)
{
uint8_t temp_wiev;
buffer_clr();
gotoxy(6,3);
fprintf(&mystdout2,"OFF");
lcd_refresh();
GPS_OFF;
REF_OFF;
ADC_OFF;
USART_PC_OFF;
delay_ms(1000);
LED_OFF;
N5110_send_command(POWER_DOWN);
temp_wiev = 0;
while (TL2_INPUT)
{
sleep_cpu();
if (!TL1_INPUT)
{
if (!temp_wiev) N5110_send_command(ACTIVE_CHIP);
temp_wiev = 1;
timer1_ovf = 0;
while ((!TL1_INPUT) && (timer1_ovf<200));
if (timer1_ovf==200)
{
max.temperature=0x8000;
min.temperature=0x7FFF;
}
}
if (!TL3_INPUT) {N5110_send_command(POWER_DOWN);temp_wiev = 0;}
if (temp_wiev) temp();
}
if (USB_PIN) USART_PC_ON;
else USART_PC_OFF;
null_variables();
LCD_N5110_INIT();
displ_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;
}
void null_variables(void)
{
key_press = 0;
key_flag = 0;
timer_key = 0;
timer_temp = 0;
timer_off = OFF_TIME;
timer_refresh = 0;
timer_status = 0;
timer1_ovf =0;
//max.temperature=0x8000;
//min.temperature=0x7FFF;
//sRTC=0;
//mRTC=15;
//hRTC=17;
//dRTC=25;
//mdRTC=7;
//yRTC=8;
id_mod = ID_START;
}
//************************************************************************
// main
int main(void)
{
pgps = &gps;
null_variables();
general_cpu_init();
//GPS_ON;
LCD_N5110_INIT();
//set_static_navigation(0);
if (USB_PIN) USART_PC_ON;
else USART_PC_OFF;
stdout = &mystdout;
sei();
for (;;)
{
switch(id_mod)
{
case ID_TIME: displ_time(); break;
case ID_LOCATION: 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: id_mod++;break;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;
}
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;
}
timer1_tik();
//id_mod = key(id_mod);
}
return 0;
}