#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay_basic.h>
#include <avr/sfr_defs.h>
#include <avr/pgmspace.h>
//#include "uart.h"
//#include "uart.c"
//#include "global.h"
//#include "buffer.h"
//#include "buffer.c"
//#include "avrlibdefs.h"
//#include "avrlibtypes.h"


#define sonar_rad_mask 0b00000110
#define sonar_stop_mask 0b00000000
#define flipmask 0b00000010
#define debounce 200
#define USART_BAUDRATE 57600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define buffer_size 2000
#define initial 0x95
#define rx_resend_done 0
#define half_transmitted 1
#define rx_size 10
#define echo_size 70
 //unsigned char  char_test[] PROGMEM ={'N','o','w',' ','g','o','e','s',' ','n','u','m','b','e','r',' ','2','5','2','0','0',' ',' ',' ',' ',0};
 unsigned char  separate_message[] PROGMEM ={13,'*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*',0};
 //unsigned char  test_message[] PROGMEM ={'A','B','C',0};
 unsigned char  timer_mess[] PROGMEM ={13,'T','I','M','E','R',' ',0};

 unsigned char  echo_p_f[] PROGMEM ={13,'E','H','O','E',' ','P','O','I','N','T','E','R',' ','F','I','N','A','L',' ',0};
 unsigned char  echo_init[] PROGMEM ={13,'E','H','O','E',' ','I','N','I','T','I','A','L',0};
 unsigned char  echo_fin[] PROGMEM ={13,'E','H','O','E',' ','F','I','N','A','L',0};
 unsigned char  echo_p[] PROGMEM ={13,'E','H','O','E',' ','P','O','I','N','T','E','R',' ',0};
 unsigned char  message_you_send[] PROGMEM ={13,'Y','o','u',' ','s','e','n','t',' ',0};
 unsigned char  message_new_echo[] PROGMEM ={13,'A','n','o','t','h','e','r',' ','e','c','h','o',' ','d','i','s','t','a','n','c','e',' ',0};
 unsigned char  message_value[] PROGMEM ={13,'v','a','l','u','e',' ',0};
 /*unsigned char  test[] PROGMEM ={254,0x00,0x01 ,0x02 ,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,
 0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff};


 /*unsigned char  freequency[] PROGMEM ={    0x00,0x99,     0x00,0x98,    0x00,0x97,   0x00,0x96,   0x00,0x95,   											
										           	 0x00,0x94,     0x00,0x93,    0x00,0x92,   0x00,0x91,   0x00,0x90,   											
										           	 0x00,0x8F,     0x00,0x8E,    0x00,0x8D,   0x00,0x8C,   0x00,0x8B,
										           	 0x00,0x8A,     0x00,0x89,    0x00,0x88,   0x00,0x87,   0x00,0x86,
0xFF,0xFF,
											 };
											
											
											
											
  											

                                             /*0x17,0x70,     0x0B, 0xB8,   0x07,0xD0,    0x05,0xDC,   0x04,0xB0,
                                             0x03,0xE8,     0x03, 0x59,   0x02,0xEE,    0x02,0x9A,   0x02,0x58,
                                             0x02,0x21,     0x01, 0xF4,   0x01,0xCD,    0x01,0xAC,   0x01,0x90,
										     0x01,0x77,     0x01, 0x60,   0x01,0x4D,    0x01,0x3B,   0x01,0x2C,
											 0x01,0x1D,     0x01, 0x10,   0x01,0x04,    0x00,0xfa,   0x00,0xf0,
											 0x00,0xe6,     0x00, 0xde,   0x00,0xd6,    0x00,0xce,   0x00,0xc8,
											 0x00,0xc1,     0x00, 0xbb,   0x00,0xb5,    0x00,0xb0,   0x00,0xab,											
											 0x00,0xa6,     0x00,0xa2,    0x00,0x9d,    0x00,0x99,   0x00,0x96,   											
											 0x00,0x92,     0x00,0x8e,    0x00, 0x8b,   0x00,0x88,   0x00,0x85,   											
											 0xFF,0xFF*/

