/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;
}
 
/Designs/GPSnavigator/SW/GPS/GPS.h
0,0 → 1,193
/* mija 2008
demo for LCD NOKIA5110 and MCP9800 and GPS modul
 
CPU ATMEGA644P
fcpu = 1MHz
 
!! define PIN,PORT,DDR for IOpin !!
*/
 
#include <stdint.h>
 
#define MAX_RX_BUF 150
#define MAX_NMEA_LOAD 100
 
// PIN TL1
#define TL1 PB4 // input
#define TL1_DDR DDRB
#define TL1_PORT PORTB
#define TL1_PIN PINB
 
// PIN TL2
#define TL2 PB2 // input //int2
#define TL2_DDR DDRB
#define TL2_PORT PORTB
#define TL2_PIN PINB
 
// PIN TL3
#define TL3 PB3 // input
#define TL3_DDR DDRB
#define TL3_PORT PORTB
#define TL3_PIN PINB
 
// PIN GPS
#define GPS PD4
#define GPS_DDR DDRD
#define GPS_PORT PORTD
 
// UART SW
#define RX PD2 // input
#define RX_DDR DDRD
#define RX_PORT PORTD
#define RX_PIN PIND
 
// i2C SW
#define SDA PC1
#define SDA_PORT PORTC
#define SDA_DDR DDRC
#define SDA_PIN PINC
 
#define SCL PC0
#define SCL_PORT PORTC
#define SCL_DDR DDRC
 
// LED
#define LED PD7
#define LED_PORT PORTD
#define LED_DDR DDRD
 
// Vref
#define REF PA0
#define REF_PORT PORTA
#define REF_DDR DDRA
 
// interni
#define TL1_INIT TL1_DDR &= ~(_BV(TL1))
#define TL1_INPUT (TL1_PIN & _BV(TL1))
#define TL1_PULLUP TL1_PORT |= _BV(TL1)
 
#define TL2_INIT TL2_DDR &= ~(_BV(TL2))
#define TL2_INPUT (TL2_PIN & _BV(TL2))
#define TL2_PULLUP TL2_PORT |= _BV(TL2)
 
#define TL3_INIT TL3_DDR &= ~(_BV(TL3))
#define TL3_INPUT (TL3_PIN & _BV(TL3))
#define TL3_PULLUP TL3_PORT |= _BV(TL3)
 
#define GPS_OFF GPS_PORT |= _BV(GPS)
#define GPS_ON GPS_PORT &= (~(_BV(GPS)))
#define GPS_INIT GPS_DDR |= _BV(GPS)
#define GPS_INPUT (!(GPS_PORT & _BV(GPS)))
 
#define RX_INIT RX_DDR &= ~(_BV(RX))
#define RX_INPUT (RX_PIN & _BV(RX))
#define RX_PULLUP RX_PORT |= _BV(RX)
 
#define SCL_INIT SCL_DDR |= _BV(SCL)
#define SCL_L SCL_PORT &= ~(_BV(SCL))
#define SCL_H SCL_PORT |= _BV(SCL)
 
#define SDA_OUT SDA_DDR |= _BV(SDA)
#define SDA_L SDA_PORT &= ~(_BV(SDA))
#define SDA_H SDA_PORT |= _BV(SDA)
#define SDA_IN SDA_DDR &= ~(_BV(SDA))
#define SDA_INPUT (SDA_PIN & _BV(SDA))
#define SDA_FLOAT SDA_IN;SDA_L
 
#define LED_ON LED_PORT |= _BV(LED)
#define LED_OFF LED_PORT &= (~(_BV(LED)))
#define LED_INIT LED_DDR |= _BV(LED)
#define LED_INPUT (LED_PORT & _BV(LED))
 
#define REF_ON REF_PORT |= _BV(REF)
#define REF_OFF REF_PORT &= (~(_BV(REF)))
#define REF_INIT REF_DDR |= _BV(REF)
 
#define ADC_ON ADCSRA |= _BV(ADEN)
#define ADC_OFF ADCSRA &= ~(_BV(ADEN))
 
#define KEY1 0
#define KEY2 1
#define KEY3 3
 
#define ID_OFF 100
#define ID_START 101
#define ID_SETUP 102
 
#ifndef TYPEDEF_OK
//typedef struct{uint8_t a; uint8_t b}GPS_SEND;
typedef struct
{
uint8_t sec;
uint8_t min;
uint8_t hour;
}TIME_T;
 
typedef struct
{
uint8_t day;
uint8_t mon;
uint8_t year;
}DATE_T;
 
typedef struct
{
double lat;
double lon;
double alt;
double speed;
double course;
int16_t temperature;
TIME_T time;
DATE_T date;
}POINT_T;
 
typedef struct
{
uint8_t id;
uint8_t elevation;
uint16_t azimut;
uint8_t SNR;
}SATELITE_DETAIL;
 
typedef struct
{
//GGA
uint8_t fix_position;
uint8_t satelites_used;
double altitude;
double geoid;
uint16_t age_diff_corr;
uint16_t diff_id;
//GSA
char mode1;
char mode2;
uint8_t satelite_id[12];
double PDOP;
double HDOP;
double VDOP;
//GSV
uint8_t gsv_num_msg;
uint8_t gsv_msg;
uint8_t gsv_satelites_view;
SATELITE_DETAIL satelit_detail[12];
//RMC
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint8_t year;
double latitude;
double longitude;
char ns_indicator;
char we_indicator;
char status;
//VTG
double course;
double speed;
}DATA_GPS;
 
#endif
 
#define TYPEDEF_OK
/Designs/GPSnavigator/SW/GPS/ascii_table.h
0,0 → 1,105
#define CHAR_WIDTH 6
 
