/*****************************************************************************
 
                Microchip Memory Disk Drive File System
 
 *****************************************************************************
 FileName:        Demonstration1.c
 Dependencies:    FSIO.h
 Processor:       PIC32
 Compiler:        C32 
 Company:         Microchip Technology, Inc.

 Software License Agreement

 The software supplied herewith by Microchip Technology Incorporated
 (the “Company”) for its PICmicro® Microcontroller is intended and
 supplied to you, the Company’s customer, for use solely and
 exclusively on Microchip PICmicro Microcontroller products. The
 software is owned by the Company and/or its supplier, and is
 protected under applicable copyright laws. All rights are reserved.
 Any use in violation of the foregoing restrictions may subject the
 user to criminal sanctions under applicable laws, as well as to
 civil liability for the breach of the terms and conditions of this
 license.

 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.


   Note:  This file is included to give you a basic demonstration of how the
           functions in this library work.  Prototypes for these functions,
           along with more information about them, can be found in FSIO.h
*****************************************************************************/

//DOM-IGNORE-BEGIN
/********************************************************************
 Change History:
  Rev            Description
  ----           -----------------------
  1.3.0          Initial Revision
  1.3.4          Cleaned up the unnecessary part of main() function.
********************************************************************/
//DOM-IGNORE-END

/*******************************************************************************
//NOTE : DISABLE MACRO "SUPPORT_LFN" IN "FSconfig.h" FILE TO WORK WITH THIS DEMO
         EFFECTIVELY. DISABLING "SUPPORT_LFN" WILL SAVE LOT OF MEMORY FOR THIS
         DEMO.
********************************************************************************/

#include "FSIO.h"
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
#include <sys/attribs.h>

unsigned char step =0;
unsigned char ind = 0;
unsigned char complete=0;
unsigned char message[];
unsigned char ck_a=0;
unsigned char ck_b=0;
unsigned long mode;
unsigned long test;
unsigned char gps_file_created;
unsigned char test_file_created;
unsigned long numEg;  //counter for engine rpm
unsigned long numWh;  //counter for wheel rpm
int butpre1 = 0;  //variable to be set to 1 when button is pressed, debouncing purposes
int butpre2 = 0;  //variable to be set to 1 when button is pressed, debouncing purposes
unsigned char NOFIX[] = {'N','o',' ','F','i','x'};
unsigned char FIX[] = {' ',' ',' ','F','i','x'};
unsigned char RACE[] = {'R','a','c','e'};
unsigned char BUG[] = {'B','U','G'};
unsigned char TEST[] = {'T','e','s','t'};




#if defined (__PIC32MX__)
    #pragma config FPLLMUL  = MUL_20        // PLL Multiplier
    #pragma config FPLLIDIV = DIV_2         // PLL Input Divider
    #pragma config FPLLODIV = DIV_1         // PLL Output Divider
    #pragma config FPBDIV   = DIV_2         // Peripheral Clock divisor                                 ****cahnged from DIV_2
    #pragma config FWDTEN   = OFF           // Watchdog Timer
    #pragma config WDTPS    = PS1           // Watchdog Timer Postscale
    #pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
    #pragma config OSCIOFNC = OFF           // CLKO Enable
    #pragma config POSCMOD  = OFF            // Primary Oscillator                                      ****changed from HS
    #pragma config IESO     = OFF           // Internal/External Switch-over
    #pragma config FSOSCEN  = OFF           // Secondary Oscillator Enable (KLO was off)
    #pragma config FNOSC    = FRCPLL        // Oscillator Selection                                     *****changed from PRIPLL
    #pragma config CP       = OFF           // Code Protect
    #pragma config BWP      = OFF           // Boot Flash Write Protect
    #pragma config PWP      = OFF           // Program Flash Write Protect
    #pragma config ICESEL   = ICS_PGx1      // ICE/ICD Comm Channel Select                              ****changed from ICS_PGx2
    #pragma config DEBUG    = ON            // Background Debugger Enable
#endif