//volatile static  unsigned char sonar_mask=sonar_rad_mask;
volatile static  unsigned short int accum=0;
volatile static  unsigned char status=1;
volatile static  unsigned char transmit_us=0;
//static unsigned char buffer[buffer_size];
static unsigned char burst_limit=16;
volatile static unsigned char rx_data;
volatile static unsigned char status_reg=0;
volatile static unsigned char rx_buffer[rx_size];
volatile static unsigned char rx_pointer=0;

// static unsigned int tA=0;
 volatile static unsigned char echo_buffer[echo_size];
 volatile static unsigned int echo_time[echo_size];

 volatile static unsigned char echo_buffer_final[echo_size];
 volatile static unsigned int echo_time_final[echo_size];
 volatile static unsigned short int timered_ech[echo_size];


//volatile static unsigned char buffer_index=0;

void UART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while(bit_is_clear (UCSRA,UDRE) ){
asm("nop"::);};

/* Put data into buffer, sends the data */
 UDR = data;
}

/* ISR(ADC_vect){
 volatile static unsigned int buffer_index=0;
 buffer[buffer_index]=ADCH;
 buffer_index++;
 if (buffer_index==buffer_size) {
 buffer_index=0;
 status=3;


 UART_Transmit( 0xFF );
 UART_Transmit( 0xBB );
 UART_Transmit( 0xCC );
 UART_Transmit( 0xDD );
 UART_Transmit( 0xEE );
 UART_Transmit( 0xFF );
 ADCSRA&=(~((1<<ADFR)|(1<<ADSC)|(1<<ADIE)));
 UCSRB|=(1<<TXCIE);
 }
 };   */

ISR(USART_RXC_vect){

   rx_buffer[rx_pointer]=UDR;
   rx_pointer++;
   status_reg=status_reg|(1<<rx_resend_done);
  };

ISR(TIMER2_COMP_vect){
 PORTB=(PORTB^sonar_rad_mask);//)&(sonar_rad_mask);
 if((accum>=(burst_limit>>1))&&(bit_is_clear(status_reg,half_transmitted))){
 TCCR1B|= 3<<CS10;
 status_reg|=1<<half_transmitted;
 };
 accum=accum+1;

 }

 //&&(bit_is_clear(status_reg,half_transmitted))

/*ISR(USART_TXC_vect){
 // unsigned char temp=0;
  volatile static unsigned int buffer_index=0;
  //volatile static  unsigned short int test_pointer=0;
 // volatile static unsigned char tx_status=0;
  //volatile static unsigned char preform=0;
//  if (tx_status==0){
 // temp=pgm_read_byte(&test[test_pointer]);
 // UDR=temp;
 // test_pointer++;
//  temp=pgm_read_byte(&test[test_pointer]);
 // if (temp==255) {
 // tx_status=1;
 // test_pointer=0;};  };

 // if (tx_status==1){
  sei();
  while(bit_is_clear (UCSRA,UDRE) ){
  asm("nop"::);}
  UDR=buffer[buffer_index];
  buffer[buffer_index]=0;
  buffer_index++;
  if (buffer_index==buffer_size) {
  //PORTB=PORTB|0b00000010;
  // _delay_loop_1(10);
  buffer_index=0;
  status=1;
  UCSRB&=(~(1<<TXCIE));

 // PORTB=PORTB|0b00000010;
  TCCR1B=TCCR1B&(~((1<<CS12)|(1<<CS11)|(1<<CS10)));
  TIFR|=(1<<OCR1A);
  TCNT1H=0;
  TCNT1L=initial-3;
  TCCR1B= 0x09;

  TIMSK|=(1<<4);
  //tx_status=0;
 // sonar_mask=sonar_rad_mask; };
   };

   }; */


/*
ISR(TIMER1_COMPA_vect){
PORTB=(PORTB^sonar_rad_mask);//)&(sonar_rad_mask);
accum=accum+1;
;}
 */