prog_uint8_t ASCII_TABLE1[480]=
{0x00,0x00,0x00,0x00,0x00, // 20 space ASCII table 96 rows * 5 bytes= 480 bytes
0x00,0x00,0x5f,0x00,0x00, // 21 !
0x00,0x07,0x00,0x07,0x00, // 22 "
0x14,0x7f,0x14,0x7f,0x14, // 23 #
0x24,0x2a,0x7f,0x2a,0x12, // 24 $
0x23,0x13,0x08,0x64,0x62, // 25 %
0x36,0x49,0x55,0x22,0x50, // 26 &
0x00,0x05,0x03,0x00,0x00, // 27 '
0x00,0x1c,0x22,0x41,0x00, // 28 (
0x00,0x41,0x22,0x1c,0x00, // 29 )
0x14,0x08,0x3e,0x08,0x14, // 2a *
0x08,0x08,0x3e,0x08,0x08, // 2b +
0x00,0x50,0x30,0x00,0x00, // 2c ,
0x08,0x08,0x08,0x08,0x08, // 2d -
0x00,0x60,0x60,0x00,0x00, // 2e .
0x20,0x10,0x08,0x04,0x02, // 2f /
0x3e,0x51,0x49,0x45,0x3e, // 30 0
0x00,0x42,0x7f,0x40,0x00, // 31 1
0x42,0x61,0x51,0x49,0x46, // 32 2
0x21,0x41,0x45,0x4b,0x31, // 33 3
0x18,0x14,0x12,0x7f,0x10, // 34 4
0x27,0x45,0x45,0x45,0x39, // 35 5
0x3c,0x4a,0x49,0x49,0x30, // 36 6
0x01,0x71,0x09,0x05,0x03, // 37 7
0x36,0x49,0x49,0x49,0x36, // 38 8
0x06,0x49,0x49,0x29,0x1e, // 39 9
0x00,0x36,0x36,0x00,0x00, // 3a :
0x00,0x56,0x36,0x00,0x00, // 3b ;
0x08,0x14,0x22,0x41,0x00, // 3c <
0x14,0x14,0x14,0x14,0x14, // 3d =
0x00,0x41,0x22,0x14,0x08, // 3e >
0x02,0x01,0x51,0x09,0x06, // 3f ?
0x32,0x49,0x79,0x41,0x3e, // 40 @
0x7e,0x11,0x11,0x11,0x7e, // 41 A
0x7f,0x49,0x49,0x49,0x36, // 42 B
0x3e,0x41,0x41,0x41,0x22, // 43 C
0x7f,0x41,0x41,0x22,0x1c, // 44 D
0x7f,0x49,0x49,0x49,0x41, // 45 E
0x7f,0x09,0x09,0x09,0x01, // 46 F
0x3e,0x41,0x49,0x49,0x7a, // 47 G
0x7f,0x08,0x08,0x08,0x7f, // 48 H
0x00,0x41,0x7f,0x41,0x00, // 49 I
0x20,0x40,0x41,0x3f,0x01, // 4a J
0x7f,0x08,0x14,0x22,0x41, // 4b K
0x7f,0x40,0x40,0x40,0x40, // 4c L
0x7f,0x02,0x0c,0x02,0x7f, // 4d M
0x7f,0x04,0x08,0x10,0x7f, // 4e N
0x3e,0x41,0x41,0x41,0x3e, // 4f O
0x7f,0x09,0x09,0x09,0x06, // 50 P
0x3e,0x41,0x51,0x21,0x5e, // 51 Q
0x7f,0x09,0x19,0x29,0x46, // 52 R
0x46,0x49,0x49,0x49,0x31, // 53 S
0x01,0x01,0x7f,0x01,0x01, // 54 T
0x3f,0x40,0x40,0x40,0x3f, // 55 U
0x1f,0x20,0x40,0x20,0x1f, // 56 V
0x3f,0x40,0x38,0x40,0x3f, // 57 W
0x63,0x14,0x08,0x14,0x63, // 58 X
0x07,0x08,0x70,0x08,0x07, // 59 Y
0x61,0x51,0x49,0x45,0x43, // 5a Z
0x00,0x7f,0x41,0x41,0x00, // 5b [
0x02,0x04,0x08,0x10,0x20, // 5c "\"
//0x00,0x41,0x41,0x7f,0x00, // 5d ] navic !!!????
0x00,0x41,0x41,0x7f,0x00, // 5d ]
0x04,0x02,0x01,0x02,0x04, // 5e ^
0x40,0x40,0x40,0x40,0x40, // 5f _
0x00,0x01,0x02,0x04,0x00, // 60 '
0x20,0x54,0x54,0x54,0x78, // 61 a
0x7f,0x48,0x44,0x44,0x38, // 62 b
0x38,0x44,0x44,0x44,0x20, // 63 c
0x38,0x44,0x44,0x48,0x7f, // 64 d
0x38,0x54,0x54,0x54,0x18, // 65 e
0x08,0x7e,0x09,0x01,0x02, // 66 f
0x0c,0x52,0x52,0x52,0x3e, // 67 g
0x7f,0x08,0x04,0x04,0x78, // 68 h
0x00,0x44,0x7d,0x40,0x00, // 69 i
0x20,0x40,0x44,0x3d,0x00, // 6a j
0x7f,0x10,0x28,0x44,0x00, // 6b k
0x00,0x41,0x7f,0x40,0x00, // 6c l
0x7c,0x04,0x18,0x04,0x78, // 6d m
0x7c,0x08,0x04,0x04,0x78, // 6e n
0x38,0x44,0x44,0x44,0x38, // 6f o
0x7c,0x14,0x14,0x14,0x08, // 70 p
0x08,0x14,0x14,0x18,0x7c, // 71 q
0x7c,0x08,0x04,0x04,0x08, // 72 r
0x48,0x54,0x54,0x54,0x20, // 73 s
0x04,0x3f,0x44,0x40,0x20, // 74 t
0x3c,0x40,0x40,0x20,0x7c, // 75 u
0x1c,0x20,0x40,0x20,0x1c, // 76 v
0x3c,0x40,0x30,0x40,0x3c, // 77 w
0x44,0x28,0x10,0x28,0x44, // 78 x
0x0c,0x50,0x50,0x50,0x3c, // 79 y
0x44,0x64,0x54,0x4c,0x44, // 7a z
0x00,0x08,0x36,0x41,0x00, // 7b {
0x00,0x00,0x7f,0x00,0x00, // 7c |
0x00,0x41,0x36,0x08,0x00, // 7d }
0x10,0x08,0x08,0x10,0x08, // 7e ~
0x06,0x09,0x09,0x06,0x00}; // 7f
 
 
 
 
#define ASCII_TABLE_DEF
/Designs/GPSnavigator/SW/GPS/default/GPS.hex
0,0 → 1,1229
:100000000C947E010C94FB020C949B010C94FC025A
:100010000C949B010C94FD020C949B010C949B018D
:100020000C94FE020C949B010C949B010C947302A3
:100030000C949B010C949B010C949B010C94620208
:100040000C949B010C949B010C949B010C949B01C0
:100050000C94BD020C949B010C949B010C949B018D
:100060000C949B010C949B010C949B010C949B01A0
:100070000C94EB020C949B010C949B010829573FB4
:100080009F2D49CBA5310F76C73493F27E37D00D23
:10009000013AB60B613D2AAAAB3F0000003F800049
:1000A00000004120000042C80000461C40004CBE39
:1000B000BC205A0E1BCA749DC5AE3DCCCCCD3C2392
:1000C000D70A38D1B717322BCC7724E695950A4F4B
:1000D000B11F083B3BD74ABC846E023D2FC1FEBD19
:1000E0009A31743DDA3D83BE117FC73E4CBBE5BEFD
:1000F000AAAA6C3F800000007F0C1E33331E0C7FC9
:100100007F0C1E3F3F1E0C7F0102047F0402017C16
:100110004447457D111F7F415F5F7F000000000065
:1001200000005F00000007000700147F147F142404
:100130002A7F2A122313086462364955225000058B
:10014000030000001C2241000041221C0014083E54
:10015000081408083E080800503000000808080885
:1001600008006060000020100804023E5149453E2E
:1001700000427F400042615149462141454B3118C0
:1001800014127F1027454545393C4A4949300171D1
:100190000905033649494936064949291E003636BC
:1001A00000000056360000081422410014141414F4
:1001B0001400412214080201510906324979413ED6
:1001C0007E1111117E7F494949363E414141227FCE
:1001D0004141221C7F494949417F090909013E41AA
:1001E00049497A7F0808087F00417F41002040414B
:1001F0003F017F081422417F404040407F020C02B3
:100200007F7F0408107F3E4141413E7F0909090676
:100210003E4151215E7F091929464649494931012C
:10022000017F01013F4040403F1F2040201F3F40D1
:1002300038403F6314081463070870080761514988
:100240004543007F41410002040810200041417FE6
:10025000000402010204404040404000010204004A
:1002600020545454787F4844443838444444203817
:100270004444487F3854545418087E0901020C52F3
:1002800052523E7F0804047800447D4000204044E0
:100290003D007F1028440000417F40007C0418048A
:1002A000787C0804047838444444387C14141408D6
:1002B000081414187C7C080404084854545420047E
:1002C0003F4440203C4040207C1C2040201C3C40BF
:1002D00030403C44281028440C5050503C44645456
:1002E0004C44000836410000007F00000041360801
:1002F00000100808100806090906000011241FBE96
:10030000CFEFD0E1DEBFCDBF12E0A0E0B1E0E6E389
:10031000FBE402C005900D92AA37B107D9F716E0A9
:10032000AAE7B2E001C01D92A036B107E1F70E9432
:1003300051110C949A250C94000024982C9A229820
:100340002A9A23982B9A52985A9A549A5C9A089A05
:1003500010980E9A0D9A0C9A0B9A0A9A389A399814
:100360004198579A5F9820E22093690084E08DBB02
:10037000109285001092840080E094E090938900B0
:100380008093880033E0309380008AE1809381007D
:1003900091E090936F002093B60087E08093B100C6
:1003A0009093700083BF8CE090E09093C5008093A1
:1003B000C40028E92093C1009093CD008093CC0025
:1003C0002093C90081E880937C0030937A000895DF
:1003D000861710F499270895861B99270895809110
:1003E0005F048F5F80935F04809140048630E1F169
:1003F000873080F48330C9F0843030F48130A9F044
:10040000823009F05EC03DC0843071F1853009F062
:1004100058C00BC0893041F1893038F08B3021F160
:100420008B3018F08C3009F04CC080915F04803222
:1004300008F447C091E090935F04809140048F5F7F
:1004400080934004809140048D30D9F5909340040E
:1004500080912303982F9F5F9093230364E60E946B
:10046000E80180932303089580915F048F3148F160
:1004700081E080935F04809140048F5F809340040B
:10048000089580915F048E3148F081E080935F048D
:10049000809140048F5F80934004089580915F04B1
:1004A0008D3179F480912303992783709070892B83
:1004B00041F081E080935F04809140048F5F8093DE
:1004C000400408951F920F920FB60F9211248F933C
:1004D00080911D038F5F80931D038F910F900FBE3E
:1004E0000F901F9018951F920F920FB60F92112424
:1004F0002F933F934F935F936F937F938F939F932C
:10050000AF93BF93EF93FF9380913D04885F8093F7
:100510003D0480913D048C33F8F080913D046CE300
:100520000E94E80180933D04809121038F5F8093B6
:100530002103809121038C3378F010922103809164
:100540008A038F5F80938A0380918A03883120F029
:1005500010928A030E94EF01FF91EF91BF91AF913A
:100560009F918F917F916F915F914F913F912F91CB
:100570000F900FBE0F901F9018951F920F920FB6FD
:100580000F9211248F939F93AF93BF93EF93FF9399
:1005900080913E048F5F80933E0480913E048639B3
:1005A00010F010923E0490913E04A6ECB0E08C91C5
:1005B000E7EAF3E0E90FF11D80838C918093CE0090
:1005C000FF91EF91BF91AF919F918F910F900FBECF
:1005D0000F901F9018951F920F920FB60F92112433
:1005E0008F938091CE008093C6008F910F900FBEA5
:1005F0000F901F9018951895189518951895AC019F
:10060000892B61F020E030E0EAEFF0E0CF010197C4
:10061000F1F72F5F3F4F42175307C1F70895982F07
:10062000E0ECF0E0808185FFFDCF9093C600089557
:1006300080911D03815080931D0380915E04882367
:1006400029F080915E04815080935E0480912403A0
:10065000882329F080912403815080932403809182
:100660001E03882329F080911E03815080931E036E
:1006700080913F04882329F080913F04815080932A
:100680003F0480911C03882331F080911C0381502A
:1006900080931C03089583B182958F70809581703B
:1006A0001A9902C0826001C08D7F1B9903C0982FE8
:1006B000986002C0982F977F80915D04981781F011
:1006C00085E080931C0390935D048091FF02882352
:1006D00021F480915D048093FF0288EC80931E03D7
:1006E00008958091FF021092FF0299270895399A88
:1006F000419840980895409A399A419A399841987A
:100700000895399A90E04098882314F4419A01C0E2
:100710004198409A9F5F983011F0880FF4CF40982D
:1007200039984198409A40980895982F399820E038
:1007300080E0409A319981604098273021F0880FFD
:100740002F5F2830B1F7992319F0399A419801C0E9
:1007500039984198409A4098399841989927089536
:100760000E94770380E90E94810381E00E94810357
:1007700081E80E9481030E947B030E94770380E945
:100780000E94810380E00E9481030E947B03089500
:10079000EF92FF920F931F930E94770381E90E94CB
:1007A000810381E00E949503E82EFF24FE2CEE24B5
:1007B00080E00E949503082F0E947B031127C70148
:1007C000802B912B1F910F91FF90EF900895CF9365
:1007D000DF93CDB7DEB723970FB6F894DEBF0FBE19
:1007E000CDBF60E070E080E090E020913D0430916A
:1007F000210340918A03622F732F842F23960FB613
:10080000F894DEBF0FBECDBFDF91CF910895CF9397
:10081000DF93CDB7DEB723970FB6F894DEBF0FBED8
:10082000CDBF60E070E080E090E020915F04309107
:10083000400440912303622F732F842F23960FB619
:10084000F894DEBF0FBECDBFDF91CF9108951F9307
:10085000182F80915D048823A1F080911E038823C6
:1008600009F05DC00E947103823009F058C01092F7
:10087000240388EC80931C030E94710384E690E0BB
:1008800050C08091FF02813041F482E380931C03C9
:100890000E947103109224031F5F8091FF02823037
:1008A00051F45F9B02C05F9801C05F9A82E380931E
:1008B0001C030E9471038091FF02883081F580E063
:1008C00090E89093A00380939F038FEF9FE790930E
:1008D0005604809355045C991DC08091F6028134C2
:1008E000C9F48091E60280933D048091E7028093F1
:1008F00021038091E8028E5F80938A038091E90250
:1009000080935F048091EA02809340048091EB021F
:100910008093230382E380931C030E947103812F41
:1009200099271F9108950F931F93CF93DF93CDB70E
:10093000DEB723970FB6F894DEBF0FBECDBF698335
:100940007A838B83072F162F862F6AE00E94FE245E
:10095000882331F460E070E080E20E94D51705C082
:1009600060E070E0805D0E94D517812F6AE00E94F0
:10097000FE2460E070E0892F805D0E94D517E09131
:100980006004F091610480E680833296F093610404
:10099000E0936004802F6AE00E94FE24882381F0A7
:1009A00060E070E0805D0E94D517802F6AE00E94B1
:1009B000FE2460E070E0892F805D0E94D51715C08D
:1009C000802F6AE00E94FE2460E070E0892F805D45
:1009D0000E94D517E0916004F091610480E6808365
:1009E0003296F0936104E093600423960FB6F89476
:1009F000DEBF0FBECDBFDF91CF911F910F91089544
:100A00000F931F93CF93DF93CDB7DEB723970FB626
:100A1000F894DEBF0FBECDBF69837A838B83072F27
:100A2000182F6AE00E94FE24882331F460E070E011
:100A300080E20E94D51705C060E070E0805D0E94F2
:100A4000D517812F6AE00E94FE2460E070E0892FB4
:100A5000805D0E94D517E0916004F091610486E307
:100A600080833296F0936104E0936004802F6AE003
:100A70000E94FE2460E070E0805D0E94D517802F08
:100A80006AE00E94FE2460E070E0892F805D0E9491
:100A9000D51723960FB6F894DEBF0FBECDBFDF91FA
:100AA000CF911F910F9108950E947C1863E086E01A
:100AB0000E94571821E632E043E050E061E070E028
:100AC00080E091E00E94A7200E94681888EE93E0E1
:100AD0000E94FF0286E08093220308958091240300
:100AE0008823B1F40E947C1863E086E00E945718C6
:100AF00021E632E043E050E061E070E084E091E024
:100B00000E94A7200E94681884E680932403089519
:100B100080912403853090F4109224035F985C9AAE
:100B2000109884E20E94B0171A9B03C088951A9906
:100B3000FDCF0E94B61785E68093220308950F9398
:100B40001F93CF93DF930E94B003109AEAE7F0E07F
:100B5000808180688083808180648083808184FF3D
:100B6000FDCF61E081E00E9457180E94C803009108
:100B7000780010917900892F99279F938F93B8015E
:100B8000882777FD8095982F0E942022112334F426
:100B900020E030E040E857E40E9442219B01AC0194
:100BA00060E070E088EC96E40E94BD2120E030E037
:100BB00040E251E40E94BD219F938F937F936F93F6
:100BC00088E091E09F938F930E94E82084E994E06D
:100BD000909361048093600480917F022DB73EB7AB
:100BE000285F3F4F0FB6F8943EBF0FBE2DBF88233E
:100BF00009F441C0813019F08230A1F46DC028EFB2
:100C000030E06CC0A0916004B0916104F9012F5FE5
:100C10003F4FE491ED93B0936104A09360048F5F24
:100C2000883081F7809160049091610401969093DF
:100C300061048093600480918E02833399F48FE085
:100C400091E026E131E0A0916004B0916104FC01E3
:100C50000196E491ED93B0936104A093600428178A
:100C6000390789F78091600490916104019690930F
:100C7000610480936004C5EAD4E0D0936104C0931A
:100C800060048091800299279F938F9384E191E083
:100C90009F938F930E94E8200F900F900F900F90DA
:100CA0005F9B1EC0CE010C969093610480936004FC
:100CB00086E191E02BE131E0A0916004B091610404
:100CC000FC010196E491ED93B0936104A09360045C
:100CD0002817390729F0F0CF20E031E080E092CFEB
:100CE000DF91CF911F910F9108950F931F93CF9391
:100CF000DF9380912403882309F0DFC084E680938A
:100D000024030E947C180E949F0562E081E00E94FB
:100D100057188091890290918A029F938F938091B6
:100D20008B0290918C029F938F9387E191E09F9328
:100D30008F930E94E82063E081E00E945718809121
:100D40008E02992787FD90959F938F9380918D02B6
:100D5000992787FD90959F938F9380E291E09F93D1
:100D60008F930E94E8208DB79EB70C960FB6F8942B
:100D70009EBF0FBE8DBF80917F02813071F08130A8
:100D800018F08230E1F412C08BE291E09F938F93D0
:100D90000E94E8200F900F901AC081E391E09F938A
:100DA0008F930E94E8200F900F9011C088E391E08C
:100DB0009F938F930E94E8200F900F9008C08EE3BE
:100DC00091E09F938F930E94E8200F900F9064E032
:100DD00081E00E9457188091A90299279F938F93D1
:100DE0008091A80299279F938F938091A7029927BA
:100DF0009F938F9385E491E09F938F930E94E820C7
:100E000065E081E00E945718CFE8D2E08DB79EB729
:100E100008960FB6F8949EBF0FBE8DBF02E511E095
:100E2000899199279F938F931F930F930E94E82096
:100E30008091600490916104029690936104809384
:100E400060040F900F900F900F9092E0C539D90772
:100E500039F766E081E00E94571880919502992742
:100E60009F938F931F930F930E94E82021960F90DA
:100E70000F900F900F9002E511E010C08991992713
:100E80009F938F931F930F930E94E8200F900F90D2
:100E90000F900F9082E0CB39D80769F08091600401
:100EA000909161040296909361048093600492E0B3
:100EB000CB39D90719F70E946818DF91CF911F919C
:100EC0000F9108958F929F92AF92BF92CF92DF922F
:100ED000EF92FF920F931F9380912403882309F0D0
:100EE000F3C084E6809324030E947C180E949F052F
:100EF00062E081E00E945718A090EC02B090ED02F1
:100F0000C090EE02D090EF02C601B5010E9403220C
:100F10007B018C01FF24B701882777FD8095982FEE
:100F20000E9420229B01AC01C601B5010E94412113
:100F300020E030E040E752E40E942E239F938F93FD
:100F40007F936F93FF92EF928091F402992787FD30
:100F500090959F938F930F2EF6E58F2EF1E09F2EA5
:100F6000F02D9F928F920E94E82063E081E00E9422
:100F70005718A090F002B090F102C090F202D09009
:100F8000F302C601B5010E9403227B018C01FF24FC
:100F9000B701882777FD8095982F0E9420229B011A
:100FA000AC01C601B5010E94412120E030E040E7DC
:100FB00052E40E942E239F938F937F936F93FF920F
:100FC000EF928091F502992787FD90959F938F93DB
:100FD0009F928F920E94E82064E081E00E9457185F
:100FE0008091A3029091A402A091A502B091A602C3
:100FF000BF93AF939F938F938091810290918202D0
:10100000A0918302B0918402BF93AF939F938F937B
:1010100083E691E09F938F930E94E82065E081E052
:101020000E94571880919F029091A002A091A10266
:10103000B091A202BF93AF939F938F93809185024B
:1010400090918602A0918702B0918802BF93AF93DE
:101050009F938F9384E791E09F938F930E94E82062
:101060008DB79EB788960FB6F8949EBF0FBE8DBF02
:1010700066E081E00E9457188091F7029091F80293
:10108000A091F902B091FA02BF93AF939F938F930F
:101090008091FB029091FC02A091FD02B091FE02B2
:1010A000BF93AF939F938F9385E891E09F938F9326
:1010B0000E94E8200E9468188DB79EB70A960FB666
:1010C000F8949EBF0FBE8DBF1F910F91FF90EF90C0
:1010D000DF90CF90BF90AF909F908F900895AC011C
:1010E000440F452F441F550B417050709A01220F39
:1010F000331F220F331F240F351F3F932F93292FA8
:10110000332727FD3A952F77307880709078282BF9
:10111000392B3F932F9386E991E09F938F930E9401
:10112000E8208DB79EB706960FB6F8949EBF0FBE07
:101130008DBF0895EF92FF920F931F93CF93DF938C
:1011400080913F04882309F01AC184E680933F040C
:101150000E94C803C4E1D3E0909315038093140365
:10116000EE24FF246894E1F8EC0EFD1E0E94E703D4
:1011700060931603F7017183809318038E010B5F50
:101180001F4F0E94070460931903F8017183828343
:101190000E947C1861E081E00E94571881E692E08D
:1011A00090935D0680935C068091140390911503E3
:1011B0000E946F0883E592E090935D0680935C0641
:1011C00061E08BE00E945718809160049091610467
:1011D0000297909361048093600460911603F70175
:1011E0007181809118030E94000562E08BE00E94EB
:1011F0005718809160049091610402979093610464
:101200008093600460911903F801718182810E94CA
:10121000930464E081E00E945718209114033091F8
:10122000150380919F039091A003821793075CF4AC
:101230008FE993E0DC015497FE0174978CE10190F3
:101240000D928150E1F70FE913E080919F03909197
:10125000A0030E946F0864E08BE00E945718809101
:1012600060049091610402979093610480936004FC
:10127000F80135966091A403718182810E949304E4
:1012800063E086E00E94571880EA91E09F938F9375
:101290000E94E82063E08BE00E9457188091600470
:1012A000909161040297909361048093600460912F
:1012B000A103F80173818091A3030E94000566E0F9
:1012C00081E00E9457180F900F90209114033091E5
:1012D00015038091550490915604281739076CF432
:1012E00085E594E0DC01549784E193E0FC01749778
:1012F0008CE101900D928150E1F705E514E08091B9
:101300005504909156040E946F0866E08BE00E949D
:101310005718809160049091610402979093610442
:1013200080936004F801359660915A04718182813E
:101330000E94930465E086E00E94571884EA91E0D9
:101340009F938F930E94E82065E08BE00E945718DE
:10135000809160049091610402979093610480935E
:10136000600460915704F8017381809159040E94D0
:1013700000050E9468180E94B0030F900F90DF9143
:10138000CF911F910F91FF90EF9008950F931F93AE
:1013900080912403882309F043C084E680932403CA
:1013A0000E947C180E949F0563E081E00E9457180C
:1013B0008091FB029091FC02A091FD02B091FE028F
:1013C000BF93AF939F938F9388EA91E09F938F93FE
:1013D00001E612E01F930F930E945C2065E086E017
:1013E0000E9457188091F7029091F802A091F9029B
:1013F000B091FA02BF93AF939F938F9387EB91E0E5
:101400009F938F931F930F930E945C200E946818F4
:101410008DB79EB740960FB6F8949EBF0FBE8DBF96
:101420001F910F910895809124038823A9F584E6E4
:10143000809324030E947C180E949F0562E081E053
:101440000E9457188EEB91E09F938F930E94E820A3
:1014500064E081E00E9457188091FB029091FC02A9
:10146000A091FD02B091FE02BF93AF939F938F9323
:1014700088EA91E09F938F9381E692E09F938F9308
:101480000E945C200E9468188DB79EB70A960FB61E
:10149000F8949EBF0FBE8DBF08956F927F928F927A
:1014A0009F92AF92BF92CF92DF92EF92FF920F93F3
:1014B0001F9380912403882309F099C084E68093C8
:1014C00024030E947C180E949F0562E081E00E9434
:1014D000571884EC91E09F938F930E94E82063E07B
:1014E00081E00E945718A090EC02B090ED02C090ED
:1014F000EE02D090EF02C601B5010E9403227B01EB
:101500008C01FF24B701882777FD8095982F0E94D2
:1015100020229B01AC01C601B5010E94412120E0BF
:1015200030E040E752E40E942E239F938F937F93F5
:101530006F93FF92EF928091F402992787FD909527
:101540009F938F930F2EF6E56F2EF1E07F2EF02DF7
:101550007F926F920F2EF1E68F2EF2E09F2EF02DEC
:101560009F928F920E945C2065E081E00E94571854
:10157000A090F002B090F102C090F202D090F3027D
:10158000C601B5010E9403227B018C01FF24B70133
:10159000882777FD8095982F0E9420229B01AC011F
:1015A000C601B5010E94412120E030E040E752E44D
:1015B0000E942E239F938F937F936F93FF92EF92BE
:1015C0008091F502992787FD90959F938F937F9245
:1015D0006F929F928F920E945C200E9468188DB734
:1015E0009EB74A960FB6F8949EBF0FBE8DBF1F914F
:1015F0000F91FF90EF90DF90CF90BF90AF909F90B2
:101600008F907F906F9008950F931F935C988091B7
:101610002403882309F054C084E6809324030E94A5
:101620007C180E949F0562E081E00E9457188DECB3
:1016300091E09F938F930E94E82063E081E00E94F5
:1016400057188091E60299279F938F938091E70224
:1016500099279F938F938091E802992702969F93F1
:101660008F9389ED91E09F938F9301E612E01F9392
:101670000F930E945C2065E081E00E9457188091E2
:10168000EB0299279F938F938091EA0299279F936A
:101690008F938091E90299279F938F938AEE91E02F
:1016A0009F938F931F930F930E945C200E94681852
:1016B0008DB79EB746960FB6F8949EBF0FBE8DBFEE
:1016C0001F910F9108952F923F924F925F926F92C8
:1016D0007F928F929F92AF92BF92CF92DF92EF92C2
:1016E000FF920F931F93CF93DF93CDB7DEB7289769
:1016F0000FB6F894DEBF0FBECDBF809124038823C0
:1017000009F0FBC084E6809324030E947C180E94A9
:101710009F0563E089E00E9457188091FB02909139
:10172000FC02A091FD02B091FE02BF93AF939F9384
:101730008F938CEF91E09F938F9381E692E09F933C
:101740008F930E945C2065E08AE00E94571882E037
:1017500092E09F938F930E94E8202091F7023091AE
:10176000F8024091F9025091FA0260E070E084EBD7
:1017700093E40E9441215B016C0125E33AEF4EE8BE
:101780005CE30E942E237B018C010E94762320E0E3
:1017900030E04CEA51E40E942E2320E030E048EA99
:1017A00051E40E9442210E94032269837A838B8341
:1017B0009C83C801B7010E94B72120E030E04CE8CB
:1017C00051E40E942E2320E030E048E851E40E94DA
:1017D00042210E9403226D837E838F83988720E0BD
:1017E00030E046E153E4C601B5010E94412125E302
:1017F0003AEF4EE85CE30E942E237B018C010E94AD
:10180000762320E030E04CEA51E40E942E2320E0D1
:1018100030E048EA51E40E9442210E9403221B0169
:101820002C01C801B7010E94B72120E030E04CE84C
:1018300051E40E942E2320E030E048E851E40E9469
:1018400042210E9403223B014C0120E030E046E1AE
:1018500053E4C601B5010E94422125E33AEF4EE868
:101860005CE30E942E237B018C010E94762320E002
:1018700030E04CEA51E40E942E2320E030E048EAB8
:1018800051E40E9442210E9403225B016C01C801C5
:10189000B7010E94B72120E030E04CE851E40E94FB
:1018A0002E2320E030E048E851E40E9442210E94CB
:1018B00003227B018C01262D422D6D8189810E949E
:1018C000BC182E2D4A2D6D8189810E94BC1821E102
:1018D00045E1662D822D0E94BC1821E145E16E2D67
:1018E0008A2D0E94BC180E9468188DB79EB70A9670
:1018F0000FB6F8949EBF0FBE8DBF28960FB6F89412
:10190000DEBF0FBECDBFDF91CF911F910F91FF9032
:10191000EF90DF90CF90BF90AF909F908F907F908F
:101920006F905F904F903F902F9008951F93CF93AB
:10193000DF93EC01809124038823A9F484E680934B
:1019400024030E947C1810E0899160915C067091DC
:101950005D06992787FD90950E947A201F5F1035BC
:1019600099F70E946818DF91CF911F9108952F92E7
:101970003F924F925F926F927F928F929F92AF921F
:10198000BF92CF92DF92EF92FF920F931F93CF936C
:10199000DF93CDB7DEB728970FB6F894DEBF0FBE42
:1019A000CDBF80912403882309F04EC284E6809342
:1019B00024030E947C180E949F0520E030E040E74D
:1019C00052EC6091F0027091F1028091F2029091DC
:1019D000F3020E942E232AE535E049E554E40E94F3
:1019E000422120E030EC47E954E40E942E233B01E1
:1019F0004C0120E030E040E752EC6091EC02709145
:101A0000ED028091EE029091EF020E942E232CE3D2
:101A10003CE947E355E40E94422120E030EC47EEE8
:101A200054E40E942E235B016C01A4019301C401C4
:101A3000B3010E942E237B018C01A6019501C601F2
:101A4000B5010E942E239B01AC01C801B7010E9481
:101A500042210E9489237B018C0163E089E00E947E
:101A6000571820E030E44CE156E4C801B7010E9469
:101A70003D2288230CF050C020E030E04AE754E4D7
:101A8000C801B7010E943D228823BCF41F930F9325
:101A9000FF92EF9287E092E09F938F9381E692E02E
:101AA0009F938F930E945C208DB79EB708960FB6C8
:101AB000F8949EBF0FBE8DBF26C020E030E04AE7FD
:101AC00054E4C801B7010E94BD219F938F937F9377
:101AD0006F938DE092E09F938F9381E692E09F93C6
:101AE0008F930E945C2065E08CE00E9457188BE683
:101AF00090E00E940821EDB7FEB738960FB6F89433
:101B0000FEBF0FBEEDBF65E08DE00E9457188DE669
:101B100090E00E9408216CC020E030E04AE754E4E5
:101B2000C801B7010E94BD217B018C0120E030E09B
:101B30004AE754E40E943D228823C4F520E030E0C7
:101B400048EC52E4C801B7010E943D228823BCF44E
:101B50001F930F93FF92EF9283E192E09F938F93F5
:101B600081E692E09F938F930E945C208DB79EB791
:101B700008960FB6F8949EBF0FBE8DBF2DC01F9361
:101B80000F93FF92EF9287E092E09F938F9381E60D
:101B900092E09F938F930E945C20EDB7FEB738963A
:101BA0000FB6F894FEBF0FBEEDBF16C01F930F9384
:101BB000FF92EF9289E192E09F938F9381E692E00A
:101BC0009F938F930E945C208DB79EB708960FB6A7
:101BD000F8949EBF0FBE8DBF65E08CE00E94571841
:101BE00080E292E09F938F930E94E8200F900F90E5
:101BF00020E030E040E050E0C601B5010E943D2207
:101C0000882351F40F2EFFE6AF2EF2E1BF2EF3E84A
:101C1000CF2EFAE3DF2EF02DA4019301C601B5010A
:101C20000E9484219B01AC016BED7FE089EC9FE376
:101C30000E9441217B018C0120E030E040E050E037
:101C40000E943D22882354F42BED3FE049EC50E400
:101C5000C801B7010E9442217B018C012BED3FE0BE
:101C600049EC50E4C801B7010E944022181654F410
:101C70002BED3FE049EC50E4C801B7010E9441213F
:101C80007B018C0125E33AEF4EE85CE36091F702BB
:101C90007091F8028091F9029091FA020E942E232D
:101CA0009B01AC01C801B7010E9441215B016C019D
:101CB00020E030E040E050E00E943D22882354F4D0
:101CC0002BED3FE049EC50E4C601B5010E944221F2
:101CD0005B016C012BED3FE049EC50E4C601B5011E
:101CE0000E944022181654F42BED3FE049EC50E4DA
:101CF000C601B5010E9441215B016C01C601B5011D
:101D00000E94762320E030E04CEA51E40E942E232A
:101D100020E030E048EA51E40E9442210E94032280
:101D200069837A838B839C83C601B5010E94B721A6
:101D300020E030E04CE851E40E942E2320E030E027
:101D400048E851E40E9442210E9403226D837E8371
:101D50008F83988724E13EEA47E250E4C601B5014B
:101D60000E9441217B018C010E94762320E030E01B
:101D70004CEA51E40E942E2320E030E048EA51E48E
:101D80000E9442210E9403221B012C01C801B701BD
:101D90000E94B72120E030E04CE851E40E942E235D
:101DA00020E030E048E851E40E9442210E940322F2
:101DB0003B014C0124E13EEA47E250E4C601B50193
:101DC0000E9442217B018C010E94762320E030E0BA
:101DD0004CEA51E40E942E2320E030E048EA51E42E
:101DE0000E9442210E9403225B016C01C801B701DD
:101DF0000E94B72120E030E04CE851E40E942E23FD
:101E000020E030E048E851E40E9442210E94032291
:101E10007B018C01262D422D6D8189810E94BC1889
:101E20002E2D4A2D6D8189810E94BC1821E145E14A
:101E3000662D822D0E94BC1821E145E16E2D8A2D70
:101E40000E94BC180E94681828960FB6F894DEBF4E
:101E50000FBECDBFDF91CF911F910F91FF90EF90FB
:101E6000DF90CF90BF90AF909F908F907F906F90BA
:101E70005F904F903F902F9008952F923F924F92F6
:101E80005F926F927F928F929F92AF92BF92CF920A
:101E9000DF92EF92FF920F931F93CF93DF93CDB713
:101EA000DEB724970FB6F894DEBF0FBECDBF80918A
:101EB0002403882309F0DCC184E680932403809105
:101EC0007A02815080937A028F3F09F0D1C183E07A
:101ED00080937A020E947C189091A9029D3070F044
:101EE00083E292E09F938F930E94E8200E946818FB
:101EF00084E180937A020F900F90BAC180917B02A7
:101F00008F5F80937B02891710F010927B0261E053
:101F10008CE00E9457188091A90299279F938F9374
:101F20000F2EF4E1EF2EF1E0FF2EF02DFF92EF9255
:101F30000E94E82062E08CE00E94571880917B02AA
:101F400099270FE712E0FC01EE0FFF1FEE0FFF1FB6
:101F5000E80FF91FE00FF11F83A599279F938F9337
:101F6000FF92EF920E94E82063E08CE00E945718F5
:101F700080917B029927FC01EE0FFF1FEE0FFF1FE0
:101F8000E80FF91FE00FF11F85A596A59F938F938A
:101F9000FF92EF920E94E82064E08CE00E945718C4
:101FA00080917B029927FC01EE0FFF1FEE0FFF1FB0
:101FB000E80FF91FE00FF11F84A599279F938F93D6
:101FC000FF92EF920E94E82065E08CE00E94571893
:101FD00080917B029927FC01EE0FFF1FEE0FFF1F80
:101FE000E80FF91FE00FF11F87A599279F938F93A3
:101FF000FF92EF920E94E82066E08CE00E94571862
:102000002DB73EB72C5E3F4F0FB6F8943EBF0FBEC4
:102010002DBF8091A902882309F410C11A828A81F8
:1020200099279C838B83FC01EE0FFF1FEE0FFF1F90
:10203000E80FF91FE158FD4F14A5612F772767FDC1
:102040007095872F972F0E942022112334F420E0CF
:1020500030E040E853E40E9442219B01AC0160E083
:1020600070E084EB92E40E9441211B012C01EB8182
:10207000FC81EE0FFF1FEE0FFF1F2B813C81E20F53
:10208000F31FE158FD4F05A516A5B801882777FD78
:102090008095982F0E942022112334F420E030E014
:1020A00040E857E40E94422125E33AEF4EE85CE322
:1020B0000E942E235B016C0125EF39E44FE95EE3BA
:1020C000C201B1010E942E237B018C01C601B50122
:1020D0000E9476239B01AC01C801B7010E942E2308
:1020E00020E030E040EF51E40E9442210E940322B0
:1020F0003B014C01698325EA3FE44AE75EE3C20104
:10210000B1010E942E237B018C01C601B5010E9402
:10211000B7219B01AC01C801B7010E942E2320E02A
:1021200030E040EC51E40E9442210E9403227B01F6
:102130008C01A62EEB81FC81EE0FFF1FEE0FFF1F1F
:102140008B819C81E80FF91FE158FD4F87A58823FB
:1021500009F43FC06E2D862D81500E948B186E2D84
:1021600089818F5F0E948B186E2D6150862D0E9491
:102170008B186E2D6F5F862D0E948B1880918002C8
:10218000882359F110E00F2EFFE7EF2EF2E0FF2E2B
:10219000F02D8B819C81880F991F880F991FEB81EF
:1021A000FC818E0F9F1F4C018E0C9F1CD701A10F2D
:1021B000B11DF40193A5FD018089981721F46A2DC2
:1021C00089810E948B181F5F80918002181728F464
:1021D000EDCF6E2D89810E948B1880917B02FA8150
:1021E000F81721F50A2D0E5FE9802EEFE20E0F2E73
:1021F000FEEFFF2EF02DFA0C202F4E2D6F2D8E2D81
:102200000E94BC1819811E5F2F2D412F602F812F36
:102210000E94BC18202F4E2D602F812F0E94BC18C9
:102220002F2D412F6F2D8E2D0E94BC183A813F5FBC
:102230003A838091A902381708F4F1CE20E04CE3EC
:1022400060E080E00E94BC182FE24CE36FE280E087
:102250000E94BC182FE240E060E080E00E94BC18C1
:102260002FE24CE360E08CE30E94BC180E946818E7
:1022700024960FB6F894DEBF0FBECDBFDF91CF918D
:102280001F910F91FF90EF90DF90CF90BF90AF9094
:102290009F908F907F906F905F904F903F902F9086
:1022A00008951F93CF93DF938FE792E090932003DD
:1022B00080931F0380E090E89093A00380939F0396
:1022C0008FEF9FE7909356048093550418E0109386
:1022D00022030E949D010E94B61710923D048FE0D8
:1022E0008093210381E180938A0389E180935F04D5
:1022F00087E0809340041093230383E592E090935A
:102300005D0680935C067894C5E2D3E08091220359
:102310008530A1F1863070F4823031F1833028F4B9
:102320008823C1F08130E9F518C0833009F1843089
:10233000C1F521C0883091F1893028F4863011F13F
:10234000873079F50EC0843601F1853609F1893080
:1023500041F521C00E94040B26C082E08093220335
:1023600022C00E943D0F1FC083E0809322031BC048
:102370000E94620718C00E94750615C086E080930F
:10238000220311C00E949A080EC00E946E050BC065
:102390000E94540508C00E94B70C05C00E94630B40
:1023A00002C010922203809122030E94270480938E
:1023B000220380911D03882331F00E94180380912D
:1023C0001D038823D1F780913E04AE0167EA73E0D4
:1023D0000E945B138430F1F0853030F4823051F08C
:1023E000833009F093CF0EC08530E1F0863009F0DC
:1023F0008DCF20C060911F0370912003CE010E94F9
:10240000091784CF60911F0370912003CE010E94B1
:1024100098167CCF60911F0370912003CE010E941B
:10242000CA1574CF60911F0370912003CE010E94E2
:102430003C146CCF60911F0370912003CE010E9469
:10244000101464CFBF92CF92DF92EF92FF920F935E
:102450001F93CF93DF93CDB7DEB7A3970FB6F89452
:10246000DEBF0FBECDBFB82EDE011496EDE3F2E065
:1024700086E101900D928150E1F7DE015A96EFE678
:10248000F2E08AE001900D928150E1F700E0EE2445
:10249000FF246894E2F8EC0EFD1E0F2EF9E1CF2E1A
:1024A000DD24F02DCC0EDD1EF70111917F01812F6F
:1024B0000E940F03010FEC14FD04B1F78AE20E94A1
:1024C0000F03802F99279F938F9388E392E09F9328
:1024D0008F93CE0101969F938F930E940F21898144
:1024E0000E940F038A810E940F038DE00E940F0358
:1024F0008AE00E940F038DB79EB706960FB6F89438
:102500009EBF0FBE8DBFBB2091F40F2EFAE1EF2EC0
:10251000FF24F02DEC0EFD1E8E010C5D1F4FF70108
:1025200081917F010E940F03E016F106C1F7A39687
:102530000FB6F894DEBF0FBECDBFDF91CF911F91D4
:102540000F91FF90EF90DF90CF90BF900895909102
:102550007E02943009F46CC0953050F4913041F112
:102560009130C8F0923089F1933009F09CC04AC094
:10257000973009F47EC0983038F4953009F465C07E
:10258000963009F090C06EC0983009F47EC0993042
:1025900009F089C081C0873431F481E080937E02E4
:1025A00085E090E0089510927E0286E090E0089524
:1025B000803531F482E080937E0285E090E00895DA
:1025C00010927E0286E090E00895823551F08635C3
:1025D00071F0873491F483E080937E0285E090E08F
:1025E000089584E080937E0285E090E0089585E080
:1025F00080937E0285E090E0089510927E0286E04E
:1026000090E00895873419F0833569F406C086E0B8
:1026100080937E0285E090E0089587E080937E02BB
:1026200085E090E0089510927E0286E090E00895A3
:102630008D3431F488E080937E0285E090E0089547
:1026400010927E0286E090E00895843531F489E0AE
:1026500080937E0285E090E0089510927E0286E0ED
:1026600090E0089510927E02813411F580E090E0B0
:10267000089510927E02813429F08635C9F482E0F3
:1026800090E0089581E090E0089510927E028334F6
:1026900079F483E090E0089510927E02873441F44B
:1026A00084E090E0089510927E0286E090E0089524
:1026B00086E090E00895CF92DF92EF92FF920F9321
:1026C0001F93CF93DF93D82E7B01EA0100917C0208
:1026D0009091790210917D020F2EF6E0CF2EF02D11
:1026E00001C096E0D11609F48AC01F5F163908F0C0
:1026F00010E0F701E10FF11D80819230C9F19330B4
:1027000030F4992371F0913009F072C01DC09430FB
:1027100009F456C0943008F43FC0953009F068C001
:1027200063C0FE01E00FF11D80830F5F8A3249F420
:1027300000937C0210937D02C092790282E090E0C7
:1027400066C0043670F6CECFFE01E00FF11D808327
:102750000F5F8A3249F400937C0210937D02C0928D
:10276000790283E090E053C0043608F0BACFBACFC4
:10277000FE01E00FF11D80830F5F8A3249F4009360
:102780007C0210937D02C092790284E090E03FC009
:10279000043608F0A6CFA6CFFE01E00FF11D80831E
:1027A0000F5F8A3249F400937C0210937D02C0923D
:1027B000790285E090E02BC0043608F092CF92CFEA
:1027C000FE01E00FF11D80830F5F8A3249F4009310
:1027D0007C0210937D02C092790286E090E017C0DF
:1027E000043608F07ECF7ECF0E94A712982F7ACFB2
:1027F000843211F000E076CF00E095E073CF0093D3
:102800007C029093790210937D0281E090E0DF9149
:10281000CF911F910F91FF90EF90DF90CF9008958F
:102820000F931F93CF93DF93FC018B0180818C3238
:10283000F1F4CF010196EC0121960E94CB23F8011F
:10284000E858FF4F608371838283938390E089917E
:102850008C32E9F79F5F9630D0F3CE010E94CB23F4
:10286000F801E458FF4F6083718382839383DF9183
:10287000CF911F910F9108956F927F928F929F92A7
:10288000AF92BF92CF92DF92EF92FF920F931F937E
:10289000CF93DF93FC013B0180818C3209F06BC147
:1028A0009F012F5F3F4F81816AE08602C0011124A2
:1028B000805EF301E759FF4F8083D9011196E9014A
:1028C0002981820F805380839D012F5F3F4FFD013F
:1028D00081818602C0011124805EF301E859FF4F17
:1028E0008083D9011196E9012981820F8053808369
:1028F000AD014F5F5F4FFD0181818602C001112450
:10290000805EF301E959FF4F8083EA012981820F3C
:1029100080538083DA0112968D918C32E9F7F301AE
:10292000E958FF4FED0189918083FD0181818C324F
:1029300009F021C15E010894A11CB11C69817727AF
:1029400067FD709560537040882777FD8095982FBC
:102950000E94202220E030E040E251E40E942E2339
:102960007B018C010F2EFDE6CF2EDD24F02DC60C51
:10297000D71CE601688379838A839B834501089489
:10298000811C911CF5016181772767FD709560536B
:102990007040882777FD8095982F0E9420229B0108
:1029A000AC01C801B7010E9442217B018C01688300
:1029B00079838A839B83E4012196CE010E94CB23F5
:1029C00020E030E040E752E40E94BD219B01AC01D1
:1029D000C801B7010E944221F6016083718382839E
:1029E000938389918C32E9F7F301EB58FF4FDE01B5
:1029F0008D91808389818C3209F0BDC05D0108947E
:102A0000A11CB11CED016981772767FD70956053AA
:102A10007040882777FD8095982F0E94202220E023
:102A200030E048EC52E40E942E237B018C010F2EF3
:102A3000F1E7CF2EDD24F02DC60CD71CF601608304
:102A400071838283938345010894811C911CE50165
:102A50006981772767FD709560537040882777FDFF
:102A60008095982F0E94202220E030E040E251E43F
:102A70000E942E239B01AC01C801B7010E94422194
:102A80007B018C01F60160837183828393835401FF
:102A90000894A11CB11CE4016981772767FD70953A
:102AA00060537040882777FD8095982F0E942022E0
:102AB0009B01AC01C801B7010E9442217B018C013E
:102AC000F6016083718382839383E5012196CE01B1
:102AD0000E94CB2320E030E040E752E40E94BD2179
:102AE0009B01AC01C801B7010E944221F60160833D
:102AF00071838283938389918C32E9F7F301EA58D9
:102B0000FF4F8991808390E089918C32E9F79F5F34
:102B10009330D0F3FE0181913AE08302C001112489
:102B2000805ED301A659BF4F8C932981820F8053B9
:102B30008C93DF01119681818302C0011124805E94
:102B4000F301E559FF4F8083AD014F5F5F4FED010A
:102B50002981820F80538083FA0181818302C00121
:102B60001124805EF301E459FF4F8083EA012A813A
:102B7000820F80538083DF91CF911F910F91FF903F
:102B8000EF90DF90CF90BF90AF909F908F907F900D
:102B90006F900895AF92BF92CF92DF92EF92FF9223
:102BA0000F931F93CF93DF93DC017B018C918C32C9
:102BB00009F0B3C0FD013196ED0189818053EB012D
:102BC00088A7DF01119681818C3209F0A6C0FD0132
:102BD0003196ED018981482F4053EB0149A7EF0160
:102BE000219681818C3209F098C0DE01119689818D
:102BF0002AE08202C0011124805EFB0182A7FD0150
:102C00003196ED012981820F8053EB018AA79F0144
:102C10002F5F3F4F81818C3209F07FC0E9012196FF
:102C2000842F880F880F0F2EFCEFBF2EF02DB80ECB
:102C3000AA24CB2CDD248601000F111F000F111FC9
:102C40000C0D1D1D0E0D1F1DCE010E94F91FF80158
:102C500063A789918C32E9F78601000F111F000FDD
:102C6000111F0C0D1D1D0E0D1F1DCE010E94F91F01
:102C7000F80164A789918C32E9F78601000F111FD2
:102C8000000F111F0C0D1D1D0E0D1F1DCE010E94EA
:102C9000F91FF80176A765A789918C32E9F7888139
:102CA0008C3231F18A3259F4F601EE0FFF1FEE0F2C
:102CB000FF1FEC0DFD1DEE0DFF1D17A62EC086019A
:102CC000000F111F000F111F0C0D1D1D0E0D1F1DDC
:102CD000CE010E94F91FF80167A789918C3299F003
:102CE0008A32D9F089918C3271F08A32B1F0FACF00
:102CF000F601EE0FFF1FEE0FFF1FEC0DFD1DEE0D99
:102D0000FF1D17A62196B394F70182A5B81628F4E3
:102D1000A394F4E0AF1609F08CCFDF91CF911F910F
:102D20000F91FF90EF90DF90CF90BF90AF900895FC
:102D3000DF92EF92FF920F931F93CF93DF93DC010B
:102D40007B018C918C3209F05CC0FD013196ED0164
:102D50008981EB018E87DF01119681818C3209F028
:102D600050C0FD013196ED018981EB018F879F01F4
:102D70002F5F3F4F81818C3209F043C0E9012196DA
:102D80008B01DD2488818C3249F0CE010E94F91F2D
:102D9000F801608B89918C3221F0FCCFF801108A08
:102DA0002196D3940F5F1F4FFCE0DF1659F78E0179
:102DB0000F5F1F4FCE010E94CB23E7016C8F7D8FE9
:102DC0008E8F9F8FF80181918F018C32D9F7EF019F
:102DD0002196CF010E94CB23F70160A371A382A3A8
:102DE00093A389918C32E9F7CE010E94CB23F7019E
:102DF00064A375A386A397A3FE01818131968C32CB
:102E0000E1F7DF91CF911F910F91FF90EF90DF904D
:102E10000895EF92FF920F931F93CF93DF93FC01DE
:102E20007B0180818C3209F070C0319690E08191F5
:102E30008C32E9F79F5F9530D0F3EF018991805391
:102E4000D7018C9381818C3209F05FC0DE0111962D
:102E500089812AE08202C0011124805EE701898312
:102E6000FD013196ED012981820F8053E7018983AD
:102E70009F012F5F3F4F81818C3209F046C0F901DD
:102E8000319681918C32E9F7EF012196CF010E94B2
:102E9000CB23F701628373838483958390E08991C8
:102EA0008C32E9F79F5F9230D0F38E010F5F1F4F96
:102EB000CE010E94CB23E7016E837F8388879987A9
:102EC00090E0F80181918F018C32D9F79F5F9230A9
:102ED000C0F380818C3261F0CF010E94F91FE701BD
:102EE0007B876A87F80181918F018C3221F0FACFBC
:102EF0008F010F5F1F4FD8018C918C3231F0C801C8
:102F00000E94F91FE7017D876C87DF91CF911F91A8
:102F10000F91FF90EF900895AC01892B61F020E0B4
:102F200030E0EAEFF0E0CF010197F1F72F5F3F4F7C
:102F300042175307C1F7089590E01698882314F4B8
:102F4000159A01C01598169A9F5F983011F0880F56
:102F5000F4CF0895149A13980E949C17139A089519
:102F6000149813980E949C17139A0895149A169A0D
:102F7000139A129884E190E00E948C17129A81E2D1
:102F80000E94B01785EC0E94B01781E10E94B01733
:102F900080E20E94B01789E00E94B01788E00E948A
:102FA000B0178CE00E94B0170895CF93DF9325E00F
:102FB0008202C00111249C0125583F4F90E0A0914E
:102FC0006004B0916104F9018491FD018193F09353
:102FD0006104E09360049F5F2F5F3F4F953079F766
:102FE000ED011982CF0101969093610480936004F2
:102FF00080E090E0DF91CF9108950F931F93CF93DE
:10300000DF9325E08202C0011124DC01A558BF4FE7
:1030100000E0C3E0D0E0FD01649110E070E040E02A
:1030200050E0262F332720FF08C0CE01042E02C017
:10303000880F991F0A94E2F7182B24FF08C0CE01CD
:10304000042E02C0880F991F0A94E2F7782B4E5F76
:103050005F4F4830510511F06695E3CFE091600471
:10306000F0916104EC5AFF4F70838091600490915D
:103070006104FC011193F0936104E09360040F5F1D
:103080001196053041F6FC01EB5AFF4F1082E0919A
:103090006004F09161041192F0936104E093600484
:1030A00080E090E0DF91CF911F910F91089594E51A
:1030B000699FB001112496E0899FC0011124680F17
:1030C000791F685F7B4F709361046093600408957B
:1030D000CF93DF9380E40E94B01780E80E94B0177E
:1030E000C2E6D4E089910E94AA1786E0CA35D807C3
:1030F000C9F7DF91CF910895E2E6F4E08AE596E022
:103100001192E817F907E1F782E694E090936104E1
:10311000809360040895482F843568F5603358F52E
:1031200077278FE290E09C01261B370B12F4295F72
:103130003F4F35952795359527953595279584E506
:1031400090E0289FF001299FF00D389FF00D112489
:10315000E40FF11DEE59FB4FCB01809590958770E0
:10316000907021E030E002C0220F331F8A95E2F711
:103170008081822B808308956F927F928F929F929D
:10318000BF92CF92DF92EF92FF920F931F93CF9354
:10319000DF93D82EB62EC42E022F481720F4CD2C44
:1031A000D42E062FB22E0B1508F04BC06D2C7724B1
:1031B0008C2D99277C01E618F708802E99248B2DF9
:1031C0009927EC01C819D909CE15DF05F4F4CD14FF
:1031D00008F47AC01D2D812F9927861997099C0123
:1031E000C29FC001C39F900DD29F900D1124B701C3
:1031F0000E940A253B2D361B632F812F0E948B18BE
:103200001F5FC11608F460C0E6CF102F812F9927E9
:10321000881999099C01E29EC001E39E900DF29EDF
:10322000900D1124BE010E940A25CB01612F3C2D77
:10323000381B832F0E948B181F5FB11608F444C0FF
:10324000E5CF6D2C77248C2D99277C01E618F708A3
:103250008B2C9924802F9927EC01C819D909CE15F8
:10326000DF05D4F4CD1480F11D2D812F9927861907
:1032700097099C01C29FC001C39F900DD29F900DE2
:103280001124B7010E940A256B0D812F0E948B1813
:103290001F5FC116C8F0E9CF1B2D812F9927881910
:1032A00099099C01E29EC001E39E900DF29E900D53
:1032B0001124BE010E940A25CB01612F8D0D0E94B1
:1032C0008B181F5F011748F7DF91CF911F910F9166
:1032D000FF90EF90DF90CF90BF909F908F907F9066
:1032E0006F9008952F923F924F925F926F927F92CC
:1032F0008F929F92AF92BF92CF92DF92EF92FF9206
:103300000F931F93CF93DF93CDB7DEB726970FB6FA
:10331000F894DEBF0FBECDBF5C016A017B01522E67
:10332000180127FF02C0552405C085E2821714F456
:1033300085E2582ED5019896BE83AD8320E030E01B
:1033400040E050E0C701B6010E943D22882354F4BA
:10335000F10180819181826091838083F7FAF094FA
:10336000F7F8F094AE014F5F5F4FC701B6010E94BE
:10337000FE223B014C01E980FA800B811C8120E098
:1033800030E040E050E0C801B7010E943D228823B0
:10339000E9F1CD80DE80442428C02DEC3CEC4CECDF
:1033A0005DE3C801B7010E942E23AE014F5F5F4F5E
:1033B0000E94FE222AE939E941E251E40E942E23CB
:1033C0000E940322605DD6016E936D014394E980F3
:1033D000FA800B811C8120E030E040E050E0C80121
:1033E000B7010E943D22882319F0AC14BD04A8F255
:1033F000750106C0F60181916F01D7018D937D01A2
:10340000ED81FE81CE16DF06A8F329C020E030E072
:1034100040E050E0C401B3010E94402218161CF0A5
:10342000750144241CC0442403C04A943701480158
:1034300020E030E040E251E4C401B3010E942E23B9
:103440007B018C0120E030E040E85FE30E943D22F8
:1034500087FDEBCFE982FA820B831C837501D101D2
:103460004D915C9153FF13C0BDEF4B1684F0242D9A
:10347000332727FD3095852D992787FD9095019657
:103480002817390724F45460F10151834083D10196
:103490008D919C9192FD08C05394052D112707FD35
:1034A00010950A0D1B1D0CC0052D112707FD109549
:1034B0000A0D1B1D842D992787FD9095080F191F54
:1034C0000A151B05D8F4F5014CC020E030E040E2BD
:1034D00051E4C401B3010E942E23AE014F5F5F4F40
:1034E0000E94FE223B014C0169817A818B819C8183
:1034F0000E940322605DD7016D937D010E151F05AB
:1035000028F0ED81FE81EE16FF06F8F28D819E8196
:103510000817190718F0F50117A224C0D8018C91DB
:103520008B5F8C93F80131E318C020E3D8012C9312
:10353000A016B10628F48E918D018F5F8C930DC07B
:10354000D8013C934394D1018D919C9192FF05C089
:10355000AE16BF0608F420833196D8018C918A33C9
:1035600024F71082842D992787FD909526960FB613
:10357000F894DEBF0FBECDBFDF91CF911F910F91A9
:10358000FF90EF90DF90CF90BF90AF909F908F9083
:103590007F906F905F904F903F902F9008952F9263
:1035A0003F924F925F926F927F928F929F92AF92D3
:1035B000BF92CF92DF92EF92FF920F931F93CF9320
:1035C000DF93CDB7DEB7EE970FB6F894DEBF0FBE30
:1035D000CDBFCC24DD2476013C017EAF6DAF5A0116
:1035E0001A821982FC0117821682838181FDF3C33E
:1035F0008FEF9FEF16C409811A8100FFD3C3842D7A
:1036000080538A30D0F4F0E34F1631F4552021F482
:1036100003FD02C0116075C18AE0252D2802C0019A
:103620001124542C580E30ED530E57FE02C04FE7B4
:10363000542E03FDCAC3352CC8C3442D45564CAF88
:10364000433028F0842D8554833008F0FCC0C50138
:10365000049698AF8FABF501C080D180E280F380F3
:1036600003FD02C036E0532E077B1A83098346010F
:103670005701A7019601C701B6010E942A1F88239E
:10368000C1F08EE48D838B8381E48C839E012A5F5D
:103690003F4F3AAF29AF3CAD333008F07AC28B814F
:1036A000805E8B838C81805E8C838D81805E8D8338
:1036B00070C2C701B6010E949125892BE9F089E407
:1036C0008D838EE48C8386E48B8320E030E040E0C1
:1036D00050E0C701B6010E943D2287FD06C0AE0141
:1036E0004A5F5F4F5AAF49AFD6CF8DE28E83CE018E
:1036F00007969AAF89AFCFCFC80192609A8389832A
:10370000E7E44E1609F449C0E41544F0F5E44F1619
:1037100079F026E4421609F042C31DC036E643168E
:10372000D1F047E64416C9F155E6451609F037C30E
:103730008E010F5F1F4F252DB501A401CE010F96FD
:103740000E947219282E8CEF380E15140CF43A943E
:10375000DE011F9615C094609A8389838E010F5FE6
:103760001F4F252DB501A401CE010F960E9472199D
:10377000282E15140CF43A94DE011F96121444F40A
:10378000FD0101900020E9F73197CE2ECA1A02C040
:10379000C52CC394BAAFA9AF7DC1552011F0252D1A
:1037A00001C021E098609A8389838E010F5F1F4FCB
:1037B000B501A401CE010F960E947219282E8981AD
:1037C0009A8192FF1EC0822D850D8150282FA82F2F
:1037D000BB27A7FDB095AC0FBD1F1F9605C08C91F0
:1037E00011972150803331F4622F27FD23C0221519
:1037F000B4F703C3C62E562E5218539400C3C92ED5
:1038000017C0252DE52DFF27E7FDF095EC0FFD1FD7
:103810003F9606C080813197292F2150803379F758
:10382000922F1216BCF3522EC22E222309F4EFC29D
:10383000592EEDC2E22FFF27E7FDF095EC0FFD1F9B
:10384000108A552499CFC8018870907003FF04C076
:10385000552011F421E0522EE9E64E1609F493C0EA
:10386000E4153CF1F3E54F1609F474C0F415ACF01F
:103870002BE24216E1F1241544F030E24316D1F177
:1038800043E2441609F080C23FC05DE24516C1F133
:103890008EE2481609F078C239C093E64916E1F184
:1038A000E4E64E1609F46FC0F8E54F1609F06CC255
:1038B0009FC020E7421609F496C0241544F03CE668
:1038C000431641F14FE6441609F05EC20DC055E7BC
:1038D000451609F48FC0E8E74E1609F489C0F3E7EE
:1038E0004F1609F051C221C028E02BAF83C0006100
:1038F0001A83098389819A8180629A83898365C248
:1039000000681A83098361C20064FBCF08601A83D0
:10391000098352C20460F5CFA5014E5F5F4F58AFD7
:103920004FABF501C0803A9434C1F501C080D1801D
:10393000892B41F0652D772767FD7095C6010E94A0
:10394000342018C0F60101900020E9F73197EC19F6
:10395000EBAF11C0F501C080D180892B41F0652DFE
:10396000772767FD7095C6010E94292003C0C60114
:103970000E9420208BAF95012E5F3F4F38AF2FABB9
:103980003BAD331A06C102FF0BC0A5014C5F5F4F70
:1039900058AF4FABF50160817181828193810EC078
:1039A00095012E5F3F4F38AF2FABF501808191819C
:1039B0009C01B901882777FD8095982F6B017C01C8
:1039C00097FF0BC002601A830983F094E094D094AF
:1039D000C094C11CD11CE11CF11C89819A818F7B90
:1039E0009A83898327C000641A83098398E7492E44
:1039F00030E13BAF29813A8122FF0BC0A5014C5F2A
:103A00005F4F58AF4FABF501608171818281938127
:103A10000CC0A5014E5F5F4F58AF4FABF5018081E1
:103A20009181AC01BA01882799276B017C012F7C19
:103A30003A83298387017601CE0103969AAF89AF35
:103A40009BADA92EBB24CC24DD24C801B701A6015F
:103A500095010E941D256A301CF0640D615201C061
:103A6000605DE9ADFAAD6193FAAFE9AFC801B701A6
:103A7000A60195010E941D2579018A0121153105B4
:103A80004105510511F7CC24DD247601CE010396C2
:103A9000C9ACC81A49815A81CA0182739070892BB6
:103AA00009F03A9446FF07C0FBADF03111F482E013
:103AB00001C081E0381A43FF10C0252D332727FDB0
:103AC00030958C2D99278217930724F0477F5A83CE
:103AD000498303C05C18351801C03C184078517008
:103AE000452B69F4832D06C0B30180E290E00E946B
:103AF0007A20812F182F11501816B4F3312E898196
:103B00009A8181FF04C0B3018DE290E00BC084FF75
:103B100004C0B3018BE290E005C085FF05C0B3018E
:103B200080E290E00E947A2089819A8186FF0FC00E
:103B3000B30180E390E00E947A202BAD203139F46C
:103B4000B301842D992787FD90950E947A20898161
:103B50009A8190FF0DC0832D06C0B30180E390E0F1
:103B60000E947A20812F182F11501816B4F3312E8D
:103B700089819A8183FF0DC0252D06C0B30180E3A2
:103B800090E00E947A20212F122F11501216B4F3C8
:103B9000512E898187FD0DC0832D06C0B30180E2BF
:103BA00090E00E947A20812F182F11501816B4F33C
:103BB000312E33E6431631F4B3018C2D992787FD5E
:103BC0009095BEC043E74416B1F4460156011BADC3
:103BD00009C0F50181915F01B301992787FD909597
:103BE0000E947A201150A8F76401FBADCF0ED11CC2
:103BF0002FEF2BAFB8C033E54316B1F44601860171
:103C0000BBAC08C0F8018491B30199270E947A20C7
:103C10000F5F1F4FBA94FFEFBF16A1F764012BADE2
:103C2000C20ED11CFBAF9FC089819A8191FD03C058
:103C300009AD1AAD91C092FF1DC01214BCF4A9AC1D
:103C4000BAAC122D09C0F50181915F01B30199272A
:103C500087FD90950E947A201150A8F729AD3AADC2
:103C6000220D311D3AAF29AF22240FC0B30180E3EA
:103C700090E009C0E9ADFAAD8191FAAFE9AFB301C7
:103C8000992787FD90950E947A2015142CF4B30192
:103C90008EE290E00E947A2089819A8192FD06C08E
:103CA00017C0B30180E390E00E947A202394822D14
:103CB000815087FF0DC05A94852D8F5F18168CF3A5
:103CC00007C0B301892F992787FD90950E947A201C
:103CD000E9ADFAAD9191FAAFE9AF992329F05A9481
:103CE000852D8F5F18166CF389819A8192FD3BC0F8
:103CF000B301842D992787FD90950E947A202A94FC
:103D000027FE07C0B3018DE290E00E947A20219443
:103D100005C0B3018BE290E00E947A206AE070E077
:103D2000822D992787FD90950E940A256B017C01C1
:103D3000CB01C096B3010E947A20B301C701C0969F
:103D40000E947A2010C0F80182918F01B301992757
:103D500087FD90950E947A20CE01039608171907D7
:103D600091F71AAF09AF898187FF17C0832D06C06D
:103D7000B30180E290E00E947A20812F182F115029
:103D80001816B4F3312E09C0B301842D992787FD8D
:103D900090950E947A20B8AEAFAA1A821982AFA875
:103DA000B8AC13C0F5E24F1649F481E090E09A8375
:103DB00089832AE02BAF3324552407C0B301842D17
:103DC000992787FD90950E947A204DAD5EAD4F5F9B
:103DD0005F4F5EAF4DAFF301838183FF04C0EDAD54
:103DE000FEAD449003C0EDADFEAD4080442009F02F
:103DF00002CCF3018681978114C0C22E5524EC2D8C
:103E0000FF27E7FDF095EC0FFD1F108AB2CCEC2DDB
:103E1000FF27E7FDF095EC0FFD1F108AFEEF4F0E18
:103E200092CCEE960FB6F894DEBF0FBECDBFDF91F9
:103E3000CF911F910F91FF90EF90DF90CF90BF90A7
:103E4000AF909F908F907F906F905F904F903F903A
:103E50002F900895A8E1B0E0E0E3FFE10C944F2536
:103E600069837A838B839C832D833E834F8358871A
:103E7000BE016F5E7F4FCE0101960E945A1FBE01A8
:103E8000675F7F4FCE0105960E945A1F8989823055
:103E900018F481E090E00AC020E030E089858230AB
:103EA00010F0C90103C021E030E0C901E2E06896EA
:103EB0000C946B25FC01DB01208131819281492F1B
:103EC0004F7750E0991F9927991F8381682F660FBC
:103ED000692B881F8827881FFD018183662309F0CD
:103EE00049C0211531054105510509F470C082E82A
:103EF0009FEFFD0193838283220F331F441F551FC1
:103F0000220F331F441F551F220F331F441F551FFD
:103F1000220F331F441F551F220F331F441F551FED
:103F2000220F331F441F551F220F331F441F551FDD
:103F300083E08C932030F0E03F07F0E04F07F0E49F
:103F40005F0790F482E89FEF220F331F441F551F35
:103F50000197203060E0360760E0460760E45607CE
:103F600098F3FD0193838283FD0124833583468387
:103F7000578308956F3F71F1862F99278F5790408F
:103F8000FD019383828383E08C93220F331F441FB0
:103F9000551F220F331F441F551F220F331F441F6D
:103FA000551F220F331F441F551F220F331F441F5D
:103FB000551F220F331F441F551F220F331F441F4D
:103FC000551F50642483358346835783089582E0C8
:103FD0008C930895211531054105510519F484E0AC
:103FE0008C93089544FD02C01C92BECF81E08C9357
:103FF000BBCF1F93FC0199278827BC01E89411913E
:104000001032E9F3193010F01E30C8F31B3251F0B2
:104010001D3249F4689406C00E943F20610F711D53
:10402000811D911D119110531A30B0F33EF49095FB
:104030008095709561957F4F8F4F9F4F1F91089589
:10404000FC0105900020E9F7809590958E0F9F1F49
:104050000895FC010590615070400110D8F78095DB
:1040600090958E0F9F1F0895FC0161507040019044
:104070000110D8F7809590958E0F9F1F0895592FA6
:10408000482F372F262F660F771F881F991F660F1F
:10409000771F881F991F620F731F841F951F660F5C
:1040A000771F881F991F08957AE0979F902D879F0B
:1040B000802D910D11240895CF93DF93CDB7DEB7F6
:1040C00022970FB6F894DEBF0FBECDBFAE01455F9D
:1040D0005F4F5A83498369857A858F8198850E94CD
:1040E000CF1A22960FB6F894DEBF0FBECDBFDF9178
:1040F000CF9108950F931F93CF93DF938C01EB0122
:104100008B81992781FF1BC082FF0DC02E813F81CB
:104110008C819D812817390764F4E881F981019326
:10412000F983E88306C0E885F985802F0995892BF6
:1041300031F48E819F8101969F838E8302C00FEFA1
:104140001FEFC801DF91CF911F910F9108958F92BA
:104150009F92AF92BF92CF92DF92EF92FF920F9316
:104160001F93CF93DF93FC014B015A017901E901C1
:104170008B8181FF1DC08F01CC24DD2413C0F7018A
:1041800020853185B701F8018081F9010995892BD6
:1041900089F40F5F1F4F2196C815D90581F7089440
:1041A000C11CD11CCA14DB0429F0C0E0D0E0F4CF5C
:1041B000CC24DD24C601DF91CF911F910F91FF9098
:1041C000EF90DF90CF90BF90AF909F908F90089529
:1041D000CF93DF93CDB7DEB722970FB6F894DEBF4B
:1041E0000FBECDBFFE01379661917191FA83E983CD
:1041F000AF0180915C0690915D060E94CF1A2296D5
:104200000FB6F894DEBF0FBECDBFDF91CF910895FA
:1042100060915C0670915D060E947A2008950F936C
:104220001F93CF93DF93CDB7DEB760970FB6F894A7
:10423000DEBF0FBECDBF0F89188D86E08E831C8335
:104240000B838FEF9FE798878F83AE01455E5F4FAB
:104250005A834983698D7A8DCE0103960E94CF1AC5
:1042600029853A85020F131FF801108260960FB658
:10427000F894DEBF0FBECDBFDF91CF911F910F919C
:1042800008955058192E8CD101D03CC1BA1762073D
:10429000730784079507B1F188F40EF410940B2E80
:1042A000BA2FA02D062E622F202D072E732F302D12
:1042B000082E842F402D092E952F502DFF27552392
:1042C000B9F0591B49F0573E98F046953795279518
:1042D000A795F0405395C9F776F0BA0F621F731F88
:1042E000841F30F4879577956795B795F04093953F
:1042F00017FA0F2E0895BF1BBB27BA0B620B730B67
:10430000840BF6CFDEF678C1552319F0992351F0CE
:1043100018C09923A1F097FB6BED7FE089EC9FE338
:1043200097F90895552359F02AF46BED7FE089E45D
:1043300090E40895662777278827992708950C9495
:104340009A221F93112797FD116057FD12600E945A
:10435000BD210E94872411FF08C02BED3FE049E4F6
:1043600050E410FD50680E9442211F91089550E4CE
:1043700049EC3FE02BED6ED0A2C012D101D0C2C0FB
:10438000552359F0992369F09F575F57951B33F4D4
:1043900042F4903811F4915805C0CCC091589F3F19
:1043A00009F42AC1BB27112462177307840730F46C
:1043B000660F771F881FBB1F915098F311D00F9283
:1043C0000FD00F920DD0A0E82617370748071B061D
:1043D00009F0A048BA2F602D7F918F910024089595
:1043E000A0E80024621773078407B10528F0621B58
:1043F000730B840BB1090A2A660F771F881FBB1F36
:10440000A69581F7089597FBD7D09F3738F0FEE93E
:10441000F91B982F872F762F6B2F05C0EAC0969532
:10442000879577956795F150D0F73EF490958095F4
:10443000709561957F4F8F4F9F4F0895E89403C00B
:1044400097FB0EF4F3DFB62F672F782F892F9EE9A5
:10445000002458C05F77552319F444230AF06AC03A
:104460002F933F934F935F9388DF55274427C6D000
:104470005F914F913F912F91F1C00ED05EF004C03B
:104480000BD026F001C008D019F020F48FEF08956A
:1044900080E0089581E0089597FB092E052600F835
:1044A000689481D0E89407FC07C0621773078407FB
:1044B000950721F008F400940794989408951F93A9
:1044C0009F7750EC49E43FE02BEDDCDE10E89F776E
:1044D0005FE349EC3FE02BED621773078407950714
:1044E00020F050EC49E4CEDE112751D19068ECE782
:1044F000F0E023D091271F9108959A95BB0F661F76
:10450000771F881F11249923A1F08823B2F79F3FBA
:1045100059F0BB0F48F421F4002011F460FF04C0EF
:104520006F5F7F4F8F4F9F4F881F9795879597F9A4
:1045300008955FC09FEF80EC0895FF92EF92DF92A5
:10454000CF92BF926B017C01B59016D0B590BB2085
:1045500069F09F938F937F936F93B601C7010CD03F
:104560002F913F914F915F910E94BD21BF90CF90BD
:10457000DF90EF90FF900895F9D102C09601A70156
:10458000EF93FF930E942E23FF91EF91EFD1EF93D2
:10459000FF930E944221FF91EF91BA9479F7089519
:1045A000052E092607FA440F551F5F3F79F0AA2709
:1045B000A51708F051E04795880F991F9F3F31F0EC
:1045C000BB27B91708F091E0879508959F919F91B7
:1045D0001124B0CF97FB880F991F9F3F31F0BB2765
:1045E000B91708F091E0879508959F919F91112444
:1045F000A1CF66277727882799270895EBDFCF93E8
:10460000DF93D52FC42F55274427332722279923FB
:10461000D9F09F37C8F0F92F75DF592F482F372F62
:10462000262FF63968F4EFDE0BDFC030CD0721F01E
:1046300069937993899399939058DF91CF9122CE82
:104640009927882777276627C030CD0721F029933F
:10465000399349935993DF91CF9154CFA1DF01D082
:1046600051CF992339F0552329F09F575F57950F64
:1046700013F49AF1C1CF91589F3FE1F3629FA12DAE
:104680000F92BB27639FA00DB11DEE27729FA00D57
:10469000B11DEE1FAF93AA27649FB00DE11D739F5C
:1046A000B00DE11DAA1F6627829FB00DE11DA61F58
:1046B0005527749FE00DA11D551F839FE00DA11D7F
:1046C000561F849FA00D511D852F7A2F6E2F1F908E
:1046D0000F9088231AF4939539F42CCF000C111CF9
:1046E000BB1F661F771F881F012808959F939F7720
:1046F000993358F050E449EC3FE02BEDABDE5FEB33
:1047000049EC3FE02BEDBEDDDADE5F915078952776
:10471000089597FD0FCF992309F40895482F5ADF84
:10472000F92FFF57F5959F1B9F1BFF93EBDEFF9221
:10473000EF92DF92CF92BF92AF929F928F926B01D6
:104740007C01405847953327222740685FE3B60134
:10475000C70149015A010E94BD219401A5010E948F
:1047600042214FEF5FEF0FD19B01AC018216930600
:10477000A406B50661F78F909F90AF90BF90CF9041
:10478000DF90EF90FF905F9125DF950FBBCE9B01EF
:10479000AC010C942E2377276627B3D0C82FD92FCE
:1047A0007F936F939D2E8C2E09910032E9F309308F
:1047B000D9F30637C9F30C30B9F30A30A9F30D3039
:1047C00099F353D070D0EEF139DE17FB97F9C92E6B
:1047D000D82EE72EF62E88270062053651F409916F
:1047E00044D04BD0992319F017FD3DC036C017FDBA
:1047F0008195E2EAF0E0182F9C2D8D2D7E2D6F2DF6
:104800009F779817870776076105D9F01A0D3AF454
:1048100011957896912F9B1997322CF504C0912F02
:104820009B0D9732D4F49C2D112359F0159538F433
:104830009DD0EF93FF9312DFFF91EF91F5CF349668
:10484000F3CFEF91FF91E030EF0711F0819290826A
:10485000ECE0CDB7DEB70C9461259C2D9F678FE708
:104860007FEF6FEFEECFC5DEECCF11270B3219F0E3
:104870000D3211F4106809910895882799270033A3
:104880008CF011F415FF0AC00A3364F41062992306
:1048900029F40E9454200F70800F911D9D2E8C2EA4
:1048A0000991EDCF08956894A4DEBB24BA94AA249C
:1048B0000E3229F416FD24C0106406F11DC0003329
:1048C000FCF019F4E89415FF12C00A33CCF410621E
:1048D0009F3084F4B394E8945527442733272AE083
:1048E0000E94DF240F70600F711D811D911D16FD48
:1048F000AA9402C016FFA3949D2E8C2E0991D8CFA6
:104900000895AA27BB27FF91EF910C9445251F938B
:104910000F930027192F10789F775FE340E86130ED
:1049200071058407950718F000680E94BB24912B3D
:104930006F937F938F939F930E94C723E2EDF0E0E4
:10494000FCDD5F914F913F912F910E942E23002318
:1049500051F02BED3FE049EC5FE300E8902717FDB5
:1049600050680E9442210F911F91089555914591E1
:104970003591259108959B01AC019FE380E877274D
:1049800066270C94BD2126DE992359F0AA27940F9F
:10499000A51F43F032F04FEF50E09417A50714F431
:1049A000B1CD27CE0EF006C000C09FEF80E870E0CA
:1049B00060E008959FE780E870E060E00895629FFE
:1049C000D001739FF001829FE00DF11D649FE00D07
:1049D000F11D929FF00D839FF00D749FF00D659F68
:1049E000F00D9927729FB00DE11DF91F639FB00D67
:1049F000E11DF91FBD01CF0111240895991B79E034
:104A000004C0991F961708F0961B881F7A95C9F75E
:104A10008095089597FB092E07260AD077FD04D0CC
:104A200065D006D000201AF4709561957F4F0895E7
:104A3000F6F7909581959F4F0895A1E21A2EAA1B33
:104A4000BB1BFD010DC0AA1FBB1FEE1FFF1FA2173E
:104A5000B307E407F50720F0A21BB30BE40BF50B3B
:104A6000661F771F881F991F1A9469F760957095C4
:104A7000809590959B01AC01BD01CF0108952F92C7
:104A80003F924F925F926F927F928F929F92AF92DE
:104A9000BF92CF92DF92EF92FF920F931F93CF932B
:104AA000DF93CDB7DEB7CA1BDB0B0FB6F894DEBFC2
:104AB0000FBECDBF09942A88398848885F846E84E8
:104AC0007D848C849B84AA84B984C884DF80EE8032
:104AD000FD800C811B81AA81B981CE0FD11D0FB63B
:104AE000F894DEBF0FBECDBFED010895AA1BBB1B1E
:104AF00051E107C0AA1FBB1FA617B70710F0A61BDE
:104B0000B70B881F991F5A95A9F780959095BC01FE
:104B1000CD0108959F3F59F4803C49F481E09927E5
:104B2000089590688923872386238395B9F388277E
:064B300099270895FFCF54
:104B3600475053004F46460025302E3166562025F5
:104B460032647F00256400643D256420256473007B
:104B560025632073743D25634420006E6F66697873
:104B660000535053666978002044666978006E6F7A
:104B760070726566004753562025642025642025FB
:104B86006400253264002563202533647F252E3496
:104B9600662700616C7425342E30666D20562532EA
:104BA6002E31660067656F25342E30666D204825E8
:104BB600322E31660025332E30666B6D2F68202528
:104BC600332E30667F0025642E253031647F430006
:104BD6006D6178006D696E002020202025332E310E
:104BE60066206B6D2F680025332E30667F0073704C
:104BF600656564006C6F636174696F6E0074696DDE
:104C06006520262064617465002020202532643AE0
:104C1600253032643A253032640020202532642E55
:104C2600253032642E3230253032640025332E3161
:104C360066006B6D2F6800252E31662000252E3309
:104C4600662000252E3266200025352E306620008F
:104C56006B6D006572726F7220766965772073617D
:104C660074656C697465730025303258002450539E
:104C760052463130302C302C343830302C382C31F0
:104C86002C30000000000200000000D517000000D4
:104C9600000000000200000000FD1700000000A058
:0A4CA600A200028F00008FB0B306D9
:00000001FF
/Designs/GPSnavigator/SW/GPS/lcd.c
0,0 → 1,190
//************************************************************************
// lcd /define nSCLK, nSDIN, nDC, nSC, nRESET /
 
