//#include "suryaa.h"
#include <avr/interrupt.h>
#include <stdint.h>

volatile uint16_t distance=0;

void pin_configure(void);
void output1(char);
uint16_t icr_value(void);
void clear_timer4(void);
void delay_microsec(int);//max load value is 128
short set_echopin(void);


void pin_configure(void)
{
  volatile char*dirf,*dirl,*dirc;
  dirf=(volatile char*)0x30;
 // dirl=(volatile char*)0x10A;
  dirc=(volatile char*)0x27;
  *dirc=0x00;
  *dirf=0xFF;
  *dirl=0x00;
  Serial.println("configured pin successfully");
}

void output1(char x)
{
  volatile char* outf;
  outf=(volatile char*)0x31;
  *outf=x;
  Serial.println("outputed successfully");
}

uint16_t icr_value(void)
{
  volatile char*icr4h,*icr4l;
  volatile uint8_t x,y;
  volatile uint16_t z;

  icr4h=(volatile char*)0xA7;
  icr4l=(volatile char*)0xA6;

  x=*icr4l;
  y=*icr4h;
  z=((y<<8)|x);
  Serial.print("the icr value is:");
  Serial.print(z);
  Serial.println();
  return z;
}


void clear_timer4(void)
{
  volatile char*tccr4a,*tccr4b,*timsk4,*tcnt4l,*tcnt4h,*icr4l,*icr4h;
  tccr4a=(volatile char*)0xA0;
  tccr4b=(volatile char*)0xA1;
  timsk4=(volatile char*)0x72;
  tcnt4l=(volatile char*)0xA4;
  tcnt4h=(volatile char*)0xA5;
  icr4l=(volatile char*)0xA6;
  icr4h=(volatile char*)0xA7;

 // *tccr4a=0x00;
  *tccr4b=0x00;
//  *timsk4=0x00;
  *tcnt4l=0x00;
  *tcnt4h=0x00;
  *icr4l=0x00;
  *icr4h=0x00;
  Serial.println("done clearing");
}

void delay_microsec(int x)
{
  volatile uint8_t i=2,y=0;
  volatile char*tccr0a,*tccr0b,*ocr0a,*timsk0;
  tccr0a=(volatile char*)0x44;
  tccr0b=(volatile char*)0x45;
  ocr0a=(volatile char*)0x47;
  timsk0=(volatile char*)0x6E;

  *tccr0a=0x02;//set in ctc mode
 // Serial.println("set in ctc successful");
  *tccr0b=0x02;//set prescalar 8
 // Serial.println("set the prescalar 8 succesful ");
  *ocr0a=(i*x);
  y=*ocr0a;
 // Serial.print("the value at ocr register: ");
 // Serial.print(y);
  //Serial.println();
  Serial.println("delayed micro successsfully");
  *timsk0=0x02;
 // Serial.println("delayed micro successsfully");
}

ISR(TIMER0_COMPA_vect)
{
  Serial.println("going to execute isr of delay timer 0");
  volatile long i;
 // Serial.println("done");
  volatile char*tccr0b,*tcnt0,*tifr0,*timsk0;
  tcnt0=(volatile char*)0x46;
  tccr0b=(volatile char*)0x45;
  tifr0=(volatile char*)0x35;
  timsk0=(volatile char*)0x6E;
  *tcnt0=0x00;
  *tccr0b=0x00;
  *timsk0=0x00;
 // Serial.println("set 0");
 // Serial.println();
  *tifr0=0x00;
  Serial.println("successfully stopped the timer0");
}

short set_echopin(void)
{
  volatile char*tccr4a,*tccr4b,*timsk4,*tifr4;
  tccr4a=(volatile char*)0xA0;
  tccr4b=(volatile char*)0xA1;
  timsk4=(volatile char*)0x72;
 // tifr4=(volatile char*)0x39;

  *tccr4a=0x00;
  *tccr4b=0x42;//prescalar 8 ,input capture mode rising edge;
  *timsk4=0x20;
  //*tifr4=0x20;
  sei();
  Serial.println("echo set successful");
  
}



ISR(TIMER4_CAPT_vect)
{
  Serial.println("going to execute isr echo");
 volatile static uint16_t rising_edge=0;
 volatile static uint16_t falling_edge=0;
 volatile char*tccr4b;
 tccr4b=(volatile char*)0xA1;

 if(*tccr4b==0x42)//rising edge
 {
   rising_edge=icr_value();//capture icr register value rising edge
   Serial.print("rising edge input capture register value:");
   Serial.print(rising_edge);
   Serial.println();
   *tccr4b=0x02;//change timer to detect falling edge
 }
 else
 {
   falling_edge=icr_value();//capture icr register value falling edge
    Serial.print("falling edge input capture register value:");
   Serial.print(falling_edge);
   Serial.println();

  volatile uint16_t duration=0;
   if(falling_edge>rising_edge){
    duration=(falling_edge-rising_edge)*0.5;
    Serial.print("rising edge duration value: ");
    Serial.print(duration);
    Serial.println();
   }
   else{
    duration=((0xFFFF-rising_edge)+falling_edge)*0.5;
    Serial.print("falling edge duration value: ");
    Serial.print(duration);
    Serial.println();
   }
   distance=duration*0.034/2;
   Serial.print("distance value in isr:");
   Serial.print(distance);
   Serial.println();
   clear_timer4();
   Serial.print("timer 4 is cleared successfully");
 }

}


void setup()
{
  Serial.begin(9600);
  sei();
  pin_configure();
  set_echopin();
  output1(0x00);
   delay_microsec(2);
   output1(0x01);
   delay_microsec(10);
   output1(0x00);
   delay_microsec(2);
   Serial.print(distance);
   Serial.print(" cm");
   Serial.println();
}

void loop()
{
   /*set_echopin();
   output1(0x00);
   delay_microsec(2);
   output1(0x01);
   delay_microsec(10);
   output1(0x00);
   delay_microsec(2);
   Serial.print(distance);
   Serial.print(" cm");
   Serial.println();*/

}
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
ultrasonic1:VCC
ultrasonic1:TRIG
ultrasonic1:ECHO
ultrasonic1:GND
led1:A
led1:C
r1:1
r1:2
led2:A
led2:C
r2:1
r2:2