void message_transmit(unsigned char* message ){
 unsigned char j=0;
 unsigned char mess_char=pgm_read_byte(&message[0]);
 while((mess_char!=0)){
  UART_Transmit(mess_char);
  j++;
  mess_char=pgm_read_byte(&message[j]);
  };
  }



 void uart_init (void){
  /* Set baud rate */
UBRRH=0;
UBRRL=BAUD_PRESCALE;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(3<<UCSZ0);}



 void ADC_init (void){
 ADMUX|=(1<<ADLAR)|(1<<MUX0);
 ADCSRA|=(1<<ADEN)|(1<<ADFR)|(4<<ADPS0);
 //ADCSRA|=(1<<ADSC)
 ;}





void send_int(unsigned short int int_to_send){
unsigned char dec4, dec3, dec2, dec1 ,dec0;
//unsigned short int temp3=0, temp1=1023,temp2=2;
//while(1){
//temp3=temp1*temp2;
//dec4++;
//UART_Transmit(temp3);
//}

dec4= int_to_send/10000;
dec3=(int_to_send%10000)/1000;
dec2=(int_to_send%1000)/100;
dec1=(int_to_send%100)/10;
dec0=(int_to_send%10);
UART_Transmit((dec4+48));
UART_Transmit((dec3+48));
UART_Transmit((dec2+48));
UART_Transmit((dec1+48));
UART_Transmit((dec0+48));
                                               }

/* void send_long_int(unsigned long int int_to_send){
unsigned char dec9=0, dec8=0, dec7=0, dec6=0, dec5=0 ,dec4=0, dec3=0, dec2=0, dec1=0 ,dec0=0;
//unsigned short int temp3=0, temp1=1023,temp2=2;
//while(1){
//temp3=temp1*temp2;
//dec4++;
//UART_Transmit(temp3);
//}
dec9=int_to_send/100000000000;
dec8=(int_to_send%1000000000)/100000000;
dec7=(int_to_send%100000000)/10000000;
dec6=(int_to_send%10000000)/1000000;
dec5=(int_to_send%1000000)/100000;
dec4=(int_to_send%100000)/10000;
dec3=(int_to_send%10000)/1000;
dec2=(int_to_send%1000)/100;
dec1=(int_to_send%100)/10;
dec0=(int_to_send%10);
UART_Transmit((dec4+48));
UART_Transmit((dec3+48));
UART_Transmit((dec2+48));
UART_Transmit((dec1+48));
UART_Transmit((dec0+48));
                                               } */



/*void int_sending (unsigned short int send_int){
unsigned char low_nibble=0;
unsigned char high_nibble=0;
low_nibble=(char)send_int;
high_nibble=(char)(send_int>>7);
}*/



unsigned short int get_timer(void){
 unsigned char  sreg ;
 unsigned short int result;
 sreg=SREG;
 cli();
 result=TCNT1;
 SREG=sreg;
 return result;


 }


/*

void timer_1_init(void){
TCCR1A=0x00;
TCCR1B|= 3<<CS10;

//PORTB=PORTB|0b00000010;
//TIMSK=TIMSK|(1<<4);
//OCR1AH=0x00;
//OCR1AL=initial;
 }*/


 void timer_2_init(void){
TCCR2= (1<<WGM21)|(1<<CS20);
OCR2=initial;
TIMSK=TIMSK|(1<<OCIE2);
 }