//uint8_t init_n5110[9]={0x21,0xc5,0x13,0x20,0x09,0x08,0xc,0x40,0x80};
 
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdio.h>
#include "lcd.h"
#include "ascii_table.h"
 
void delay_ms1(uint16_t time)
{
while(time--) _delay_ms(1);
}
 
void N5110_send(uint8_t data)
{
uint8_t a;
 
for (a=0;a<8;a++)
{
nSCLK_L;
if (data & 0x80) nSDIN_H;
else nSDIN_L;
data <<= 1;
nSCLK_H;
}
}
 
void N5110_send_data(uint8_t data)
{
nDC_H;
nCS_L;
N5110_send(data);
nCS_H;
}
 
void N5110_send_command(uint8_t data)
{
nDC_L;
nCS_L;
N5110_send(data);
nCS_H;
}
 
void LCD_N5110_INIT(void)
{
//uint8_t a;
nDC_H;
nSCLK_H;
nCS_H;
nRESET_L;
delay_ms1(20);
nRESET_H;
 
//mise lcd
//for (a=0;a<9;a++) N5110_send_command(init_n5110[a]);
N5110_send_command(EXTENDED_SET);
N5110_send_command(VOP|0x45); //default 0x45
N5110_send_command(BIAS_1);
N5110_send_command(H_ADDR);
N5110_send_command(DISPLAY_ALL_ON);
//clear_lcd();
//delay_ms1(1000);
N5110_send_command(DISPLAY_BLANK);
//delay_ms1(1000);
N5110_send_command(DISPLAY_NORMAL);
 
/* //mija lcd
//for (a=0;a<9;a++) N5110_send_command(init_n5110[a]);
//N5110_send_command(EXTENDED_SET);
//N5110_send_command(VOP|69); //default 0x45
//N5110_send_command(BIAS_3);
N5110_send_command(H_ADDR);
//N5110_send_command(DISPLAY_ALL_ON);
//clear_lcd();
//delay_ms(1000);
//N5110_send_command(DISPLAY_BLANK);
//delay_ms(1000);
N5110_send_command(DISPLAY_NORMAL);
*/
}
 