void serial_init1(unsigned long value)
{
    U3MODEbits.ON=1;
    U3MODEbits.BRGH=1;
    U3STAbits.UTXEN=1;
    U3STAbits.URXEN=1;
    unsigned long Fpb = 40000000;
    unsigned long num = Fpb/(4*value)-1;
    U3BRG = num;
}

void serial_init6(unsigned long value)
{
    //U6MODEbits.ON=1;
    //U6MODEbits.BRGH=1;
    //U6STAbits.UTXEN=1;
    //U6STAbits.URXEN=1;
    //unsigned long Fpb = 10000000;
    //unsigned long num2 = 4*Fpb/(4*value)-1;
    //U6BRG = num2;
}

unsigned char getu1(void)
{
    while(1)
    {
        if (U3STAbits.URXDA == 1)
        {
            char letter = U3RXREG;
            return letter;
        }
    }
}

unsigned char getu6(void)
{
    //while(1)
    //{
    //    if (U6STAbits.URXDA == 1)
    //    {
    //        char letter3 = U6RXREG;
    //        return letter3;
    //    }
    //}
}

void putu1(unsigned char letter4)
{
    while(1)
    {
        if (U3STAbits.UTXBF == 0)
        {
            U3TXREG = letter4;
            return;
        }
    }
}

void putu6(unsigned char letter2)
{
   // while(1)
   // {
   //     if (U6STAbits.UTXBF == 0)
    //    {
   //         U6TXREG = letter2;
    //        return;
   //     }
   // }
}

void enableInter(void)
{
    INTCONbits.MVEC=1;
    
    IEC0bits.INT1IE=0;
    IEC0bits.INT2IE=0;
    IEC0bits.INT3IE=0;
    IEC0bits.INT4IE=0;

    IFS0bits.INT1IF=0;
    IFS0bits.INT2IF=0;
    IFS0bits.INT3IF=0;
    IFS0bits.INT4IF=0;

    IPC1bits.INT1IP = 7;
    IPC2bits.INT2IP = 6;
    IPC3bits.INT3IP = 4;
    IPC4bits.INT4IP = 3;

    INTCONbits.INT1EP=1;
    INTCONbits.INT2EP=1;
    INTCONbits.INT3EP=1;
    INTCONbits.INT4EP=1;

    IEC0bits.INT1IE=1;
    IEC0bits.INT2IE=1;
    IEC0bits.INT3IE=1;
    IEC0bits.INT4IE=1;

    IEC1bits.U3RXIE=1;
    IFS0bits.INT3IF=0;
    U3STAbits.URXISEL1=0;
    IPC7bits.U3IP=111;
    U3STAbits.URXISEL0=0;
    IFS1bits.U3RXIF=0;
    asm("ei");                              //clear interrupt flag
}

void spiInit()
{
   SPI4BRG = (40/(2*2))-1;

   TRISBbits.TRISB12=0;  //CS output
   TRISBbits.TRISB14=0; //CLK output
   TRISFbits.TRISF4=1;  //MISO input
   TRISFbits.TRISF5=0;  //MOSI output

   LATBbits.LATB12=1;    //CS high

   unsigned int left;
   left = SPI4BUF;

   SPI4STATCLR=0x40;
   SPI4CONbits.ON=1;
   SPI4CONbits.CKE=1;
   SPI4CONbits.CKP=0;
   SPI4CONbits.SMP=1;
   SPI4CONbits.MSTEN=1;
   SPI4CONbits.SRXISEL=00;
}

unsigned char swap(unsigned char info)
{
    SPI4BUF=info;
    //while(!SPI4STATbits.SPIRBF);
    while(!SPILCD_INT);
    return SPI4BUF;
    SPILCD_INT=0;
}

void sndCMD (unsigned char comd[], unsigned char reply[])
{
    int n; int i;


    //send zero
    swap(0xFF);
    //send six command bytes
    for (n=0;n<6;n++)
    {
        swap(comd[n]);
    }
    //wait until reply is heard

        
    do
    {
        reply[0] = swap(0xFF);
    } while (reply[0]==0xFF);

    //read reply
    for (i=1;i<6;i++)
    {
        reply[i] = swap(0xFF);
    }

    return;
}

