{*
         
          * Test des Moduls:  Smart-GPS
            Bearbeiter: S. Taborek
            Begin: 18.10.2010
            Stand: 20.10.2010
            Version:  2.04
          
         
           Configuration:
              MCU:             ATmega128
              Dev.Board:       BigAVR2
              Oscillator:      External Clock 08.0000 MHz
              Ext. Modules:    SmartGPS extra board
              Devices:         GLCD 128x64, KS108/107 controller (PORTE)
                               LCDmE LCD 2x16 (PORTC)
                               MMC module
          * NOTES:
              - Switches: SW1 Port E off
                          SW3 all off
                          SW4 all off
                          MMC all on 
              - Connect SmartGPS extra board to PORT-E
                          PullUp and PullDown  Port E disabel
                          change Cabel-Connection like this:
                          Smart-GPS       BIGAVR2
                            P0     ----      PE0
                            P1     ----      PE1
                            -                no Connection
                            -                no Connection
                            -                no Connection
                            -                no Connection
                            -                no Connection
                            -                no Connection
                            VCC    ----      VCC
                            GND    ----      GND
                          at GPS-Bort Bit 3 and 7 on
         
              - Data-Out over GLCD
              - Data-Out over LCD
         
              - Data-Archive on MMC
         
         *}
         
         {------------------------------------------------------------------------------}
         
         program Smart_Gps_with_uartA;
         
         {------------------------------------------------------------------------------}
         
          
         
         uses ;
         
          
         
         const pufmax = 485;  // Bufferlen for some Telegrams
               txtmax = 120;  // Bufferlen for one Telegram
         
          
         // Glcd module connections
         var GLCD_DataPort             : byte at PORTA;
             GLCD_DataPort_Direction   : byte at DDRA;
          
         
         var GLCD_CS1                  : sbit at PORTE.B2;
             GLCD_CS2                  : sbit at PORTE.B3;
             GLCD_RS                   : sbit at PORTE.B4;
             GLCD_RW                   : sbit at PORTE.B5;
             GLCD_EN                   : sbit at PORTE.B6;
             GLCD_RST                  : sbit at PORTE.B7;
          
         
         var GLCD_CS1_Direction        : sbit at DDRE.B2;
             GLCD_CS2_Direction        : sbit at DDRE.B3;
             GLCD_RS_Direction         : sbit at DDRE.B4;
             GLCD_RW_Direction         : sbit at DDRE.B5;
             GLCD_EN_Direction         : sbit at DDRE.B6;
             GLCD_RST_Direction        : sbit at DDRE.B7;
         // End Glcd module connections
         
         
         // LCD module connections
         var LCD_RS                    : sbit  at PORTC.B2;
             LCD_EN                    : sbit  at PORTC.B3;
             LCD_D4                    : sbit  at PORTC.B4;
             LCD_D5                    : sbit  at PORTC.B5;
             LCD_D6                    : sbit  at PORTC.B6;
             LCD_D7                    : sbit  at PORTC.B7;
          
             LCD_RS_Direction          : sbit at DDRC.B2;
             LCD_EN_Direction          : sbit at DDRC.B3;
             LCD_D4_Direction          : sbit at DDRC.B4;
             LCD_D5_Direction          : sbit at DDRC.B5;
             LCD_D6_Direction          : sbit at DDRC.B6;
             LCD_D7_Direction          : sbit at DDRC.B7;
         // End LCD module connections
         
         
         var
             Mmc_Chip_Select           : sbit at PORTG1_bit;
             Mmc_Chip_Select_Direction : sbit at DDG1_bit;
             filename                  : string[14];                         // File names
             filename_old              : string[14];                         // File names
             card_ok                   : byte;
             size                      : longint;
             filedate                  : String[10];
             file_contents             : String[txtmax];
             append_ok                 : byte;
          
          
         {------------------------------------------------------------------------------}
          
         Type
         
          
             TGPS_Daten = record             // 0-terminierte Strings!! (len + 1)
                Date                 : String[11];  // aus RMC
                Time                 : String[14]; // aus RMC oder GGA
                Status1              : String[2];  // aus RMC
                P_2D_3D              : String[2];  // aus GSA
                Latitude             : String[14]; // aus RMC oder GGA
                Longitude            : String[15]; // aus RMC oder GGA
                Hight_m              : String[8];  // aus GGA oder RMZ(in Fu?)
                PDOP                 : String[5];  // aus GSA
                HDOP                 : String[5];  // aus GSA
                VDOP                 : String[5];  // aus GSA
                Velocity_kmh         : String[7];  // aus VTG
                Bew_Kurs             : String[8];  // aus RMC
                Kurs                 : String[8];  // aus VTG
                Kurs_magt            : String[8];  // aus VTG
                Missweisung          : String[8];  // aus RMC
                Mess_Qualitaet       : String[3];  // aus GGA
                Mess_Genauik         : String[7];  // aus GSA
                Anz_Satelliten       : String[3];  // aus GGA
                Satellit_PRN         : String[38]; // aus GSA (f¸r 12 Satelliten n1,n2,...)
                DS_Typ_last          : String[13];  // ....
             end;
          
         
         {------------------------------------------------------------------------------}
          
         
         var txt                     : String[txtmax];
             puf1                    : array[pufmax] of byte;
             in_ptr                  : word;
             out_ptr                 : word;
             ready                   : byte;
             changes                 : byte;
             ret_str                 : string[22];
             ref_str                 : string[41];
             vcode                   : byte;
             error                   : byte;
             i_h                     : byte;
             l_h                     : byte;
             DS_Typ                  : byte;
             GPS_DS                  : TGPS_Daten;
             GPS_DS0                 : TGPS_Daten;
             GPS_Date                : String[11];
             GPS_Time                : String[12];
             ltypes                  : String[13];
             delims                  : String[21];
             //-----------------------------------
          
         
         {------------------------------------------------------------------------------}
         
          
         
         {==============================================================================}
         procedure UART_Rd_ISR(); org IVT_ADDR_USART0__RX;
         {==============================================================================}
         begin
           puf1[in_ptr] := UART1_Read();    // GPS-Telegram
           inc(in_ptr);
           if in_ptr > (pufmax) then begin
             in_ptr := 1;
             ready  := 1;                   //
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         function MakeFileName: array[0..19] of char;
         {------------------------------------------------------------------------------}
         begin
           result :=  xxx ;
           if length(filedate) > 5 then begin
             result :=  GP +filedate+ .txt ;
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure WriteToMMCCard;
         {------------------------------------------------------------------------------}
         var l : byte;
         begin
           if StrCmp(GPS_DS.Status1,  A ) <> 0 then exit;
           //
           if (card_ok = 0) then begin
             filename := MakeFileName;                     // use GPS_DS
             if StrCmp(filename, filename_old) > 0 then begin
               if Mmc_Fat_Assign(filename,0xA0) = 0 then begin  // File do not exists
                 Mmc_Fat_Rewrite;                 // To clear file and start with new data
                 filename_old := filename;
                 append_ok := 0;
               end
               else begin
                 if append_ok = 0 then begin
                 //  append_ok := 1;
                   Mmc_Fat_Append();
                 end;          // Prepare file for append
               end;
             end;
             if Mmc_Fat_Assign(filename,0xA0) <> 0 then begin  // File exists
               with GPS_DS do begin
                 ref_str := DS_Typ_last +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_str := GPS_Date +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_str := GPS_Time +#13+#10;
                 l := length(ref_Str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_Str := Latitude +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_Str, l);             // Write data to assigned file
                 //
                 ref_str := Longitude +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_str := Hight_m +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_str := Satellit_PRN +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
                 //
                 ref_str :=  ------------------------------  +#13+#10;
                 l := length(ref_str);
                 Mmc_Fat_Write(ref_str, l);             // Write data to assigned file
               end{with};
             end;
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         function HexToByte(bstr1, bstr2:char):byte;
         {------------------------------------------------------------------------------}
         const hx    : string[17] =  0123456789ABCDEF- ;
         var   t1, t2: word;
               i     : byte;
         begin
           result := 0;
           t1:= 0; t2 := 0;
           for i := 1 to 16 do begin
             if bstr1 = hx[i] then t1 := i ;
             if bstr2 = hx[i] then t2 := i;
           end;
           result := Lo(t1*16 + t2);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         function DS_Verify():byte;
         {------------------------------------------------------------------------------}
         var xorstr : string[8];
             l, i   : byte;
             csxor : byte;
             csref : byte;
         begin
           result := 0;
           l := length(txt);
           if l < 14 then exit;
           csxor := 0;
           for i := 1 to l-6 do begin // between $  and *
             csxor := csxor xor txt[i];
           end;
           csref := HexToByte(txt[l-4], txt[l-3]);
           if csxor = csref then result := 1;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         function DatenTyp():byte;
         {------------------------------------------------------------------------------}
         var hs : String[3];
             i  : byte;
         begin
           result := 0;
           hs :=   ;
           for i := 3 to 5 do begin
             hs := hs + txt[i];
           end;
           if strcmp(hs,  RMC ) = 0 then result := 1; // Datum, Zeit, x, y, z, Kurs und V
           if strcmp(hs,  GGA ) = 0 then result := 3; // Zeit x,y und Hˆhe
           if strcmp(hs,  GSA ) = 0 then result := 4; // Infos zu aktiven Satelliten
           if strcmp(hs,  GSV ) = 0 then result := 5; // Infos zu sichtbaren Satelliten
           if strcmp(hs,  GLL ) = 0 then result := 6; // veraltet
           if strcmp(hs,  BOD ) = 0 then result := 7; // Kurs vom Start
           if strcmp(hs,  VTG ) = 0 then result := 8; // Kurs und Geschwindigkeit
           if strcmp(hs,  RME ) = 0 then result := 9; // gesch‰tzter Fehler x, y in m
           if strcmp(hs,  RMZ ) = 0 then result := 10;// Hˆhe in Fu?
           if strcmp(hs,  RMM ) = 0 then result := 11;// horizontale Datum
           if strcmp(hs,  TXT ) = 0 then result := 12;// horizontale Datum
         end;
         
         
         {------------------------------------------------------------------------------}
         function SearchDelimiter(var anz1 : byte): array[0..19] of char;
         {------------------------------------------------------------------------------}
         // Function is only for search in var txt
         // result : number of delimiters
         // delims :  ,  within DS_GPS
         var i, j, l : byte;
         begin
           anz1 := 0;
           l := length(txt);
           if l < (7) then exit;
           //
           j := 1;
           for i := 1 to l do begin
             if txt[i] =  ,  then begin
               result[j] := i;        // Data begin at (i+1)
               inc(j);
             end;
           end;
           anz1 := j;                 // return-value
           result[0] := anz1;         // length of array
           result[j] := l - 5;        // last delimiter =  *   .  l-5 because txt+#13#10
           result[j + 1] := 0;        // termination
         end;
         
          
         
         {------------------------------------------------------------------------------}
         function StrCopy(dcc : byte): array[0..26] of char;
         {------------------------------------------------------------------------------}
         // Returns var result
         // Parameter dcc = Pointer at delimiter-array
         var i, j, von, bis : byte;
         begin
           result[0] := 0;                            // termination
           if length(txt) < bis then exit;
           von := delims[dcc] + 1;
           bis := delims[dcc + 1] - 1;
           j := 0;
           if ((bis + 1 - von) > 0) then begin
             for i := von to bis do begin
               result[j] := txt[i];
               inc(j);
             end;
           end;
           result[j] := #0;                           // termination
         end;
          
         
         {------------------------------------------------------------------------------}
         procedure GetDataFrom_RMC;    {Typ = 1}
         {------------------------------------------------------------------------------}
         // DS is in txt
         //
         var dc : byte;
         begin
           delims := SearchDelimiter(dc); // for StrCopy
           if dc <> 13 then exit;         // RMC-Constante
           //
           dc := 1;
           GPS_DS.Time := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.Status1 := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.latitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  N  or  S 
           dc := dc + 1;
           GPS_DS.Longitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  E  or  W 
           dc := dc + 1;
           //GPS_DS.Geschwindk_Knt := StrCopy(dc);
           dc := dc + 1;
           GPS_DS.Bew_Kurs := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.Date := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.Missweisung := StrCopy(dc);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GetDataFrom_GLL;            {Typ = 6}
         {------------------------------------------------------------------------------}
         // DS is in txt
         var dc : byte;
         begin
           delims := SearchDelimiter(dc); // for StrCopy
           if dc <> 8 then exit;          // GLL-Constante
           //
           dc := 1;
           GPS_DS.Latitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  N  or  S 
           dc := dc + 1;
           GPS_DS.Longitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  E  or  W 
           dc := dc + 1;
           GPS_DS.Time := StrCopy(dc);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GetDataFrom_GGA;          {Typ = 3}
         {------------------------------------------------------------------------------}
         // DS ist in txt
         var dc : byte;
         begin
           delims := SearchDelimiter(dc); // for StrCopy
           if dc <> 15 then exit;         // GGA-Constante
           //
           dc := 1;
           GPS_DS.Time := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.latitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  N  or  S 
           dc := dc + 1;
           GPS_DS.Longitude := StrCopy(dc);
           //
           dc := dc + 1;
           //  E  or  W 
           dc := dc + 1;
           GPS_DS.Mess_Qualitaet := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.Anz_Satelliten := StrCopy(dc);
           //
           dc := dc + 1;
           //GPS_DS.DHop := StrCopy(dc);
           dc := dc + 1;
           GPS_DS.Hight_m := StrCopy(dc);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GetDataFrom_GSA;           {Typ = 4}
         {------------------------------------------------------------------------------}
         // DS ist in txt
         var dc, d1 : byte;
         begin
           delims := SearchDelimiter(dc); // for StrCopy
           if dc <> 18 then exit;         // GSA-Constante
           //
           dc := 1;
           // Auto-Auswahl 2D oder 3D
           dc := dc + 1;
           GPS_DS.P_2D_3D := StrCopy(dc);
           //
           ref_str :=   ;  // Satellit-numbers
           for d1 := 1 to 12 do begin
             dc := dc + 1;
             ret_str := StrCopy(dc);
             if length(ret_str) > 1 then begin
               ref_str := + ref_str +     + ret_str;  // nn mm oo pp qq ....
             end;
           end;
           LTrim(ref_str);
           GPS_DS.Satellit_PRN := ref_str +    ;    // +     > for LCD-Out
           //
           dc := dc + 1;
           GPS_DS.PDOP := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.HDOP := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.VDOP := StrCopy(dc);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GetDataFrom_VTG;               {Typ = 8}
         {------------------------------------------------------------------------------}
         // DS ist in txt
         var dc : byte;
         begin
           delims := SearchDelimiter(dc); // f¸r StrCopy
           if dc <> 9 then exit;          // VTG-Constante
           //
           dc := 1;
           GPS_DS.Kurs := StrCopy(dc);
           //
           dc := dc + 1;
           GPS_DS.Kurs_magt := StrCopy(dc);
           //
           dc := dc + 1;
           //  M 
           dc := dc + 1;
           // V in Knoten
           dc := dc + 1;
           GPS_DS.Velocity_kmh := StrCopy(dc);
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GPS_DateTimeAdaption;
         {------------------------------------------------------------------------------}
         var i, j: byte;
         begin
            if length(GPS_DS.Time) > 4 then begin
              LTrim(GPS_DS.Time);
              ret_str :=   ;
              j := 0;
              for i := 0 to 5 do begin
                ret_str[j]:= GPS_DS.Time[i];          {hh}
                inc(j);
                if (i = 1)or(i = 3) then begin
                  ret_str[j]:=  : ;
                  inc(j);
                end;
              end;
              ret_str[j] := #00;
              ret_str := ret_str +  .00 ;
              GPS_Time := ret_Str;
            end;
            if length(GPS_DS.Date) > 4 then begin
              ret_str :=   ;
              j := 0;
              for i := 0 to 3 do begin
                ret_str[j]:= GPS_DS.Date[i];          {hh}
                inc(j);
                if (i = 1)or(i = 3) then begin
                  ret_str[j]:=  . ;
                  inc(j);
                end;
              end;
              ret_str[6] :=  2 ;
              ret_str[7] :=  0 ;
              ret_str[8] := GPS_DS.Date[4];
              ret_Str[9] := GPS_DS.Date[5];
              ret_str[10] := #00;
              GPS_Date := ret_Str;
            end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure DS_Out_GLCD(c : byte);
         {------------------------------------------------------------------------------}
         const cp: byte = 1;
               xp : byte = 44;
         // Zeilenl‰nge 21 Zeichen
         // Um Flackern des Display zu minimieren, werden nur ge‰nderte Daten angezeigt
         begin
           if c = 1 then begin
             GPS_DateTimeAdaption;
             if StrCmp(GPS_DS.DS_Typ_last, GPS_DS0.DS_Typ_last) <> 0 then begin
               Glcd_Write_Text(GPS_DS.DS_Typ_last, xp, 0, cp);
               GPS_DS0.DS_Typ_last := GPS_DS.DS_Typ_last;
             end;
             if StrCmp(GPS_DS.Status1, GPS_DS0.Status1) <> 0 then begin
               if StrCmp(GPS_DS.Status1,  A ) = 0 then begin
                 ref_str :=  Active ;
                 filedate := GPS_DS.Date;
               end
               else begin
                 filedate :=  - ;
                 ref_Str :=  Void ;
               end;
               Glcd_Write_Text(ref_Str, xp, 1, cp);
               GPS_DS0.Status1 := GPS_DS.Status1;
             end;
             if StrCmp(GPS_DS.Date, GPS_DS0.Date) <> 0 then begin
               Glcd_Write_Text(GPS_Date, xp, 2, cp);
               GPS_DS0.Date := GPS_DS.Date;
             end;
             if StrCmp(GPS_DS.Time, GPS_DS0.Time) <> 0 then begin
               Glcd_Write_Text(GPS_Time, xp, 3, cp);
               GPS_DS0.Time := GPS_DS.Time;
             end;
             if StrCmp(GPS_DS.Latitude, GPS_DS0.Latitude) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Latitude, xp, 4, cp);
               GPS_DS0.Latitude := GPS_DS.Latitude;
             end;
             if StrCmp(GPS_DS.Longitude, GPS_DS0.Longitude) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Longitude, xp, 5, cp);
               GPS_DS0.Longitude := GPS_DS.Longitude;
             end;
             if StrCmp(GPS_DS.Hight_m, GPS_DS0.Hight_m) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Hight_m, xp, 6, cp);
               GPS_DS0.Hight_m := GPS_DS.Hight_m;
             end;
             if StrCmp(GPS_DS.Anz_Satelliten, GPS_DS0.Anz_Satelliten) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Anz_Satelliten, xp, 7, cp);
               GPS_DS0.Anz_Satelliten := GPS_DS.Anz_Satelliten;
             end;
           end;
           //----------------------------------------------------------
           if c = 2 then begin
             if StrCmp(GPS_DS.PDOP, GPS_DS0.PDOP) <> 0 then begin
               Glcd_Write_Text(GPS_DS.PDOP, xp, 1, cp);
               GPS_DS0.PDOP := GPS_DS.PDOP;
             end;
             if StrCmp(GPS_DS.HDOP, GPS_DS0.HDOP) <> 0 then begin
               Glcd_Write_Text(GPS_DS.HDOP, xp, 2, cp);
               GPS_DS0.HDOP := GPS_DS.HDOP;
             end;
             if StrCmp(GPS_DS.VDOP, GPS_DS0.VDOP) <> 0 then begin
               Glcd_Write_Text(GPS_DS.VDOP, xp, 3, cp);
               GPS_DS0.VDOP := GPS_DS.VDOP;
             end;
             if StrCmp(GPS_DS.Mess_Qualitaet, GPS_DS0.Mess_Qualitaet) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Mess_Qualitaet, xp, 4, cp);
               GPS_DS0.Mess_Qualitaet := GPS_DS.Mess_Qualitaet;
             end;
             if StrCmp(GPS_DS.Bew_Kurs, GPS_DS0.Bew_Kurs) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Bew_Kurs, xp, 5, cp);
               GPS_DS0.Bew_Kurs := GPS_DS.Bew_Kurs;
             end;
             if StrCmp(GPS_DS.Missweisung, GPS_DS0.Missweisung) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Missweisung, xp, 6, cp);
               GPS_DS0.Missweisung := GPS_DS.Missweisung;
             end;
             if StrCmp(GPS_DS.Velocity_kmh, GPS_DS0.Velocity_kmh) <> 0 then begin
               Glcd_Write_Text(GPS_DS.Velocity_kmh, xp, 7, cp);
               GPS_DS0.Velocity_kmh := GPS_DS.Velocity_kmh;
             end;
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure DS_Out_LCD(c : byte);
         {------------------------------------------------------------------------------}
         var str : String[18];
             i, j, sa1, sa2, len2 : byte;
         {Show the number of each visible Satellite}
         begin
           if (c = 2) then begin
             len2 := length(GPS_DS.Satellit_PRN);
             if len2 < 3 then exit;
             if len2 > 15 then begin
               sa2 := (len2 div 3) - 5;
               sa1 := 5;
             end
             else begin
               sa1 := len2 div 3;     // sa: max 5
               sa2 := 0;
             end;
             //----------line1-----------
             str :=  S   ;
             j := 2;
             for i := 0 to (sa1*3) do begin
               str[j] := GPS_DS.Satellit_PRN[i];
               inc(j);
             end;
             str[j] := char(0);
             Lcd_Out(1,1,                   );
             Lcd_Out(1,1,str);
             //----------line2-----------
             if sa2 > 0 then begin     // if more then 5 Satellites
               str :=  S   ;
               j := 2;
               for i := 0 to (sa2*3) do begin
                 str[j] := GPS_DS.Satellit_PRN[i+15];
                 inc(j);
               end;
               str[j] := char(0);
               Lcd_Out(2,1,                   );
               Lcd_Out(2,1,str);
             end;
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure DS_Out_GLCD_Mask(c : byte);
         {------------------------------------------------------------------------------}
         const cp: byte = 1;                       // 0 = color
         // Zeilenl‰nge 21 Zeichen
         begin
           Glcd_Fill(0x00);                        // Clear GLCD
           if c = 1 then begin
               Glcd_Write_Text( DS-Typ:  , 0, 0, cp);  // DS-Types from GPS
               Glcd_Write_Text( Status:  , 0, 1, cp);  // Active or void
               Glcd_Write_Text( Date  :  , 0, 2, cp);  // Date
               Glcd_Write_Text( Time  :  , 0, 3, cp);  // Time UTC
               Glcd_Write_Text( Latit :  , 0, 4, cp);  // Latitude without N or S
               Glcd_Write_Text( Longit:  , 0, 5, cp);  // Longitude without E or W
               Glcd_Write_Text( Hight :  , 0, 6, cp);  // Hight in m
               Glcd_Write_Text( SatCnt:  , 0, 7, cp);  // Count of Satillites
           end;
           if c = 2 then begin
             Glcd_Write_Text( PDOP    :  , 0, 1, cp);  //
             Glcd_Write_Text( HDOP    :  , 0, 2, cp);  //
             Glcd_Write_Text( VDOP    :  , 0, 3, cp);  //
             Glcd_Write_Text( MessQu  :  , 0, 4, cp);  //
             Glcd_Write_Text( BewKurs :  , 0, 5, cp);  //
             Glcd_Write_Text( Missws  :  , 0, 6, cp);  //
             Glcd_Write_Text( Veloci  :  , 0, 7, cp);  //
           end;
         end;
         
          
         
         {------------------------------------------------------------------------------}
         procedure GPS_DS_Reset;
         {------------------------------------------------------------------------------}
         begin
           with GPS_DS do begin
                Date           :=  - ;
                Time           :=  - ;
                Status1        :=  - ;  // aus RMC
                P_2D_3D        :=  - ;
                Latitude       :=  - ; // aus RMC oder GGA
                Longitude      :=  - ; // aus RMC oder GGA
                Hight_m        :=  - ;  // aus GGA oder RMZ(in Fu?)
                PDOP           :=  - ;  // aus GSA
                HDOP           :=  - ;  // aus GSA
                VDOP           :=  - ;  // aus GSA
                Velocity_kmh   :=  - ;  // aus VTG
                Bew_Kurs       :=  - ;  // aus RMC
                Kurs           :=  - ;  // aus VTG
                Missweisung    :=  - ;  // aus RMC
                Mess_Qualitaet :=  - ;  // aus GGA
                Mess_Genauik   :=  - ;  // aus GSA
                Anz_Satelliten :=  - ;  // aus GGA
                Satellit_PRN   :=  - ;  // aus GSA
                DS_Typ_last    :=  - ;
            end;
            with GPS_DS0 do begin
                Date           :=  - ;
                Time           :=  - ;
                Status1        :=  - ;  // aus RMC
                P_2D_3D        :=  - ;
                Latitude       :=  - ; // aus RMC oder GGA
                Longitude      :=  - ; // aus RMC oder GGA
                Hight_m        :=  - ;  // aus GGA oder RMZ(in Fu?)
                PDOP           :=  - ;  // aus GSA
                HDOP           :=  - ;  // aus GSA
                VDOP           :=  - ;  // aus GSA
                Velocity_kmh   :=  - ;  // aus VTG
                Bew_Kurs       :=  - ;  // aus RMC
                Kurs           :=  - ;  // aus VTG
                Missweisung    :=  - ;  // aus RMC
                Mess_Qualitaet :=  - ;  // aus GGA
                Mess_Genauik   :=  - ;  // aus GSA
                Anz_Satelliten :=  - ;  // aus GGA
                Satellit_PRN   :=  - ;  // aus GSA
                DS_Typ_last    :=  - ;
            end;
            ltypes :=   ;
            filename_old :=    ;
         end;
         
          
         
         {==============================================================================}
          
         
         begin
         
           ready := 0;             // 0!
         
           in_ptr := 1;
         
           UART1_Init(9600);       // UART to GPS
         
          
         
           //---------------------------
         
          
         
           SREG_I_bit := 1;        // Enable Global interrupt
         
           //---------------------------------------------------------------------------
         
           Glcd_Init();                            // Initialize GLCD
         
           Glcd_Set_Font(@Font_Glcd_System5x7, 5, 7, 32);
         
           Glcd_Fill(0x00);                        // Clear GLCD
         
           delay_ms(1000);
         
           Glcd_Write_Text( Neustart , 1, 1, 1);
         
           delay_ms(100);
         
           //
         
           Lcd_Init();                        // Initialize LCD
         
           Lcd_Cmd(_LCD_CLEAR);               // Clear display
         
           Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
         
           //-------------------------------------------------
         
           i_h := 0;
         
           repeat
         
             //--- Init the FAT library
         
             SPI1_Init_Advanced(_SPI_MASTER, _SPI_FCY_DIV128, _SPI_CLK_LO_LEADING);
         
             card_ok := Mmc_Init();  // Init with CS line at PORT.B2
         
             card_ok := card_ok or Mmc_Fat_Init();
         
             inc(i_h);
         
             delay_ms(50);
         
           until(card_ok = 0)or(i_h > 3);
         
           //-------------------------------------------------------------------
         
           if card_ok = 0 then ref_str :=  MMCard OK  else ref_Str :=  Card not found ;
         
           delay_ms(400);
         
           Lcd_Out(1,1, GPS Version 2.04 );
         
           Lcd_Out(2,1, ref_str);
         
           delay_ms(400);
         
           GPS_DS_Reset;
         
           DS_Out_GLCD_Mask(1);
         
           //--------------------------LOOP----------------------------------------------
         
           while(TRUE) do begin
         
             if ready =1 then begin                          // set in ISR-UART
         
               RXCIE0_bit := 0;                              // deactivate UART-INT
         
               ready := 2;
         
               out_ptr := 0;                                 //
         
               repeat
         
                 repeat
         
                   inc(out_ptr);
         
                   if out_ptr > (pufmax) then ready := 0;
         
                 until (puf1[out_ptr] = Ord( $ )) or (ready = 0); // search for Start
         
                 txt :=   ;                                  // Textbegin at out_ptr
         
                 //
         
                 if ready = 2 then begin
         
                   repeat
         
                     txt := txt + char(puf1[out_ptr]);        // Buffer to txt
         
                     inc(out_ptr);
         
                     if out_ptr > (pufmax) then ready := 0;
         
                     if length(txt) >= (txtmax-1) then ready := 0;
         
                   until (puf1[out_ptr] = #13) or (ready = 0);
         
                   txt := txt + #13+#10;                      // LF
         
                   vcode := DS_Verify(); // DS in txt
         
                   if vcode = 1 then begin //--------------------------------------------
         
                     changes := 0;
         
                     //-Satztyp--
         
                     DS_Typ := DatenTyp();                    // uses txt
         
                     IntToStr(DS_Typ, ref_str);
         
                     LTrim(ref_str);
         
                     ltypes := ref_str + ltypes;
         
                     ltypes[11] := char(0);
         
                     GPS_DS.DS_Typ_last := ltypes;
         
                     //------------
         
                     case DS_Typ of
         
                       01: begin
         
                              GetDataFrom_RMC;  // DS in txt
         
                              changes := 1;
         
                           end;
         
                       03: begin
         
                             GetDataFrom_GGA;  // DS in txt
         
                             changes := 1;
         
                           end;
         
                       04: begin
         
                             GetDataFrom_GSA;  // DS in txt
         
                             changes := 1;
         
                             DS_Out_LCD(2);    // Write Sat-Numbers
         
                           end;
         
                       06: begin
         
                             GetDataFrom_GLL;  // DS in txt
         
                             changes := 1;
         
                           end;
         
                       08: begin
         
                             GetDataFrom_VTG;  // DS in txt
         
                             changes := 1;
         
                           end;
         
                       10: begin
         
                           //  GetDataFrom_RMZ;  // DS in txt
         
                           end;
         
                       12: begin
         
                           //  GetDataFrom_TXT;  // DS in txt
         
                           end;
         
                     end;
         
                     //---------------------------
         
                     if changes > 0 then begin
         
                       changes := 0;
         
                       DS_Out_GLCD(1);          // Ausgabe des Teil-Satzes
         
                      end;
         
                     //---------------------------
         
                   end{vcode=1}; //
         
                 end{if ready=2};
         
               until ready = 0;        // no more datas
         
               //delay_ms(300);
         
             end{if ready=1};
         
             WriteToMMCCard;             // GPS_DS to MMC
         
             RXCIE0_bit := 1;                       // Enable UART Receiver interrupt
         
           end;
         
           //
         
         end.