void  start(void) {
/*	                                   |-
	                                   ||-
	                                   |||-
	                                   ||||-
           	                          |||||-
	                                   ||||||-sonar
	                                   |||||||-sonar
                                      ||||||||-button             */
//                             DDRB=0b00000110;
 ACSR=0x80;

 PORTD=0b00000010|(1<<2);
 DDRD=0b01111110;
 PORTB=0b00000010;
 DDRB=0b00000110;
// PORTB=0b00000010;
 //PORTD=0b00000000|(1<<2);
 DDRC=0b00110000;
 PORTC=0b00000000;

  };









 int main (void) {

 //unsigned int test_var='D';

 //unsigned char k=0,l=0,m=0;

  //unsigned short int form_var=23300; // to test muliple char output
  unsigned char A=0  ;
  unsigned char B=0 ;
  unsigned char C=0 ;
  unsigned char D=0 ;
  unsigned char E=0 ;
  unsigned char F=0 ;
  unsigned char G=0 ;

 unsigned short int temp_time=0;
 unsigned char echo_pointer_final=0;
// unsigned short char temp2=0;
 unsigned char l=0,m=0,n=0;
// unsigned short int m=0;

////////////////////////
 unsigned char echo_pointer=0;
 unsigned int buffer_index=0;
 unsigned char counter_press=0, counter_unpress=0;
 unsigned char stats=0;//0 means button pressed but not yet  presed "debounce" times
// unsigned char i=0;
 unsigned char mess_char=' ';
// unsigned char chars_to_send=0;                     //1 means button unpressed but not "debounce" times

 start();
 uart_init ();
// for(int l=0;l<1000;l++){
// asm("nop"::);}

// send_int(form_var);
 ADC_init();
 timer_2_init();


 sei();
// UART_Transmit(0);


 while(1){

  if((status==1)&&(accum>=burst_limit)){
  //TIMSK=TIMSK&(~(1<<4));//for timer 1
  TIMSK=TIMSK&(~(1<<OCIE2));//for timer 2
  accum=0;
  status=2;
  //_delay_loop_1(10);
  //sonar_mask=sonar_stop_mask;
  //UCSRB|=(1<<TXCIE);

  // PORTB=PORTB&0b11111001;
  //ADMUX|=(1<<MUX0);
  ADCSRA|=(1<<ADEN);
  //ADCSRA|=(1<<ADSC)|(1<<ADIE);
  ADCSRA|=(1<<ADSC);
  }

//
  while (status==2)
  {

  if(bit_is_set(ADCSRA,ADIF))
   {
  //buffer[buffer_index]=ADCH;
  buffer_index++;
  ADCSRA=ADCSRA|(1<<ADIF);
  //tA=buffer_index;


  if ((D>=C)&&(D>=E)&&(D>=B)&&(D>=F)&&(D>=G)&&(D>=A)&&(E>=G)&&(C>=A)&&(D>4))
    {
  echo_buffer[echo_pointer]=D;
  echo_time[echo_pointer]=buffer_index-3;
  timered_ech[echo_pointer]=get_timer()-15;
  echo_pointer++;
  //UART_Transmit(echo_pointer);
    };
  G=F;
  F=E;
  E=D;
  D=C;
  C=B;
  B=A;
  A=ADCH;

  if (buffer_index==buffer_size)
    {

  ADCSRA&=(~(1<<ADEN));
  buffer_index=0;
  status=1;



  //message_transmit(test_message);

// unsigned char j=1,i=0,k=0;
  m=0;
  while ( m<=echo_pointer){
  temp_time=echo_time[m];

  l=0;
  while((echo_buffer[m]==echo_buffer[m+1])&&(echo_time[m+1]==echo_time[m]+1)&&(echo_buffer[m]!=0)){
  //temp_time=temp_time+echo_time[m+1];
  m++;
  l++;
  };


  echo_time_final[echo_pointer_final]=temp_time+(l>>1);
  echo_buffer_final[echo_pointer_final]=echo_buffer[m];
  m++;
  echo_pointer_final++;
  };
  echo_pointer_final--;
  //echo_pointer_final=j;

  message_transmit(echo_p_f);
  send_int(echo_pointer_final);
  UART_Transmit(mess_char);
  message_transmit(echo_p);
  send_int(echo_pointer);

  message_transmit(echo_init);

   for (unsigned short int j=0;j<echo_pointer; j++)
     {

  message_transmit(message_new_echo);
  send_int((echo_time[j]*34));
  message_transmit(timer_mess);
  send_int((timered_ech[j]));

  //UART_Transmit((echo_time[j]));

  message_transmit(message_value);
  send_int(echo_buffer[j]);
     };

  message_transmit(echo_fin);
  for (unsigned short int j=0;j<echo_pointer_final; j++)
     {

  message_transmit(message_new_echo);
  send_int((echo_time_final[j]*34));
  //UART_Transmit((echo_time[j]));

  message_transmit(message_value);
  send_int(echo_buffer_final[j]);
     };





  echo_pointer_final=0;
  echo_pointer=0;
  for( char i=0;i<=echo_size;i++)
     {
 echo_time[i]=0;
 echo_time_final[i]=0;
  echo_buffer[i]=0;
  echo_buffer_final[i]=0;
     };
     //UCSRB|=(1<<TXCIE);
     message_transmit(separate_message);

     TCCR1B=0;
     TCNT1=0;
     status_reg&=~(1<<half_transmitted);

     TCCR2&=0b11111110;
     TCNT2=0;
     SFIOR|=(1<<PSR2);
   //  while(bit_is_clear (SFIOR,PSR2) ){
   //  asm("nop"::);};
     TCCR2|=(1<<CS20);
     TIMSK|=(1<<OCIE2);


      /*  TCCR1B=TCCR1B&(~((1<<CS12)|(1<<CS11)|(1<<CS10)));
  TIFR|=(1<<OCR1A);
  TCNT1H=0;
  TCNT1L=0;
  TCCR1B= 0x09;

  TIMSK|=(1<<4);*/
    };


   };
  };




  if(bit_is_set(status_reg,rx_resend_done))
    {



  message_transmit(message_you_send);


 // chars_to_send=rx_pointer;
  for(int  chars_to_send=0; chars_to_send<rx_pointer; chars_to_send++)
     {
  UART_Transmit(rx_buffer[chars_to_send]);
     };
  PORTD=PORTD&0b10000011;
  PORTD=PORTD|((~0b10000011)&rx_buffer[0]);
  PORTC=PORTC&0b11001111;
  PORTC=PORTC|(((~0b11111100)&rx_buffer[0])<<4);

  switch (rx_buffer[0])
     {
  case 'L': case 'l' : { if (((rx_buffer[1]=='E')||(rx_buffer[1]=='e'))&&((rx_buffer[2]=='V')||(rx_buffer[2]=='v'))&&((rx_buffer[3]=='E')||(rx_buffer[3]=='e'))) {UART_Transmit('S');};}
  break;

     };

  for( int j=0; j<=rx_pointer;j++){
  rx_buffer[j]=0;
    };

  rx_pointer=0;


  //UART_Transmit(rx_data);
  mess_char=pgm_read_byte(&message_you_send[0]);
  //i=0;
  status_reg=status_reg&(~(1<<rx_resend_done));
   };



  /*
  if((status==1)&&(accum>=40)){
  accum=0;
  status=0;
  sonar_mask=sonar_stop_mask;
  UCSRB|=(1<<TXCIE);
  ADCSRA|=(((1<<ADEN)|(1<<ADFR)|(1<<ADSC)|(1<<ADIE)));}


  if((status==0)&&(accum>=400)){
  accum=0;
  status=1;
  sonar_mask=sonar_rad_mask;
  ADCSRA&=(~((1<<ADEN)|(1<<ADFR)|(1<<ADSC)|(1<<ADIE)));
  UCSRB&=(~(1<<TXCIE));
   }; */




 /* if((bit_is_set(PINB,0))&&(stats==0)){counter_press=counter_press+1;};
  if((bit_is_clear(PINB,0))&&(stats==1)){counter_unpress=counter_unpress+1;};

  if((stats==0)&&(counter_press>debounce)) {
   stats=1;
   counter_press=0;
   };

  if ((stats==1)&&(counter_unpress>debounce)) {
   counter_unpress=0;
   stats=0;
   rx_limit++;
  // if(channel==1){channel=2;}
  // else{channel=1;};
   PORTD=(rx_limit-9)<<3; }; */


 // transmit_us=ADCH;



 //light=light+2;

 /* high_=pgm_read_byte(&freequency[light[0]]);
  low_=pgm_read_byte(&freequency[light[0]+1]);
  if ((low_==0xFF)&&(high_==0xFF))  {light[0]=0;low_=1;high_=0; };
 // if(light[0]!=light[1]){
  cli();
  OCR1AH=high_;
  OCR1AL=low_;
  sei();   */
// _delay_loop_2(50000);
 // PORTD=low_;
 // light[1]=light[0];};
  };
 // if(bit_is_set(PINB,0)){PORTD=0b01111100;}
 // else {PORTD=0b00000000;}
 // OCR1AH=pgm_read_word(&freequency[light[0]]);
 // OCR1AL=pgm_read_word(&freequency[light[0]+1]);*/




  ;}




























