void sdInit ()
{

    spiInit();
    int n;

    unsigned char comd[6];
    comd[0]=0x40;
    comd[1]=0x00;
    comd[2]=0x00;
    comd[3]=0x00;
    comd[4]=0x00;
    comd[5]=0x95;
    unsigned char reply[6];
    reply[0]=0x00;
    reply[1]=0x00;
    reply[2]=0x00;
    reply[3]=0x00;
    reply[4]=0x00;
    reply[5]=0x00;

    //wait
    for (n=0;n<25;n++)
    {
        swap(0xFF);
    }

    //set CS low
    LATBbits.LATB12=0;


    //wait
    for (n=0;n<25;n++)
    {
        swap(0xFF);
    }

    //send CMD0
    sndCMD(comd,reply);

    //send CMD8
    comd[0]=0x48;
    comd[1]=0x00;
    comd[2]=0x00;
    comd[3]=0x01;
    comd[4]=0xAA;
    comd[5]=0x87;
    sndCMD(comd,reply);

    do
    {
        //CMD55 inform SD of application specific command
        comd[0]=0x77;
        comd[1]=0x00;
        comd[2]=0x00;
        comd[3]=0x00;
        comd[4]=0x00;
        comd[5]=0x95;
        sndCMD(comd,reply);

        //ACMD41 to check if SD is out of idle state
        comd[0]=0x69;
        comd[1]=0x40;
        comd[2]=0x00;
        comd[3]=0x00;
        comd[4]=0x00;
        comd[5]=0x95;
        sndCMD(comd,reply);

    } while (reply[0]!=0x00);
}

void sdstuff ()
{
   FSFILE * pointer;
   char path[30];
   char count = 30;
   char * pointer2;
   SearchRec rec;
   unsigned char attributes;
   unsigned char size = 0, i;
   // Turn on the interrupts
//INTEnableSystemMultiVectoredInt();
//SYSTEMConfigPerformance(GetSystemClock());
//mOSCSetPBDIV(OSC_PB_DIV_2);
                //1) Initialize the RTCC
//RtccInit();
                //while(RtccGetClkStat()!=RTCC_CLK_ON);        // wait for the SOSC to be actually running and RTCC to have its clock source
//DelayMs(1000);                                           // could wait here at most 32ms
//RtccOpen(0x10073000, 0x07011602, 0);

                //2) Initialize SD Card
    sdInit();

   SPI4BRG = 9;

   //TRISBbits.TRISB10=0;     //WE
   //PORTBbits.RB10=1;        //WE
   //TRISBbits.TRISB11=1;     //CD
   //PORTBbits.RB11=1;        //CD

   TRISBbits.TRISB12=0;     //CS output
   TRISBbits.TRISB14=0;     //CLK output
   TRISFbits.TRISF4=1;      //MISO input
   TRISFbits.TRISF5=0;      //MOSI output

   SD_CS=1;

   unsigned int empty_buff;
   empty_buff = SPI4BUF;

   SPI4CONbits.CKP = 0;
   SPI4CONbits.CKE = 1;
   SPI4CONbits.SMP=1;
   SPI4CONbits.MSTEN=1;

   SPI4CONbits.ON=1;


   /**

    int n;

    unsigned char comd[6];
    comd[0]=0x40;
    comd[1]=0x00;
    comd[2]=0x00;
    comd[3]=0x00;
    comd[4]=0x00;
    comd[5]=0x95;
    unsigned char reply[6];
    reply[0]=0x00;
    reply[1]=0x00;
    reply[2]=0x00;
    reply[3]=0x00;
    reply[4]=0x00;
    reply[5]=0x00;

    //wait
    for (n=0;n<25;n++)
    {
        swap(0xFF);
    }


    //set CS low
    SD_CS=0;

    //wait
    for (n=0;n<25;n++)
    {
        swap(0xFF);
    }

    //send CMD0

    sndCMD(comd,reply);



    //send CMD8
    comd[0]=0x48;
    comd[1]=0x00;
    comd[2]=0x00;
    comd[3]=0x01;
    comd[4]=0xAA;
    comd[5]=0x87;
    sndCMD(comd,reply);

    do
    {
        //CMD55 inform SD of application specific command
        comd[0]=0x77;
        comd[1]=0x00;
        comd[2]=0x00;
        comd[3]=0x00;
        comd[4]=0x00;
        comd[5]=0x95;
        sndCMD(comd,reply);

        //ACMD41 to check if SD is out of idle state
        comd[0]=0x69;
        comd[1]=0x40;
        comd[2]=0x00;
        comd[3]=0x00;
        comd[4]=0x00;
        comd[5]=0x95;
        sndCMD(comd,reply);

    } while (reply[0]!=0x00);
    
         
                //3) Media Detect
                //while(!MDD_SDSPI_MediaDetect());                  // Initialize the library
                //4) FSInit
//while (!FSInit());

    */
SD_WE_TRIS=0;
SD_WE=0x00;
}