//************************************************************************
// buffer lcd
 
uint8_t video_buf[504];
uint8_t *offset_text;
 
int lcd_put(char c, FILE *stream)
{
uint8_t a;
uint16_t pos;
pos = (c - 0x20) * 5;
for(a=0; a<5;a++)
{
*(offset_text++) = pgm_read_byte(&ASCII_TABLE1[pos+a]);
}
*(offset_text++) = 0;
return 0;
}
 
int lcd_put2(char c, FILE *stream)
{
uint8_t a;
uint8_t b;
uint16_t pos;
uint8_t pom;
uint8_t l_text;
uint8_t h_text;
 
pos = (c - 0x20) * 5;
for(a=0; a<5;a++)
{
h_text=0;
l_text=0;
pom = pgm_read_byte(&ASCII_TABLE1[pos+a]);
for (b=0;b<4;b++)
{
if (pom & 0x01) l_text |= 3<<(2*b);
if (pom & 0x10) h_text |= 3<<(2*b);
pom>>=1;
}
*(offset_text+84) = h_text;
*(offset_text++) = l_text;
}
*(offset_text+84) = 0;
*(offset_text++) = 0;
return 0;
}
 
 
void gotoxy(uint8_t x,uint8_t y)
{
offset_text= video_buf + (y-1)*84 + 6*(x-1);
}
 
