#include <pic.h> 
#include "globals.h" 
#include "serial.h" 

#undef GPSRECV_DEBUG 


/* this is the blocking $GPRMC string retrieval function. 
   this has been superceded by the RCIE inthdl() form which greatly improves 
   bandwidth utilization over the pipe.
*/

void gps_gprmc() {
   unsigned char i, devnull;

   for (;;) {
      do {
         getch();
      } while(RCREG != '$');
   
      for (i = 0; i < 5; i++) {
         getch();
         devnull = RCREG;        // this *must* be done, otherwise RCIF does not get cleared, *overflow*
      }
   
      if (RCREG == 'C') {
         getch();
         devnull = RCREG;

         for (i = 0; i < 60; i++) {
            getch();
            TXREG = RCREG;
         }
         break;
      }
   }
}

/* initializing function for this module
   specifically disables RCIE receive interrupt before enabling CREN
*/

void gps_init() {
   SPEN  =  1;                   // set serial port enable : SPEN RCSTA<7> = 1
   TRISC =  TRISC | 0b01000000;  // set tristate TRISC<6> high, for rx

   SPBRG =  BRGSPEED;
   BRGH  =  1;
   SYNC  =  0;

   RCIE  =  0;
   RX9   =  0;
   
   CREN  =  0;
   CREN  =  1;
}

/* one-time use -- needed to limit Garmin output to only $GPRMC string.
   other strings may be useful but that has not yet been determined
*/

void gps_packet_limiter() {
   unsigned int timewaster;

   putstc("$PGRMO,GPGGA,0");     // disable $GPGGA sentence
   putlf();
   putstc("$PGRMO,GPGSA,0");     // disable $GPGSA sentence
   putlf();
   putstc("$PGRMO,GPGSV,0");     // disable $GPGSV sentence
   putlf();
   putstc("$PGRMO,PGRMT,1");     // enable $PGRMT sentence
   putlf();

   for (timewaster = 0; timewaster < 50000; timewaster++);
}

/* _r stands for reentrant, these are called from within
   inthdl() ONLY
*/

void getch_r() {                       
   if (OERR || FERR) {                 
      CREN  =  0;
      CREN  =  1;
   }

   while (!RCIF) {
   }
}

/* _r stands for reentrant, these are called from within
   inthdl() ONLY
*/

void putch_r(unsigned char cout) {
   TXREG = cout;
   while (!TRMT);                                          // this is the fastest way of doing this.
}


#ifdef GPSRECV_DEBUG 
main() {
   setup_interrupts();
   serial_init();

// gps_packet_limiter();
   gps_init();
   RCIE = 1;
   PEIE = 1;
   GIE  = 1;
   CREN = 1;
   
   for(;;) { }
}
#endif 

void interrupt inthdl() {
   unsigned char t1 = TMR1H;
   unsigned char t2 = TMR1L;
// TXREG=RCREG;
   RCIE = 0;
   PEIE = 0;
   GIE  = 0;

/*   
   while(RCREG != '$') {
      getch_r();
   }
*/
   do {
      TXREG = RCREG;
      getch_r();
   } while(RCREG != 10);
   TXREG = 10;
//   putch_r('$');
//   putch_r(13);
//   putch_r(10);
   
   RCIE = 1;
   PEIE = 1;
   GIE  = 1;
   
   TMR1H = t1;
   TMR1L = t2;
}