void sd_ammend (char toSD[])
{
#ifdef ALLOW_WRITES
   char newline[]="\r";
   FSFILE * pointer;
   int length2 = strlen(toSD);
   pointer = FSfopen("GPSDATA.csv","a");
   FSfwrite(toSD,1,length2,pointer);
   FSfclose(pointer);
#endif 
}

void sd_fammend (unsigned long tester)
{
#ifdef ALLOW_WRITES
   char newline[]="\r";
   FSFILE * pointer;
   pointer = FSfopen("GPSDATA.csv","a");
   FSfprintf(pointer,"%1d",tester);
   FSfclose(pointer);
#endif
}

void lap_ammend (char toSD[])
{
#ifdef ALLOW_WRITES
   char newline[]="\r";
   FSFILE * pointer;
   int length2 = strlen(toSD);
   pointer = FSfopen("LAPTIMES.csv","a");
   FSfwrite(toSD,1,length2,pointer);
   FSfclose(pointer);
#endif
}

void lap_fammend (unsigned long tester)
{
#ifdef ALLOW_WRITES
   char newline[]="\r";
   FSFILE * pointer;
   pointer = FSfopen("LAPTIMES.csv","a");
   FSfprintf(pointer,"%1d",tester);
   FSfclose(pointer);
#endif
}

void sd_try(float try)
{
   #ifdef ALLOW_WRITES
   FSFILE * pointer;
   pointer = FSfopen("GPSDATA.csv","a");
   FSfprintf(pointer,"%.3f",try);
   FSfclose(pointer);
#endif
}

void sd_format (unsigned long UTCtime)
{
#ifdef ALLOW_WRITES
   char newline[]="\r";
   char topline[]="Time (sec),Speed ((m/s)*10^2),Latitude ((deg)*10^6),Longitude ((deg)*10^6),Engine rpm,Wheel rpm";
   char lapline[]="Lap,Lap Time (sec)\r";
   FSFILE * pointer1;
   FSFILE * pointer2;

   int length1 = strlen(topline);
   int length2 = strlen(lapline);

   if (gps_file_created==0)
   {
       pointer1 = FSfopen("GPSDATA.csv","w");
       FSfwrite(topline,1,length1,pointer1);
       FSfclose(pointer1);

       pointer2 = FSfopen("LAPTIMES.csv","w");
       FSfwrite(lapline,1,length2,pointer2);
       FSfclose(pointer2);
       gps_file_created=1;
   }
   else
   {
       sd_ammend("New Data Set,UTC Time:,");
       sd_fammend(UTCtime);
       sd_ammend("\r");

       sd_ammend("New Data Set,UTC Time:,");
       sd_fammend(UTCtime);
       sd_ammend("\r");
   }
#endif
}

void __ISR(_UART_3_VECTOR, IPL7AUTO) u1interrupt(void)
{
    
    unsigned char disp1;
    disp1=getu1();                                   //get input from UART1 buffer
    //putu6(disp1);                                                         //send to UART6 for terminal
    IFS1bits.U3RXIF=0;                               //clear interrupt flag



    switch (step)
    {
        case 0:

            if (disp1==0xD0)
            {
                step=1;
            }
            else
            {
                step=0;
            }
            break;
        case 1:
            if (disp1==0xDD)
            {
                step=2;
            }
            else
            {
                step=0;
            }
            break;
        case 2:
            if (disp1==0x20)
            {
                ck_a=disp1;
                ck_b=ck_a;
                ind=0;
                step=3;
            }
            else
            {
                step=0;
            }
            break;
        case 3:
            message[ind]=disp1;
            ck_a=ck_a+disp1;
            ck_b=ck_b+ck_a;
            ind=ind+1;
            if (ind==32)
            {
                step=4;
            }
            break;
        case 4:
            if (ck_a==disp1)
            {
                step=5;
            }
            else
            {
                step=0;
            }
            break;
        case 5:
            if (ck_b==disp1)
            {
                complete=1;
            }
            step=0;
            break;
        default:
            step=0;
    }
}