void lcd_refresh(void)
{
uint16_t a;
uint8_t *point;
 
N5110_send_command(0x40);
N5110_send_command(0x80);
point = video_buf;
for (a=0;a<504;a++) N5110_send_data(*(point++));
}
 
void buffer_clr(void)
{
uint16_t a;
 
for (a=0;a<504;a++) video_buf[a]=0;
offset_text = video_buf;
}
 
//************************************************************************
// graphics
 
void lcd_plot(uint8_t x, uint8_t y)
{
uint8_t *point;
 
if (x>(LCD_WIDTH-1) || y>(LCD_HEIGHT-1)) return;
point = video_buf + LCD_WIDTH*((LCD_HEIGHT-y-1)/8)+x;
*point |= 1<<(7-(y%8));
}
 
void lcd_line(uint8_t x1,uint8_t y1,uint8_t x2, uint8_t y2)
{
uint8_t a;
uint8_t savex,savey;
 
if (x1>x2) {savex=x1;savey=y1;x1=x2;y1=y2;x2=savex;y2=savey;}
if (y1>y2)
{
if ((x2-x1)>(y1-y2))for (a=x1;a<=x2;a++)lcd_plot(a,y1-((y1-y2)*(a-x1)/(x2-x1)));
else for (a=y2;a<=y1;a++)lcd_plot(x2-((x2-x1)*(a-y2)/(y1-y2)),a);
return;
}
if ((x2-x1)>(y2-y1))for (a=x1;a<=x2;a++)lcd_plot(a,y1+((y2-y1)*(a-x1)/(x2-x1)));
else for (a=y1;a<=y2;a++)lcd_plot(x1+((x2-x1)*(a-y1)/(y2-y1)),a);
}
 
