/*
    Cat Tracker
*/

#include <avr/io.h>
//#include "rprintf.h"


#define FOSC 8000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1


//Define functions
//======================
void ioinit(void);      //Initializes IO
void delay_ms(uint16_t x); //General purpose delay
void delay(void);
void delay_halfbit(uint16_t x);//4800 baud half-bit width
char getc(void);
void putchr(char x);
void delay_1_4bit(uint16_t x);
void get_GPS(void);
void uart_sync(void);

//======================

//Global variables
//=========================
char GPS_buff[60];


int main (void)
{
	int j;
    //ioinit(); //Setup IO pins and defaults
	
	DDRA = 0b01000000;//PA6 = out (TX)
	DDRB = 0b00000100;//PB2 = out
	
	PORTA = 0b11100000;
	delay_ms(1000);
	PORTB = 0b00000100;//turn on GPS
	
	
	
	/*
	while(1)
	{
		//this works, reads the GPS to the TX line
		
		j = PINA;
		if (j & 0b10000000) PORTA |= 0b01000000;
		else PORTA &= 0b10111111;
		
		
		
		//PORTA |= 0b01000000;
		//delay_halfbit(1);
		//PORTA &= 0b10111111;
		//delay_halfbit(1);
		
		
	}
	*/
	
	
	
	while(1)
	{
		uart_sync();
		//j = getc();
		//putchr(j);
		
		while (j != 'R') j = getc();
		get_GPS();
		for (j = 0; j < 60; j++)
		{
			putchr(GPS_buff[j]);
		}
		
		putchr(10);
		putchr(13);
		
		//j = getc();
		//putchr(j);
		
		/*
		putchr('H');
		delay_ms(10);
		putchr('e');
		delay_ms(10);
		putchr('l');
		delay_ms(10);
		putchr('l');
		delay_ms(10);
		putchr('o');
		delay_ms(10);
		putchr(' ');
		delay_ms(10);
		putchr('W');
		delay_ms(10);
		putchr('o');
		delay_ms(10);
		putchr('r');
		delay_ms(10);
		putchr('l');
		delay_ms(10);
		putchr('d');
		delay_ms(10);
		
		putchr(10);
		delay_ms(10);
		putchr(13);
		delay_ms(1000);
		*/
		
		//putchr(85);
		//delay_ms(1);
		
		/*
		PORTA &= 0b10111111;//start bit
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA &= 0b10111111;//1
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//0
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//0
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//0
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//0
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//0
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA &= 0b10111111;//1
		delay_halfbit(1);
		delay_halfbit(1);
		
		PORTA |= 0b01000000;//stop bit
		delay_halfbit(1);
		delay_halfbit(1);
		*/
		
		//putchr('u');
		//delay_ms(30);
		
	}
   
    
}

void ioinit (void)
{
	
    //1 = output, 0 = input
    //DDRB = 0b11111111; //All outputs
    //DDRC = 0b11111111; //All outputs
    //DDRD = 0b11111110; //PORTD (RX on PD0)
	
	//PORTC = 0b00111111;
	
	//DDRB = 0b00000011; //PB0 and PB1 are outs
	//DDRC = 0b00111111; //PC0-PC5 are also outs.  These are the display control lines
	//DDRD = 0b11111100; //PD2-PD8 are also outs.  Ports B and D are the data bus.
	
}

//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
      for ( z = 0 ; z < 6 ; z++){
        asm volatile ("nop");
      }
    }
  }
}


//4800 baud half-bit width
void delay_halfbit(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 15 ; y++){
      
        asm volatile ("nop");
      
    }
  }
}


//4800 baud quarter-bit width
void delay_1_4bit(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 7 ; y++){
      
        asm volatile ("nop");
      
    }
  }
}


//delay for display timing
void delay(void)
{
	char x;
	
	for(x = 0; x < 10; x++)
	{
		asm volatile ("nop");
	}
	
}

char getc(void)
{
	char j = 32, k, l = 0;
	
	//while(j & 0b00100000) j = PINA; //wait for PA5 to go low, user input
	while(j & 0b10000000) j = PINA; //wait for PA7 to go low, GPS input
	
	delay_halfbit(1);
	delay_1_4bit(1);
	delay_halfbit(1);
	//delay_halfbit(1);
	//delay_halfbit(1);//this should put us in the middle of the first data bit
	
	j = 0;
	
	for (k = 0; k < 8; k++)
	{
		l >>= 1;
		//delay_halfbit(1);
		j = PINA;
		//if (j & 0b00100000) l |= 0b10000000;//user input
		if (j & 0b10000000) l |= 0b10000000;//GPS input
		else l &= 0b01111111;
		
		delay_halfbit(1);
		delay_halfbit(1);
	}
	
	//delay_halfbit(1);//one stop bit
	//delay_halfbit(1);
	
	return l;
}


void get_GPS(void)
{
	int j;
	
	
	for (j = 0; j < 60; j++)
	{
		GPS_buff[j] = getc();
	}
	

}



void putchr(char x)
{
	char k;
	
	PORTA &= 0b10111111;
	delay_halfbit(1);//1 start bit
	delay_halfbit(1);
	//delay_halfbit(1);
	//delay_halfbit(1);
	
	for (k = 0; k < 8; k++)//8 data bits
	{
		if (x & 0b00000001) PORTA |= 0b01000000;
		else PORTA &= 0b10111111;
		x >>= 1;
		delay_halfbit(1);
		delay_halfbit(1);
	}
	
	//PORTA &= 0b10111111;
	//delay_1_4bit(1);
	//delay_halfbit(1);//1 stop bit
	//delay_halfbit(1);
	
	PORTA |= 0b01000000;//set it high again
	delay_halfbit(1);
	delay_halfbit(1);

}


void uart_sync(void)
{
	int a = 0;
	char b;
	
	/*
	while(1)
	{
		delay();
		b = PINA;
		//if (b & 0b00100000) a++;
		if (b & 0b10000000) a++;
		else a = 0;
		
		if (a >= 2000) return;
	}
	*/
	
	
	for (a = 0; a < 2000; a++)
	{
		delay();
		b = PINA;
		if (!(b & 0b10000000)) a = 0;
		//if (!(b & 0b00100000)) a = 0;
	}
	

}