void __ISR(_EXTERNAL_1_VECTOR, IPL7AUTO) INT1Interrupt(void)    //LAP
{
    //whatever the lap button does
    butpre1 = 1;
    IEC0bits.INT1IE=0;
    IFS0bits.INT1IF=0;
}

void __ISR(_EXTERNAL_2_VECTOR, IPL7AUTO) INT2Interrupt(void)    //DONE
{
    //whatever the stop button does
    butpre2 = 1;
    IEC0bits.INT2IE=0;
    IFS0bits.INT2IF=0;
    test=1;
}

void __ISR(_EXTERNAL_3_VECTOR, IPL7AUTO) INT3Interrupt(void) //ENGINE RPM
{
    numEg=numEg+1;
    IFS0bits.INT3IF=0;
}

void __ISR(19, IPL7AUTO) INT4Interrupt(void) //WHEEL RPM
{
    numWh=numWh+1;
    IFS0bits.INT4IF=0;
}

void excel_setup (unsigned long fix, unsigned long date, unsigned long UTCtime)
{
    unsigned long yr;
    unsigned long day;
    unsigned long month;

    day = date/10000;
    date = date - day*10000;
    month = date/100;
    date = date - month*100;
    yr = date;

    sd_format(UTCtime);
    if (fix==3)
    {
        sd_ammend(",");
        sd_fammend(month);
        sd_ammend("/");
        sd_fammend(day);
        sd_ammend("/");
        sd_fammend(yr);
        sd_ammend(",");
    }
    else
    {
        sd_ammend(",DATE UNAVAILABLE");
    }
    sd_ammend("\r");
}

void gps_setting (unsigned char setting[])
{
    int n=0;
    while(setting[n]!='\0')
    {
        putu1(setting[n]);
        n=n+1;
    }
}

unsigned long value(unsigned int index)
{
    unsigned long value1;
    value1 = message[index];
    value1 = (value1<<8)+message[index-1];
    value1 = (value1<<8)+message[index-2];
    value1 = (value1<<8)+message[index-3];
    return value1;
}