/Designs/GPSnavigator/SW/GPS/lcd.h
0,0 → 1,104
/* mija 2008
defines for LCD NOKIA5110 (instruction set)
 
CPU ATMEGA16
fcpu = 1MHz
 
!! define PIN,PORT,DDR for IOpin !!
*/
 
 
#define LCD_WIDTH 84
#define LCD_HEIGHT 48
#define CHAR_WIDTH 6
 
// LCD SW
#define nSCLK PA6
#define nSCLK_PORT PORTA
#define nSCLK_DDR DDRA
 
#define nSDIN PA5
#define nSDIN_PORT PORTA
#define nSDIN_DDR DDRA
 
#define nDC PA4
#define nDC_PORT PORTA
#define nDC_DDR DDRA
 
#define nCS PA3
#define nCS_PORT PORTA
#define nCS_DDR DDRA
 
#define nRESET PA2
#define nRESET_PORT PORTA
#define nRESET_DDR DDRA
 
//void N5110_send(uint8_t data);
//void N5110_send_data(uint8_t data);
void N5110_send_command(uint8_t data);
void LCD_N5110_INIT(void);
int lcd_put(char c, FILE *stream);
int lcd_put2(char c, FILE *stream);
void gotoxy(uint8_t x,uint8_t y);
void lcd_refresh(void);
void buffer_clr(void);
void lcd_plot(uint8_t x, uint8_t y);
void lcd_line(uint8_t x1,uint8_t y1,uint8_t x2, uint8_t y2);
 
