Rev Author Line No. Line
1213 mija 1 /* mija 2008
2 demo for LCD NOKIA5110 and MCP9800 and GPS modul
3  
4 CPU ATMEGA644P
5 fcpu = 1MHz
6  
7 !! define PIN,PORT,DDR for IOpin !!
8 */
9  
10  
11 //************************************************************************
12 // defines
13  
14 #define KEY_TIME_DEAD 5 //cca 50ms 8*5
15 //#define KEY_TIME_START_REPEAT 100 //cca 1s
16 //#define KEY_TIME_REPEAT 20 //cca 240ms
17 #define KEY_TIME_FIRST 50
18  
19 #define TEMP_TIME_REPEAT 100
20  
21 #define OFF_TIME 200
22  
23 #define REFRESH_TIME 100
24  
25 #define STATUS_REFRESH_TIME 100
26  
27 #define CLOCK1S 100
28 #define CLOCK2S 200
29 #define CLOCK5S 255;
30 #define CLOCK50MS 5
31  
32 #define DEBUG
33  
34 //************************************************************************
35 //including
36  
37 #include <avr/io.h>
38 #include <stdlib.h>
39 #include <avr/pgmspace.h>
40 #include <avr/interrupt.h>
41 #include <avr/sleep.h>
42 #include <util/delay.h>
43 #include <stdio.h>
44 #include <math.h>
45 //#include "ascii_table.h"
46 #include "lcd.h" //define PINs LCD
47 #include "GPS.h" //define PINs GPS,TL,LED,REF,I2C
48 #include "nmea_scan.h"
49  
50 //************************************************************************
51 // pomocne
1217 mija 52  
1213 mija 53 #define WIDTH_CHAR_SIGNALL 8
54 prog_uint8_t CHAR_SIGNALL[WIDTH_CHAR_SIGNALL]={127,12,30,51,51,30,12,127};
55  
56 #define WIDTH_CHAR_SIGNALL_D 8
57 prog_uint8_t CHAR_SIGNALL_D[WIDTH_CHAR_SIGNALL_D]={127,12,30,63,63,30,12,127};
58  
59 #define WIDTH_CHAR_SIGNALL_2D 7
60 prog_uint8_t CHAR_SIGNALL_2D[WIDTH_CHAR_SIGNALL_2D]={1,2,4,127,4,2,1};
61  
62 #define WIDTH_CHAR_SIGNALL_3D 7
63 prog_uint8_t CHAR_SIGNALL_3D[WIDTH_CHAR_SIGNALL_3D]={124,68,71,69,125,17,31};
64  
65 #define WIDTH_CHAR_LIGHT 5
66 prog_uint8_t CHAR_LIGHT[WIDTH_CHAR_LIGHT]={127,65,95,95,127};
67  
68  
1217 mija 69 #define BOOT() (((void(*)(void))(char *)0x7C00)())
70 #define RESET() (((void(*)(void))(char *)0x0000)())
1213 mija 71 //***********************************************************************
72 // global variables
1217 mija 73  
1213 mija 74 extern uint8_t video_buf[504];
75 extern uint8_t *offset_text;
76  
77 uint8_t id_mod;
78 char scan_buf[MAX_NMEA_LOAD];
79 POINT_T now,max,min;
80 DATA_GPS gps;
81 DATA_GPS *pgps;
82  
83 enum {ID_TIME,ID_LOCATION,ID_COURSE,ID_ALL_POSITION,ID_ALL_SERVICE,ID_SERVICE,ID_TEMP,ID_SATELITES,ID_NORTH,ID_NAV};
84  
1217 mija 85 static FILE mystdout = FDEV_SETUP_STREAM(lcd_put, NULL,_FDEV_SETUP_WRITE); // in lcd.h
86 static FILE mystdout2 = FDEV_SETUP_STREAM(lcd_put2, NULL,_FDEV_SETUP_WRITE); // in lcd.h
1213 mija 87  
1217 mija 88 //************************************************************************
89 // prototypes
1213 mija 90  
1217 mija 91 //(*bootloader)(void) = 0x7C00;
92 void delay_ms(uint16_t time);
93 void null_variables(void);
94  
1213 mija 95 //************************************************************************
96 // general cpu init
97  
98 void general_cpu_init(void)
99 {
100 //*** IO_PIN ***
101 TL1_INIT;
102 TL1_PULLUP;
103 TL2_INIT;
104 TL2_PULLUP;
105 TL3_INIT;
106 TL3_PULLUP;
107  
1217 mija 108 USB_INIT;
109 //USB_PULLUP;
1213 mija 110  
111 GPS_INIT;
112 GPS_OFF;
113  
114 REF_INIT;
115 REF_OFF;
116  
117 nSCLK_INIT;
118 nSDIN_INIT;
119 nDC_INIT;
120 nCS_INIT;
121 nRESET_INIT;
122  
123 SCL_INIT;
124 SDA_FLOAT;
125  
126 LED_INIT;
127 LED_OFF;
128  
129 //*** EXTERNAL PIN INTERRUPTS
1217 mija 130 //EICRA = _BV(ISC21); //pin INT2 - TL2
131 //EIMSK = _BV(INT2); //pin INT2 - TL2
132  
1213 mija 133  
1217 mija 134 //*** PIN CHANGE INTERRUPTS PCINT29
135 PCICR = _BV(PCIE1);
136 PCMSK1 = _BV(PCINT10) | _BV(PCINT11) |_BV(PCINT12); //pin change TL1,TL2,TL3
137  
138 PCICR |= _BV(PCIE3);
139 PCMSK3 = _BV(PCINT29); // pin USB
140  
141 //*** TIMER1 *** tik for TL fosc/64 /1024(TCNT1) cca 8ms
1213 mija 142 TCNT1 = 0;
143 OCR1A = 1024;
144 TCCR1A = _BV(WGM11) | _BV(WGM10);
1217 mija 145 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11) | _BV(CS10) ; // TIMER1 fast PWM
1213 mija 146 TIMSK1 = _BV(TOIE1);
147  
148 //*** TIMER2 *** RTC
149 ASSR = _BV(AS2);
150 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
151 TIMSK2 = _BV(TOIE2);
152  
153 //*** SLEEP ***
154 SMCR = _BV(SM1) | _BV(SM0) | _BV(SE);
155  
156 //*** WDT ***
157 //WDTCSR = _BV(WDCE) | _BV(WDE);
158 //WDTCSR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0);
159  
160 //*** USART0 *** RX PD0, TX PD1, GPS
1217 mija 161 UBRR0 = 95;
1213 mija 162 //UCSR0A =
163 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
164  
165 //*** USART1 *** RX PD2, TX PD3 PC
1217 mija 166 #ifndef DEBUG
167 UBRR1 = 95;
168 #else
169 UBRR1 = 3;
170 #endif
1213 mija 171 //UCSR0A =
172 UCSR1B = _BV(RXCIE1) | _BV(RXEN0) | _BV(TXEN1);
173  
174 //*** ADC ***
175 ADMUX = _BV(REFS1) | _BV(MUX0);
1217 mija 176 ADCSRA = _BV(ADPS1) | _BV(ADPS2);
1213 mija 177  
178 }
179  
180 //************************************************************************
181 // interrupts + RTC / clock 8s ... TIMER2 /
182  
183 volatile uint8_t RTC_flag;
184 volatile uint8_t sRTC,mRTC,hRTC,dRTC,mdRTC,yRTC;
185  
186 uint8_t modulo(uint8_t h,uint8_t m) //pomocna fce pro modulo x
187 {
188 if (h<m) return (h);
189 return(h-m);
190 }
191  
192 void set_date(void) //citac datumu
193 {
194 dRTC++;
195 switch (mdRTC)
196 {
197 case 1:
198 case 3:
199 case 5:
200 case 7:
201 case 8:
202 case 10:
203 case 12: if(dRTC>=32) {dRTC=1;mdRTC++;if(mdRTC==13) {mdRTC =1;yRTC=modulo(yRTC++,100);}} break;
204 case 4:
205 case 6:
206 case 9:
207 case 11: if(dRTC>=31) {dRTC=1;mdRTC++;} break;
208 case 2: if (dRTC >= 30) {dRTC=1;mdRTC++;break;}
209 if (dRTC ==29) {if (!(yRTC & 0x03)) break;dRTC=1;mdRTC++;}
210 }
211 }
212  
213  
214 volatile uint8_t timer1_ovf;
215  
216 ISR(TIMER1_OVF_vect)
217 {
218 timer1_ovf ++;
219 }
220  
221  
222 ISR(TIMER2_OVF_vect)
223 {
224 sRTC += 8;
225 if (sRTC >= 60)
226 {
227 sRTC=modulo(sRTC,60); //1min
228 if (++mRTC>=60)
229 {
230 mRTC=0; //1hod
231 if (++hRTC>=24)
232 {
233 hRTC=0;
234 set_date(); //1den
235 }
236 }
237 }
238 }
239  
240 char rx_buf[MAX_RX_BUF];
241 volatile uint8_t rx_shift;
242  
243 ISR(USART0_RX_vect)
244 {
245 if (++rx_shift >= MAX_RX_BUF) rx_shift =0;
246 rx_buf[rx_shift]=UDR0;
247 UDR1 = UDR0;
248 }
249  
1217 mija 250 uint8_t first_char_usart1 = 0;
251  
1213 mija 252 ISR(USART1_RX_vect)
253 {
1217 mija 254 #ifndef DEBUG
1213 mija 255 UDR0 = UDR1;
1217 mija 256 #else
257 if (TL1_INPUT && TL3_INPUT) BOOT();
258 //bootloader();
259 #endif
1213 mija 260 }
261  
1217 mija 262 ISR(PCINT1_vect)
263 {
264 if ((!TL3_INPUT) && (!TL1_INPUT)) RESET();
265 }
266  
267 ISR(PCINT3_vect)
268 {
269 if (!TL2_INPUT && USB_INPUT)
270 {
271 cli();
272 buffer_clr();
273 gotoxy(2,3);
274 fprintf(&mystdout2,"programing");
275 gotoxy(6,5);
276 fprintf(&mystdout2,"mod");
277 lcd_refresh();
278 delay_ms(1000);
279 BOOT();
280 }
281  
282 }
283  
1213 mija 284 EMPTY_INTERRUPT(INT0_vect)
285 EMPTY_INTERRUPT(INT2_vect)
286 EMPTY_INTERRUPT(WDT_vect)
287  
288 //************************************************************************
289 // delay_ms functions /define fcpu /
290  
291 void delay_ms(uint16_t time)
292 {
293 while(time--) _delay_ms(1);
294 }
295 //************************************************************************
296 // static navigation
297  
298 void gps_put(char c)
299 {
300 while ( !( UCSR0A & _BV(UDRE0)) );
301 UDR0 = c;
302 }
303  
304 //************************************************************************
305 // key + timer1_ovf
306  
307  
308 volatile uint8_t key_press;
309 volatile uint8_t key_flag;
310 volatile uint8_t timer_key;
311 volatile uint8_t timer_temp;
312 volatile uint8_t timer_off;
313 volatile uint8_t timer_refresh;
314 volatile uint8_t timer_status;
315  
316 void timer1_tik(void)
317 {
318 uint8_t key_temp;
319  
1217 mija 320 while (timer1_ovf)
1213 mija 321 {
1217 mija 322 timer1_ovf--;
1213 mija 323 if (timer_status) timer_status--;
324 if (timer_refresh) timer_refresh--;
325 if (timer_off) timer_off--;
326 if (timer_temp) timer_temp--;
327 if (timer_key) timer_key--;
328 else
329 {
1217 mija 330 key_temp = 0;
331 if (!TL1_INPUT) key_temp = _BV(KEY1);
332 if (!TL2_INPUT) key_temp |= _BV(KEY2);
333 if (!TL3_INPUT) key_temp |= _BV(KEY3);
1213 mija 334 if (key_temp != key_press)
335 {
336 timer_key = KEY_TIME_DEAD;
337 key_press = key_temp;
338 if (!key_flag) key_flag = key_press;
339 timer_off= OFF_TIME;
340 }
341 }
342 }
343 }
344  
345 uint8_t key_read(void)
346 {
347 uint8_t key_send;
348  
349 key_send = key_flag;
350 key_flag = 0;
351 return key_send;
352 }
353  
354 //************************************************************************
355 // SW I2C /define SDA, SCL; tested for fosc 1Mhz/
356  
357 void I2C_start(void)
358 {
359 SDA_OUT;
360 SDA_L;
361 SCL_L;
362 }
363  
364 void I2C_stop(void)
365 {
366 SCL_H;
367 SDA_OUT;
368 SDA_H;
369 SDA_FLOAT;
370 }
371  
372 void I2C_write(uint8_t data)
373 {
374 uint8_t a;
375  
376 SDA_OUT;
377 for(a=0;a<8;a++)
378 {
379 SCL_L;
380 if (data & 0x80) SDA_H;
381 else SDA_L;
382 SCL_H;
383 data <<= 1;
384 }
385 SCL_L;
386 SDA_FLOAT;
387 SCL_H;
388 SCL_L;
389 }
390  
391 uint8_t I2C_read(uint8_t ack)
392 {
393 uint8_t a;
394 uint8_t data;
395  
396 SDA_IN;
397 data=0;
398 for(a=0;a<8;a++)
399 {
400 SCL_H;
401 if (SDA_INPUT) data |=1;
402 SCL_L;
403 if (a != 7)data <<= 1;
404 }
405  
406 if (ack) {SDA_OUT;SDA_L;}
407 else SDA_FLOAT;
408 SCL_H;
409 SCL_L;
410 SDA_FLOAT;
411 return data;
412 }
413  
414 //************************************************************************
415 // temperature sensor MCP9800 of MICROCHIP
416  
417 void start_MCP9800(void)
418 {
419 I2C_start();
420 I2C_write(0x90);
421 I2C_write(0x1); // configuration pointer MCP9800
422 //I2C_write(0xE1); // 12bit + only 1 convert and then sleep
423 I2C_write(0x81); // 9bit + only 1 convert and then sleep
424 I2C_stop();
425 I2C_start();
426 I2C_write(0x90);
427 I2C_write(0x0); // temperature pointer
428 I2C_stop();
429 }
430  
431 uint16_t read_temp(void)
432 {
433 uint16_t temp;
434  
435 I2C_start();
436 I2C_write(0x91);
437 temp = I2C_read(1) << 8;
438 temp |= I2C_read(0);
439 I2C_stop();
440 return temp;
441 }
442  
443 //************************************************************************
444 // templota
445  
446 void print_temp(int16_t teplota)
447 {
448 printf("%d.%01dC",((teplota>>8) & 0x807F) | (teplota & 0x8000),5*((teplota>>7)& 0x1));
449 }
450  
451 void print_time(TIME_T time)
452 {
453 uint8_t temp;
454  
455 temp = time.hour/10;
456 if (temp == 0) lcd_put(' ',0);
457 else lcd_put(temp + 0x30,0);
458 lcd_put(time.hour%10 + 0x30,0);
459 //put_lcd(':');
460 *(offset_text++) = 0x36;
461 offset_text++;
462 lcd_put(time.min/10 + 0x30,0);
463 lcd_put(time.min%10 + 0x30,0);
464 //put_lcd(':');
465 //put_lcd(sRTC/10 + 0x30);
466 //put_lcd(sRTC%10 + 0x30);
467 }
468  
469 void print_date(DATE_T date)
470 {
471 uint8_t temp;
472  
473 temp = date.day/10;
474 if (temp == 0) lcd_put(' ',0);
475 else lcd_put(temp + 0x30,0);
476 lcd_put(date.day%10 + 0x30,0);
477 //put_lcd('/');
478 *(offset_text++) = 0x60;
479 offset_text++;
480 temp = date.mon/10;
481 if (temp != 0) lcd_put(temp + 0x30,0);
482 lcd_put(date.mon%10 + 0x30,0);
483 if (temp == 0)
484 {
485 *(offset_text++) = 0x60;
486 offset_text++;
487 }
488 //put_lcd('/');
489 //put_lcd(yRTC/10 + 0x30);
490 //put_lcd(yRTC%10 + 0x30);
491 }
492  
493 TIME_T actual_time(void)
494 {
495 TIME_T time;
496  
497 time.sec=sRTC;
498 time.min=mRTC;
499 time.hour=hRTC;
500 return time;
501 }
502  
503 DATE_T actual_date(void)
504 {
505 DATE_T date;
506  
507 date.day=dRTC;
508 date.mon=mdRTC;
509 date.year=yRTC;
510 return date;
511 }
512  
513 //*********************************************************************
514 //status
515  
516 void status(void)
517 {
518 uint8_t a,b;
519 uint8_t *ptr;
520  
521 start_MCP9800();
522 REF_ON;
523 ADC_ON;
524 ADCSRA |= _BV(ADSC);
525 while (!(ADCSRA & _BV(ADIF)));
526  
527 gotoxy(1,1);
528 printf("%0.1fV %2d",1024.0*25/ADC/10,read_temp()>>8);
529 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT - 2*CHAR_WIDTH - WIDTH_CHAR_SIGNALL_3D - WIDTH_CHAR_SIGNALL - 2;
530 if (gps.fix_position)
531 {
1217 mija 532  
533 ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;//offset_text++;
534 if (gps.mode2 == '3')
535 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
536  
537 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT - 2*CHAR_WIDTH - WIDTH_CHAR_SIGNALL_3D - 2;
1213 mija 538 switch (gps.fix_position)
539 {
540 case 1: ptr= CHAR_SIGNALL;b=WIDTH_CHAR_SIGNALL;break;
541 case 2: ptr= CHAR_SIGNALL_D;b=WIDTH_CHAR_SIGNALL_D;break;
542 case 0:
543 default:ptr= CHAR_SIGNALL;b=0;
544 }
545 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
546  
1217 mija 547  
1213 mija 548 }
549 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT-2*CHAR_WIDTH;
550 printf("%d",gps.satelites_used);
551 if (LED_INPUT)
552 {
553 ptr= CHAR_LIGHT;b=WIDTH_CHAR_LIGHT;
554 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT;
555 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
556 }
557  
558 }
559  
560 //************************************************************************
561 // mod
562  
563 void displ_time(void)
564 {
565 GPS_ON;
566 if (!timer_refresh)
567 {
568 timer_refresh = CLOCK1S;
569 buffer_clr();
570 status();
1217 mija 571 //gotoxy(1,2);
572 // printf("time & date");
1213 mija 573 gotoxy(1,3);
574 fprintf(&mystdout2," %2d:%02d:%02d",gps.hour+2,gps.minute,gps.second);
575 gotoxy(1,5);
576 fprintf(&mystdout2," %2d.%02d.20%02d",gps.day,gps.month,gps.year);
577 lcd_refresh();
578 }
579 }
580  
581 void displ_location(void)
582 {
1217 mija 583 uint8_t a,b;
584 uint8_t *ptr;
585  
1213 mija 586 if (!timer_refresh)
587 {
588 timer_refresh = CLOCK1S;
589 buffer_clr();
590 status();
1217 mija 591  
592 gotoxy(8,2);
593 offset_text -=2;
594 ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;//offset_text++;
595 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
596  
597 //gotoxy(9,2);
598 printf("%4.0fm",gps.altitude);
599  
1213 mija 600 gotoxy(1,3);
601 //gps.latitude = 14.5;
602 fprintf(&mystdout2,"%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
603 gotoxy(1,5);
604 //gps.longitude = 48.25;
605 fprintf(&mystdout2,"%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
606 lcd_refresh();
607 }
608 }
609  
610 void displ_speed(void)
611 {
612 if (!timer_refresh)
613 {
614 timer_refresh = CLOCK1S;
615 buffer_clr();
616 status();
617 gotoxy(1,2);
618 printf("speed");
619 gotoxy(1,4);
620 fprintf(&mystdout2," %3.1f km/h",gps.speed);
621 lcd_refresh();
622 }
623 }
624  
625 void displ_course(void)
626 {
627 if (!timer_refresh)
628 {
629 timer_refresh = CLOCK1S;
630 buffer_clr();
631 status();
632 //gotoxy(1,2);
633 //printf("course");
634 gotoxy(1,3);
635 fprintf(&mystdout2," %3.1f km/h",gps.speed);
636 gotoxy(6,5);
637 fprintf(&mystdout2,"%3.0f",gps.course);
638 lcd_refresh();
639 }
640 }
641  
642 void displ_satelites(void)
643 {
644 #define WIDTH_REC 60
645  
646 uint8_t a,x,y,b;
647 static uint8_t d = 0;
648 static uint8_t c = 0;
649 double elevace,azimut;
650  
651 if (!timer_refresh)
652 {
653 timer_refresh = CLOCK1S;
654 if (c--) return;
655 c=3;
656 buffer_clr();
657 //status();
658 #ifdef DEBUG
659 if(gps.gsv_satelites_view > 12)
660 {
661 printf("error view satelites");
662 lcd_refresh();
663 c=20;
664 return;
665 }
666 #endif
667 if (++d >= gps.gsv_satelites_view) d = 0;
668 gotoxy(12,1);
669 printf("%d",gps.gsv_satelites_view);
670 gotoxy(12,2);
671 printf("%d",gps.satelit_detail[d].id);
672 gotoxy(12,3);
673 printf("%d",gps.satelit_detail[d].azimut);
674 gotoxy(12,4);
675 printf("%d",gps.satelit_detail[d].elevation);
676 gotoxy(12,5);
677 printf("%d",gps.satelit_detail[d].SNR);
678 gotoxy(12,6);
679  
680 for (a=0;a<gps.gsv_satelites_view;a++)
681 {
682 azimut = (double)gps.satelit_detail[a].azimut;
683 elevace = (double)gps.satelit_detail[a].elevation;
684  
685 x=(uint8_t)((WIDTH_REC-4)/2.0/90.0*(90.0-elevace)*sin(M_PI/180*azimut) + WIDTH_REC/2.0);
686 y=(uint8_t)((LCD_HEIGHT-4)/2.0/90.0*(90.0-elevace)*cos(M_PI/180*azimut) + LCD_HEIGHT/2.0);
687 if (gps.satelit_detail[a].SNR)
688 {
689 lcd_plot(x-1,y);lcd_plot(x+1,y);lcd_plot(x,y-1);lcd_plot(x,y+1);
690 for (b=0;b<gps.satelites_used;b++)
691 if (gps.satelit_detail[a].id == gps.satelite_id[b])
692 lcd_plot(x,y);
693 }
694 else lcd_plot(x,y);
695  
696 if (d == a)
697 {
698 lcd_line(x-2,y-2,x-2,y+2);
699 lcd_line(x+2,y+2,x+2,y-2);
700 lcd_line(x+2,y+2,x-2,y+2);
701 lcd_line(x-2,y-2,x+2,y-2);
702 }
703 }
704  
705 lcd_line(0,0,WIDTH_REC,0);
706 lcd_line(0,LCD_HEIGHT-1,WIDTH_REC,LCD_HEIGHT-1);
707 lcd_line(0,0,0,LCD_HEIGHT-1);
708 lcd_line(WIDTH_REC,0,WIDTH_REC,LCD_HEIGHT-1);
709  
710 lcd_refresh();
711 }
712 }
713  
714 void displ_all_position()
715 {
716 if (!timer_refresh)
717 {
718 timer_refresh = CLOCK1S;
719 buffer_clr();
720 status();
721  
722 gotoxy(1,2);
723 printf("%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
724 gotoxy(1,3);
725 printf("%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
726 gotoxy(1,4);
727 printf("alt%4.0fm V%2.1f",gps.altitude,gps.VDOP);
728 gotoxy(1,5);
1217 mija 729 printf("geo%4.1fm H%2.1f",gps.geoid,gps.HDOP);
1213 mija 730 gotoxy(1,6);
731 printf("%3.0fkm/h %3.0f",gps.speed,gps.course);
732 lcd_refresh();
733 }
734 }
735  
736 void displ_nav(void)
737 {
1217 mija 738  
1213 mija 739 double lon,lat,temp;
740 double course;
741 uint8_t x,y,xl,yl,xp,yp;
1217 mija 742 uint8_t a,b;
743 uint8_t *ptr;
1213 mija 744  
745 if (!timer_refresh)
746 {
747 timer_refresh = CLOCK1S;
748 buffer_clr();
749 status();
750  
751 const float gc_lat=48*60+57.7647,gc_lon=14*60+28.0836; // DOMA
752  
753 lon=(gc_lon-gps.longitude*60)*1214;
754 lat=(gc_lat-gps.latitude*60)*1854;
755 temp = sqrt((lon*lon) + (lat*lat));
756  
757 gotoxy(9,3);
1217 mija 758 offset_text -=2;
759 ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;
760 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
761 //offset_text++;
762  
763 //gotoxy(10,3);
764 printf("%4.0fm",gps.altitude);
765  
766 gotoxy(7,2);
767 printf("go home");
768  
769 gotoxy(9,4);
1213 mija 770 if (temp < 10000)
771 {
772 if (temp<1000) fprintf(&mystdout2,"%.1f ",temp);
773 else
774 {
775 fprintf(&mystdout2,"%.3f ",temp/1000);
1217 mija 776 gotoxy(12,6);
1213 mija 777 printf("k");
778 }
1217 mija 779 gotoxy(13,6);
1213 mija 780 printf("m");
781 }
782 else
783 {
784 temp=temp/1000;
785 if (temp < 1000)
786 {
787 if (temp < 100)
788 {
789 fprintf(&mystdout2,"%.2f ",temp);
790 }
791 else
792 {
793 fprintf(&mystdout2,"%.1f ",temp);
794 }
795 }
796 else fprintf(&mystdout2,"%5.0f ",temp);
1217 mija 797 gotoxy(12,6);
1213 mija 798 printf("km");
799 }
800  
801 if (lat==0) lat=0.001;
802 lon=M_PI/2.0-(atan2(lat,lon));
803 if (lon<0) lon+=2*M_PI;
804 if (lon>(2*M_PI)) lon-=2*M_PI;
805 //printf(lcd_putc,"BE%2.0g*",lon);
806 lat=M_PI/180*gps.course;
807 lon=lon-lat;
808 if (lon<0) lon+=2*M_PI;
809 if (lon>2*M_PI) lon-=2*M_PI;
810 //printf(lcd_putc,"HE%2.0g*AZ%2.0g* ",lon,lat);
811  
812 #define WIDTH_REC_NAV 43
813 #define LCD_HEIGHT_NAV 35
814  
815 course = lon;
816 x=(uint8_t)(WIDTH_REC_NAV/2.0*sin(course) +WIDTH_REC_NAV/2);
817 y=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos(course) +(LCD_HEIGHT_NAV)/2);
818  
819 xl=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course-2.62))+WIDTH_REC_NAV/2 );
820 yl=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course-2.62))+(LCD_HEIGHT_NAV)/2 );
821  
822 xp=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course+2.62))+WIDTH_REC_NAV/2 );
823 yp=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course+2.62)) +(LCD_HEIGHT_NAV)/2);
824  
825 //xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
826 //ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
827  
828 lcd_line( x,y,xl,yl);
829 lcd_line( x,y,xp,yp);
830 //lcd_line( xp,yp,xl,yl);
831 lcd_line(xl,yl,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
832 lcd_line(xp,yp,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
833  
834 //lcd_line(xl,yl,xs,ys);
835 //lcd_line(xp,yp,xs,ys);
836 lcd_refresh();
837 }
838 }
839  
840 void displ_service(char *buf)
841 {
842 uint8_t a;
843  
844 if (!timer_refresh)
845 {
846 timer_refresh = CLOCK1S;
847 buffer_clr();
848 for (a = 0; a<80; a++) putchar(*(buf++));
849 lcd_refresh();
850 }
851 }
852  
853 void displ_north(void)
854 {
1217 mija 855 uint8_t a,b;
856 uint8_t *ptr;
1213 mija 857 uint8_t x,y;
858 uint8_t xp,yp;
859 uint8_t xl,yl;
860 //uint8_t xs,ys;
861 double course;
862  
863 if (!timer_refresh)
864 {
865 timer_refresh = CLOCK1S;
866 buffer_clr();
867 status();
1217 mija 868  
1213 mija 869 gotoxy(9,3);
1217 mija 870 offset_text -=2;
871 ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;//offset_text++;
872 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
873  
874 //gotoxy(10,3);
875 printf("%4.0fm",gps.altitude);
876  
877 gotoxy(9,2);
878 printf("north");
879  
880 gotoxy(9,4);
1213 mija 881 fprintf(&mystdout2,"%3.1f",gps.speed);
1217 mija 882 gotoxy(10,6);
1213 mija 883 printf("km/h");
884  
885 #define WIDTH_REC_NORTH 43
886 #define LCD_HEIGHT_NORTH 35
887  
888 course = 360-gps.course;
889 x=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*course) +WIDTH_REC_NORTH/2);
890 y=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*course) +(LCD_HEIGHT_NORTH)/2);
891  
892 xl=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course-150.0))+WIDTH_REC_NORTH/2 );
893 yl=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course-150.0))+(LCD_HEIGHT_NORTH)/2 );
894  
895 xp=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course+150.0))+WIDTH_REC_NORTH/2 );
896 yp=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course+150.0)) +(LCD_HEIGHT_NORTH)/2);
897  
898 //xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
899 //ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
900  
901 lcd_line( x,y,xl,yl);
902 lcd_line( x,y,xp,yp);
903 //lcd_line( xp,yp,xl,yl);
904 lcd_line(xl,yl,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
905 lcd_line(xp,yp,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
906  
907 //lcd_line(xl,yl,xs,ys);
908 //lcd_line(xp,yp,xs,ys);
909 lcd_refresh();
910 }
911 }
912  
913 void displ_all_service(void)
914 {
915 uint8_t a;
916  
917 if (!timer_refresh)
918 {
919 timer_refresh = CLOCK1S;
920 buffer_clr();
921 status();
922  
923 gotoxy(1,2);
924 printf("d=%d %ds",gps.diff_id,gps.age_diff_corr);
925 gotoxy(1,3);
926 printf("%c st=%cD ",gps.mode1,gps.mode2);
927 switch (gps.fix_position)
928 {
929 case 0: printf("nofix");break;
930 case 1: printf("SPSfix");break;
931 case 2: printf(" Dfix");break;
932 default: printf("nopref");
933 }
934 gotoxy(1,4);
935 printf("GSV %d %d %d",gps.gsv_num_msg,gps.gsv_msg,gps.gsv_satelites_view);
936 gotoxy(1,5);
937 for(a=0;a<6;a++)
938 {
939 printf("%2d",gps.satelite_id[a]);
940 offset_text+=2;
941 }
942 gotoxy(1,6);
943 for(a=6;a<12;a++)
944 {
945 printf("%2d",gps.satelite_id[a]);
946 if (a != 11) offset_text+=2;
947 }
948 lcd_refresh();
949 }
950 }
951  
952 void displ_temp()
953 {
954 //GPS_OFF;
955 //ADC_OFF;
956 //REF_OFF;
957  
958 if(!timer_temp)
959 {
960 timer_temp = TEMP_TIME_REPEAT;
961 now.temperature=read_temp();
962 now.time=actual_time();
963 now.date=actual_date();
964  
965 buffer_clr();
966 gotoxy(1,1);
967 stdout = &mystdout2;
968 print_temp(now.temperature);
969 stdout = &mystdout;
970 gotoxy(11,1);
971 offset_text-= 2;
972 print_time(now.time);
973 gotoxy(11,2);
974 offset_text-= 2;
975 print_date(now.date);
976 gotoxy(1,4);
977 if (now.temperature > max.temperature) max=now;
978 print_temp(max.temperature);
979 gotoxy(11,4);
980 offset_text-= 2;
981 print_date(max.date);
982 gotoxy(6,3);
983 printf("max");
984 gotoxy(11,3);
985 offset_text-= 2;
986 print_time(max.time);
987 gotoxy(1,6);
988 if (now.temperature < min.temperature) min=now;
989 print_temp(min.temperature);
990 gotoxy(11,6);
991 offset_text-= 2;
992 print_date(min.date);
993 gotoxy(6,5);
994 printf("min");
995 gotoxy(11,5);
996 offset_text-= 2;
997 print_time(min.time);
998 lcd_refresh();
999 start_MCP9800();
1000 }
1001 }
1002  
1003 void displ_start(void)
1004 {
1005 buffer_clr();
1006 gotoxy(6,3);
1007 fprintf(&mystdout2,"GPS");
1008 lcd_refresh();
1009 delay_ms(1000);
1010 id_mod = ID_TEMP;
1011  
1012 }
1013  
1014 void all_off(void)
1015 {
1016 buffer_clr();
1017 gotoxy(6,3);
1018 fprintf(&mystdout2,"OFF");
1019 lcd_refresh();
1020 GPS_OFF;
1021 REF_OFF;
1217 mija 1022 delay_ms(1000);
1023 LED_OFF;
1213 mija 1024 N5110_send_command(POWER_DOWN);
1025  
1026 while (TL2_INPUT)
1217 mija 1027 {
1028 sleep_cpu();
1213 mija 1029  
1217 mija 1030 }
1031 null_variables();
1213 mija 1032 LCD_N5110_INIT();
1217 mija 1033 displ_start();
1213 mija 1034 }
1035  
1036 //************************************************************************
1037 // spol key
1038  
1039 uint8_t key(uint8_t mod)
1040 {
1041 if(key_press)
1042 {
1043 if (!timer_off)
1044 {
1045 if (key_read() == _BV(KEY2))
1046 {
1047 timer_refresh = 0;
1048 timer_key = CLOCK2S;
1049 key_read();
1050 return ID_OFF;
1051 }
1052 }
1053 }
1054 else
1055 {
1056 if (key_flag == _BV(KEY1))
1057 {
1058 timer_key = KEY_TIME_FIRST;
1059 key_read();
1060 timer_refresh = 0;
1061 ++mod;
1062 }
1063 if (key_flag == _BV(KEY2))
1064 {
1065 if (LED_INPUT) LED_OFF;
1066 else LED_ON;
1067 timer_key = KEY_TIME_FIRST;
1068 key_read();
1069 }
1070 if (key_flag == _BV(KEY3))
1071 {
1072 max.temperature=0x8000;
1073 min.temperature=0x7FFF;
1074 if (GPS_INPUT && (gps.status == 'A'))
1075 {
1076 sRTC=gps.second;
1077 mRTC=gps.minute;
1078 hRTC=gps.hour+2;
1079  
1080 dRTC=gps.day;
1081 mdRTC=gps.month;
1082 yRTC=gps.year;
1083 }
1084  
1085 timer_key = KEY_TIME_FIRST;
1086 key_read();
1087 }
1088 }
1089 return mod;
1090 }
1091  
1217 mija 1092 void null_variables(void)
1093 {
1094 key_press = 0;
1095 key_flag = 0;
1096  
1097 timer_key = 0;
1098 timer_temp = 0;
1099 timer_off = OFF_TIME;
1100 timer_refresh = 0;
1101 timer_status = 0;
1102 timer1_ovf =0;
1103  
1104 //max.temperature=0x8000;
1105 //min.temperature=0x7FFF;
1106  
1107 //sRTC=0;
1108 //mRTC=15;
1109 //hRTC=17;
1110  
1111 //dRTC=25;
1112 //mdRTC=7;
1113 //yRTC=8;
1114  
1115 id_mod = ID_START;
1116 }
1117  
1213 mija 1118 //************************************************************************
1119 // main
1120  
1121 int main(void)
1217 mija 1122 {
1213 mija 1123  
1124 pgps = &gps;
1125  
1217 mija 1126 null_variables();
1127  
1213 mija 1128 general_cpu_init();
1129 //GPS_ON;
1130 LCD_N5110_INIT();
1131  
1132 //set_static_navigation(0);
1133  
1134 stdout = &mystdout;
1135 sei();
1136  
1137 for (;;)
1138 {
1139 switch(id_mod)
1140 {
1217 mija 1141 case ID_TIME: displ_time(); break;
1142 case ID_LOCATION: displ_location();break;
1213 mija 1143 //case ID_SPEED: displ_speed(); break;
1217 mija 1144 case ID_SATELITES: displ_satelites();break;
1145 case ID_COURSE: id_mod++;break;displ_course(); break;
1146 case ID_ALL_POSITION: displ_all_position(); break;
1147 case ID_ALL_SERVICE: id_mod++;break;displ_all_service();break;
1148 case ID_SERVICE: id_mod++;break;displ_service(scan_buf);break;
1149 case ID_TEMP: displ_temp(); break;
1150 case ID_OFF: all_off(); break;
1151 case ID_START: displ_start(); break;
1213 mija 1152 case ID_NAV: displ_nav();break;
1217 mija 1153 case ID_NORTH: displ_north();break;
1213 mija 1154 default : id_mod = 0;
1155 }
1156  
1157  
1158 switch (load_nmea(rx_shift,rx_buf,scan_buf))
1159 {
1160 case RETURN_GGA: nmea_gga(scan_buf,pgps);break;
1161 case RETURN_GSA: nmea_gsa(scan_buf,pgps);break;
1162 case RETURN_GSV: nmea_gsv(scan_buf,pgps);break;
1163 case RETURN_RMC: nmea_rmc(scan_buf,pgps);break;
1164 case RETURN_VTG: nmea_vtg(scan_buf,pgps);break;
1165 }
1217 mija 1166  
1167 timer1_tik();
1168  
1169 id_mod = key(id_mod);
1170  
1213 mija 1171 }
1172 return 0;
1173 }
1174