int main(int argc, char** argv)
{

    numWh = 0;
    numEg = 0;

    //initialize UART for GPS and corresponding interrupts
    TRISGbits.TRISG6=1;
    TRISGbits.TRISG8=0;
    TRISGbits.TRISG7=1;
    TRISGbits.TRISG9=0;
    TRISDbits.TRISD8=1;
    TRISDbits.TRISD9=1;
    TRISDbits.TRISD10=1;
    TRISDbits.TRISD11=1
    enableInter();

    serial_init1(38400);
    
    gps_setting("$PGCMD,16,0,0,0,0,0*6A\r\n");
     

    //initialize SD card and SPI
    LCD_init();
    //sdstuff();
        
    //Delayms(30);
//    int g=0;
//
//    SD_CS =0;
//    while(g<15)
//    {
//       swap('V');
//       g=g+1;
//    }
//    SD_CS =1;

    //initialize gps and set in binary mode


    //variable declarations
    unsigned long latit;
    unsigned long longit;
    unsigned long date;
    unsigned long speed;
    unsigned long fix;
    unsigned long t=0;
    unsigned long laptime=0;
    unsigned long laps=0;
    unsigned char formatted=0;
    unsigned long time_of_last_press;
    unsigned long butdec1 = 0;  //counter to debounce button
    unsigned long butdec2 = 0;  //counter to debounce button

    char PREVLAP[4];
    char SPEED[3];
    char testspd[3];
    char DIG0[1];
    char DIG1[1];
    char DIG2[1];
    char DIG3[1];
    unsigned long UTCtime;
    mode=1;
    test=0;
    gps_file_created=0;
    unsigned long prevLAP=0;
    unsigned long speed2 = 2000;
    unsigned long dig0;
    unsigned long dig1;
    unsigned long dig2;
    unsigned long dig3;
    unsigned int fixset=0;
    unsigned int nofixset=0;
    unsigned int modeset=0;
    unsigned int velocityset=0;



    while(1)
    {
        //snd_cmd(0x51,0x00);
        //string_snd(tester,3);
        if (butpre1 == 1)  //resets counter if button is pressed
        {
            butdec1 = 0;
            butpre1 = 0;
            test=2;
        }
        if (butpre2 == 1)  //resets other counter if button is pressed
        {
            butdec2 = 0;
            butpre2 = 0;
        }
        if(butdec1 == 30000)  //restarts the lap button interrupt
        {
            IFS0bits.INT1IF=0;
            IEC0bits.INT1IE=1;
            butdec1 = 0;
        }
        if(butdec2 == 30000)  //restarts the stop button interrupt
        {
            IFS0bits.INT2IF=0;
            IEC0bits.INT2IE=1;
            butdec2 = 0;
        }
        ++butdec1;
        ++butdec2;

            

        //lap button activated
        if ((test==2)&&(mode==1))
        {
            //snd_cmd(0x45,0x51);
            //string_snd(tester,3);
            
            prevLAP=t;
            t=0;

            sprintf(PREVLAP, "%ld", prevLAP);
            snd_cmd(0x45,0x5E);
            //Delayms(10);
            if(prevLAP < 10)
            {
               string_snd(PREVLAP,1);
            }
            else if(prevLAP < 100)
            {
                string_snd(PREVLAP,2);
            }
            else if(prevLAP<1000)
            {
                string_snd(PREVLAP,3);
            }
            else if(prevLAP>1000)
            {
                string_snd(PREVLAP,4);
            }
            else   
            {
                string_snd(PREVLAP,0);
            }


//           laps++;
//           laptime=t-time_of_last_press;
//           time_of_last_press=t;
//
////           lap_fammend(laps);
////           lap_ammend(",");
////           lap_fammend(laptime);
////           lap_ammend("\r");
////           //change screen display

           test=0;
        }

        //test mode activated
        if (test==1)
        {
            //formatted=0;
            //display speed on screen

            snd_cmd(0x45,0x46);
            string_snd(TEST,4);
            //when lap is pressed
                //create file if first time
                //delay 100ms
                //calculate rpm
                //output time and rpm to file
        }

        //race mode activated
        if (test==0)
        {
                if (modeset==0)
                {
                    //Delayms(5);
                    snd_cmd(0x45,0x46);
                    //Delayms(10);
                    string_snd(RACE,4);
                    modeset=1;
                }

                if (complete==1)
                {

                    //output rps
                    char ERPS[3];
                    //Delayms(5);
                    sprintf(ERPS, "%ld", numEg);
                    snd_cmd(0x45,0x52);
                    //Delayms(10);
                    if(numEg < 10)
                    {
                       string_snd(ERPS,1);
                    }
                    else if((numEg < 100)&&(numEg>9))
                    {
                        string_snd(ERPS,2);
                    }
                    else
                    {
                        string_snd(ERPS,3);
                    }
                    numEg=0;

                    char RPS[3];
                    //Delayms(5);
                    sprintf(RPS, "%ld", numWh);
                    snd_cmd(0x45,0x12);
                   // Delayms(10);
                    if(numWh < 10)
                    {
                       string_snd(RPS,1);
                    }
                    else if((numWh < 100)&&(numWh>9))
                    {
                        string_snd(RPS,2);
                    }
                    else
                    {
                        string_snd(RPS,3);
                    }
                    numWh=0;


                    //output time
                    t++;
                    //sendValue(t,0x1D);
                    char T[4];
                    //Delayms(5);
                    sprintf(T, "%ld", t);
                    snd_cmd(0x45,0x1D);
                    //Delayms(20);
                    if(t < 10)
                    {
                       string_snd(T,1);
                    }
                    else if(t < 100)
                    {
                        string_snd(T,2);
                    }
                    else if(t < 1000)
                    {
                        string_snd(T,3);
                    }
                    else
                    {
                        string_snd(T,4);
                    }


                    //extract values from message
                    speed = value(15);
                    latit = value(3);
                    longit = value(7);
                    date = value(25);
                    UTCtime = value(29);
                    fix = message[21];


                    if (fix!=3)
                    {
                        if (nofixset==0)
                        {
                            //Delayms(5);
                            snd_cmd(0x45,0x22);
                            //Delayms(10);
                            string_snd(NOFIX,6);
                            nofixset=1;
                            fixset=0;
                        }
                    }
                    else if (fix==3)
                    {
                        if (fixset==0)
                        {
                            //Delayms(5);
                            snd_cmd(0x45,0x22);
                            //Delayms(10);
                            string_snd(FIX,6);
                            fixset=1;
                            nofixset=0;
                        }
                    }

                    if (mode==0)
                    {
                        snd_cmd(0x45,0x06);
                        //Delayms(10);
                        string_snd(BUG,3);
                    }

                    if (mode==1)
                    {

                        //snd_cmd(0x45,0x46);
                        //string_snd(RACE,6);

                        //if this is the first message received, format the two excel sheets
//                        if (formatted==0)
//                        {
////                            excel_setup(fix,date,UTCtime);
//                            formatted=1;
//                        }

                        //output data if gps fix exists
                        if (fix==3)
                        {
                            //calc erpm and wrpm based on counters

//                            sd_fammend(t);
//                            sd_ammend(",");
//                            sd_fammend(speed);
//                            sd_ammend(",");
//                            sd_fammend(latit);
//                            sd_ammend(",");
//                            sd_fammend(longit);
//                            //sd_ammend(",");
//                            //sd_fammend(erpm);
//                            //sd_ammend(",");
//                            //sd_fammend(wrpm);
//                            sd_ammend("\r");

                            //screen displays speed and lap times
                            //
                            long speed3=speed;
                            speed3=speed3*224;

                            //sprintf(testspd,"%ld",speed3);
                            //Delayms(5);
                            snd_cmd(0x45,0x05);
                            //Delayms(10);
                            dig0=(speed3/100000)%10;
                            dig1=(speed3/10000)%10;
                            dig2=(speed3/1000)%10;
                            dig3=speed3%1000;
                            sprintf(DIG0,"%ld",dig0);
                            sprintf(DIG1,"%ld",dig1);
                            sprintf(DIG2,"%ld",dig2);
                            sprintf(DIG3,"%ld",dig3);
                            if (DIG0!=0)
                            {
                                string_snd(DIG0,1);
                            }
                            string_snd(DIG1,1);
                            LCD_snd('.');
                            string_snd(DIG2,1);
                            string_snd(DIG3,1);
                            //snd_cmd(0x45,SPEED[0]);
                            //snd_cmd(0x45,'.');
                            //snd_cmd(0x45,SPEED[1]);
                            //snd_cmd(0x45,SPEED[2])
                            velocityset=0;
                        }
                        else
                        {
                            if (velocityset==0);
                            {
                                //Delayms(5);
                                snd_cmd(0x45,0x05);
                                //Delayms(10);
                                dig0=0;
                                dig1=0;
                                dig2=0;
                                dig3=0;
                                sprintf(DIG0,"%ld",dig0);
                                sprintf(DIG1,"%ld",dig1);
                                sprintf(DIG2,"%ld",dig2);
                                sprintf(DIG3,"%ld",dig3);
                                string_snd(DIG0,1);
                                string_snd(DIG1,1);
                                LCD_snd('.');
                                string_snd(DIG2,1);
                                string_snd(DIG3,1);
    //                            sd_fammend(t);
    //                            sd_ammend(",");
    //                            sd_ammend("NO GPS FIXXX0");
    //                            sd_ammend("\r");
                            }
                            velocityset=1;
                            //screen displays zero for speed and normal lap time
                        }

                        complete=0;
                    }
                }
            
        }
    }
    //return (EXIT_SUCCESS);
}