//interni
#define nSCLK_H nSCLK_PORT |= _BV(nSCLK)
#define nSCLK_L nSCLK_PORT &= (~(_BV(nSCLK)))
#define nSCLK_INIT nSCLK_DDR |= _BV(nSCLK)
 
#define nSDIN_H nSDIN_PORT |= _BV(nSDIN)
#define nSDIN_L nSDIN_PORT &= (~(_BV(nSDIN)))
#define nSDIN_INIT nSDIN_DDR |= _BV(nSDIN)
 
#define nDC_H nDC_PORT |= _BV(nDC)
#define nDC_L nDC_PORT &= (~(_BV(nDC)))
#define nDC_INIT nDC_DDR |= _BV(nDC)
 
#define nCS_H nCS_PORT |= _BV(nCS)
#define nCS_L nCS_PORT &= (~(_BV(nCS)))
#define nCS_INIT nCS_DDR |= _BV(nCS)
 
#define nRESET_H nRESET_PORT |= _BV(nRESET)
#define nRESET_L nRESET_PORT &= (~(_BV(nRESET)))
#define nRESET_INIT nRESET_DDR |= _BV(nRESET)
 
 
// FUNCTION SET
#define ACTIVE_CHIP 0x20
#define POWER_DOWN 0x24
#define H_ADDR 0x20
#define V_ADDR 0x22
#define BASIC_SET 0x20
#define EXTENDED_SET 0x21
 
// BASIC SET
#define DISPLAY_BLANK 0x08
#define DISPLAY_NORMAL 0x0C
#define DISPLAY_ALL_ON 0x09
#define DISPLAY_INV 0x0D
 
#define Y_SET 0x40 // | Y2..Y0
#define X_SET 0x80 // | X6..X0
 
// EXTENDED SET
#define TEMP_COEF 0x04 // | TC1|TC0
#define TEMP_COEF_0 0x04
#define TEMP_COEF_1 0x05
#define TEMP_COEF_2 0x06
#define TEMP_COEF_3 0x07
 
#define BIAS_0 0x10
#define BIAS_1 0x11
#define BIAS_2 0x12
#define BIAS_3 0x13
#define BIAS_4 0x14
#define BIAS_5 0x15
#define BIAS_6 0x16
#define BIAS_7 0x17
 
#define VOP 0x80 // | Vop6..Vop0
/Designs/GPSnavigator/SW/GPS/nmea_scan.c
0,0 → 1,272
//************************************************************************
// NMEA LOAD FROM rx GPS
 
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include "nmea_scan.h"
#include "gps.h"
 
enum {ID_RX_GGA,ID_RX_GSA,ID_RX_GSV,ID_RX_RMC,ID_RX_VTG,ID_RX_LOAD,ID_RX_FIND};
 
uint8_t nmea_start_load(char data)
{
enum {NM_G,NM_P,NM_GP,NM_GPG,NM_GPR,NM_GPV,NM_GPGG,NM_GPGS,NM_GPRM,NM_GPVT};
static uint8_t ptr = NM_G;
switch (ptr)
{
case NM_G: if (data == 'G') ptr = NM_P; //G
else { ptr = NM_G; return ID_RX_FIND;}
break;
case NM_P: if (data == 'P') ptr = NM_GP; //P
else { ptr = NM_G; return ID_RX_FIND;}
break;
case NM_GP: switch (data) //GPG || GPR || GPV
{
case 'G': ptr=NM_GPG;break;
case 'R': ptr=NM_GPR;break;
case 'V': ptr=NM_GPV;break;
default : ptr = NM_G; return ID_RX_FIND;
}
break;
case NM_GPG: switch(data) //GPGG || GPGS
{
case 'G': ptr=NM_GPGG;break;
case 'S': ptr=NM_GPGS;break;
default : ptr = NM_G; return ID_RX_FIND;
}
break;
case NM_GPR: if (data == 'M') ptr = NM_GPRM; //GPRM
else { ptr = NM_G; return ID_RX_FIND;}
break;
case NM_GPV: if (data == 'T') ptr = NM_GPVT; //GPVT
else { ptr = NM_G; return ID_RX_FIND;}
break;
case NM_GPGG: ptr = NM_G; //GPGGA
if (data == 'A') return ID_RX_GGA;
return ID_RX_FIND;
case NM_GPGS: ptr = NM_G;
switch(data) //GPGG || GPGS
{
case 'A': return ID_RX_GSA;
case 'V': return ID_RX_GSV;
}
return ID_RX_FIND;
case NM_GPRM: ptr = NM_G; //GPRMC
if (data == 'C') return ID_RX_RMC;
return ID_RX_FIND;
case NM_GPVT: ptr = NM_G; //GPVTG
if (data == 'G') return ID_RX_VTG;
return ID_RX_FIND;
default: ptr = NM_G; return ID_RX_FIND;
}
return ID_RX_LOAD;
}
 
uint8_t load_nmea(uint8_t rx_shift, char *rx_buf,char *scan_buf)
{
static uint8_t id_rx_msg = ID_RX_FIND;
static uint8_t rx_now = 0;
static uint8_t ptr = 0;
char data;
 
while (1)
{
if (rx_shift == rx_now) return RETURN_RX;
if(++rx_now >= MAX_RX_BUF) rx_now = 0;
data = *(rx_buf + rx_now);
 
switch (id_rx_msg)
{
case ID_RX_GGA: *(scan_buf+ptr++) = data;
if (data == '*') {id_rx_msg = ID_RX_FIND; return RETURN_GGA;}
if (ptr >= MAX_NMEA_LOAD) id_rx_msg = ID_RX_FIND;
break;
case ID_RX_GSA: *(scan_buf+ptr++) = data;
if (data == '*') {id_rx_msg = ID_RX_FIND; return RETURN_GSA;}
if (ptr >= MAX_NMEA_LOAD) id_rx_msg = ID_RX_FIND;
break;
case ID_RX_GSV: *(scan_buf+ptr++) = data;
if (data == '*') {id_rx_msg = ID_RX_FIND; return RETURN_GSV;}
if (ptr >= MAX_NMEA_LOAD) id_rx_msg = ID_RX_FIND;
break;
case ID_RX_RMC: *(scan_buf+ptr++) = data;
if (data == '*') {id_rx_msg = ID_RX_FIND; return RETURN_RMC;}
if (ptr >= MAX_NMEA_LOAD) id_rx_msg = ID_RX_FIND;
break;
case ID_RX_VTG: *(scan_buf+ptr++) = data;
if (data == '*') {id_rx_msg = ID_RX_FIND;return RETURN_VTG;}
if (ptr >= MAX_NMEA_LOAD) id_rx_msg = ID_RX_FIND;
break;
case ID_RX_LOAD: id_rx_msg = nmea_start_load(data); break;
case ID_RX_FIND:
default: ptr=0;if (data == '$') id_rx_msg = ID_RX_LOAD;
}
}
return 0 ;
}
 
void nmea_gga(char *buf,DATA_GPS *pgps)
{
uint8_t a;
 
if (*(buf++) != ',') return; // ,
for (a=0;a<5;a++) while (*(buf++) != ','); // UTC,lat,N,lot,W,
pgps->fix_position = *(buf++) - 0x30; // fix_position
if (*(buf++) != ',') return; // ,
pgps->satelites_used = 10 * (*(buf++) - 0x30) ; // satelites
pgps->satelites_used += *(buf++)-0x30;
if (*(buf++) != ',') return; // ,
while (*(buf++) != ','); // HDOP,
pgps->altitude = atof(buf++); // atlitude,
for (a=0;a<2;a++) while (*(buf++) != ','); // ,M,
pgps->geoid = atof(buf++); // geoid
for (a=0;a<2;a++) while (*(buf++) != ','); //,M,
if (*buf != ',')
{
pgps->age_diff_corr = atol(buf); // age_dif_corr,
while (*(buf++) != ',');
}
else buf++;
if (*buf != ',') pgps->diff_id = atol(buf); // ID_diff_station
}
 
void nmea_gsa(char *buf,DATA_GPS *pgps)
{
uint8_t a;
 
if (*(buf++) != ',') return; // ,
pgps->mode1 = *(buf++); // mode1
if (*(buf++) != ',') return; // ,
pgps->mode2 = *(buf++); // mode2
if (*(buf++) != ',') return; // ,
for (a=0;a<12;a++)
{
if (*buf != ',')
{
//pgps->satelite_id[a] = 10*(*(buf++) - 0x30);
//pgps->satelite_id[a] += *(buf++)-0x30;
//buf++;
pgps->satelite_id[a] = atol(buf);
while (*(buf++) != ',');
}
else
{
pgps->satelite_id[a] = 0;
buf++;
}
}
pgps->PDOP = atof(buf++);
while (*(buf++) != ',');
pgps->HDOP = atof(buf++);
while (*(buf++) != ',');
pgps->VDOP = atof(buf++);
while (*(buf++) != ',');
}
 
void nmea_gsv(char *buf,DATA_GPS *pgps)
{
uint8_t a,i,b;
 
if (*(buf++) != ',') return; // ,
pgps->gsv_num_msg = (*(buf++) - 0x30); // num of msg
if (*(buf++) != ',') return; //,
pgps->gsv_msg = (*(buf++) - 0x30); // num msg
if (*(buf++) != ',') return; //,
pgps->gsv_satelites_view = 10*(*(buf++) - 0x30); // satelites view
pgps->gsv_satelites_view +=(*(buf++) - 0x30);
if (*(buf++) != ',') return; // ,
a = 4 * (pgps->gsv_msg - 1);
for (i= 0; i<4; i++)
{
/*pgps->satelit_detail[a].id = 10*(*(buf++) - 0x30);
pgps->satelit_detail[a].id += *(buf++) - 0x30;
buf++;
pgps->satelit_detail[a].elevation = 10*(*(buf++) - 0x30);
pgps->satelit_detail[a].elevation += *(buf++) - 0x30;
buf++;
pgps->satelit_detail[a].azimut = 100*(*(buf++) - 0x30);
pgps->satelit_detail[a].azimut += 10*(*(buf++) - 0x30);
pgps->satelit_detail[a].azimut += *(buf++) - 0x30;
buf++;*/
pgps->satelit_detail[a].id = atol(buf);
while (*(buf++) != ',');
pgps->satelit_detail[a].elevation = atol(buf);
while (*(buf++) != ',');
pgps->satelit_detail[a].azimut = atol(buf);
while (*(buf++) != ',');
 
if ((*buf) != ',')
{
if (*(buf) == '*')
{
pgps->satelit_detail[a].SNR =0;
return;
}
//pgps->satelit_detail[a].SNR = 10*(*(buf++) - 0x30);
//pgps->satelit_detail[a].SNR += *(buf++) - 0x30;
pgps->satelit_detail[a].SNR = atol(buf);
b= *(buf++);
while ((b != ',') && (b != '*') ) b=*(buf++);
if (b == '*') return;
}
else
{
pgps->satelit_detail[a].SNR =0;
buf++;
}
if ( ++a >= pgps->gsv_satelites_view ) return;
}
}
 
//$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598, ,*10
void nmea_rmc(char *buf,DATA_GPS *pgps)
{
uint8_t a;
 
if (*(buf++) != ',') return; // ,
pgps->hour = (10* (*(buf++) - 0x30)); //hour
pgps->hour += (*(buf++) - 0x30);
pgps->minute = 10* (*(buf++) - 0x30); //minute
pgps->minute += (*(buf++) - 0x30);
pgps->second = 10* (*(buf++) - 0x30); //second
pgps->second += (*(buf++) - 0x30);
while (*(buf++) != ','); //.xxx
pgps->status = *(buf++);
if (*(buf++) != ',') return; //A,
pgps->latitude =10.0 * (*(buf++) - 0x30);
pgps->latitude += 1.0 * (*(buf++) - 0x30);
pgps->latitude += atof(buf)/60.0;
while (*(buf++) != ','); //latitude,
pgps->ns_indicator = *(buf++); // N/S
if (*(buf++) != ',') return; //,
pgps->longitude = 100.0 * (*(buf++) - 0x30);
pgps->longitude += 10.0 * (*(buf++) - 0x30);
pgps->longitude += 1.0 * (*(buf++) - 0x30);
pgps->longitude += atof(buf)/60.0;
while (*(buf++) != ','); //longitude,
pgps->we_indicator = *(buf++); // E/W
for (a=0;a<3;a++) while (*(buf++) != ','); // ,speed,course,
pgps->day = 10* (*(buf++) - 0x30);
pgps->day += *(buf++) - 0x30; // day
pgps->month = 10* (*(buf++) - 0x30);
pgps->month += *(buf++) - 0x30; // month
pgps->year = 10* (*(buf++) - 0x30);
pgps->year += *(buf) - 0x30; // year
}
 
void nmea_vtg(char *buf,DATA_GPS *pgps)
{
uint8_t a;
 
if (*(buf++) != ',') return; // ,
pgps->course = atof(buf++); // course
for (a=0;a<6;a++) while (*(buf++) != ','); // ,T,course,M,speed,N,
pgps->speed = atof(buf++);
}
 
/Designs/GPSnavigator/SW/GPS/nmea_scan.h
0,0 → 1,23
 
#include "gps.h"
 
#define MAX_GGA_PLAYLOAD 100
#define MAX_GSA_PLAYLOAD 100
#define MAX_GSV_PLAYLOAD 100
#define MAX_RMC_PLAYLOAD 100
#define MAX_VTG_PLAYLOAD 100
 
#define RETURN_RX 1
#define RETURN_GGA 2
#define RETURN_GSA 3
#define RETURN_GSV 4
#define RETURN_RMC 5
#define RETURN_VTG 6
 
 
uint8_t load_nmea(uint8_t rx_shift, char *rx_buf, char *scan_buf);
void nmea_gga(char *buf,DATA_GPS *pgps);
void nmea_gsa(char *buf,DATA_GPS *pgps);
void nmea_gsv(char *buf,DATA_GPS *pgps);
void nmea_rmc(char *buf,DATA_GPS *pgps);
void nmea_vtg(char *buf,DATA_GPS *pgps);