US – Code – Measure.c

/*
 * US_measure.c
 *
 * Created: 20-08-17 09:05:59
 *  Author: raspi.th.in
 */ 
#include "US_measure.h"
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
typedef enum
{
	START,
	STOP,
	DONE,
	OV_ERROR,	
}
US_measure_STATE;
uint16_t US1_value,US2_value;
volatile US_measure_STATE US1_state,US2_state;

 ISR(TIMER1_CAPT_vect)
 {
	 switch (US1_state)
	 {
		case START:
			US1_value=ICR1;
			US1_state=STOP;
			TCCR1B=0x02;//falling edge on ICP1;clk/8
		break;
		case STOP:
			US1_value=ICR1-US1_value;
			US1_state=DONE;
			TIMSK1=0;//disable timer 1 interrupts
		break;
		case DONE:
		break;
		case OV_ERROR:
			//US1_value=65535;
		break;
	 }
 }
 
 ISR(TIMER2_CAPT_vect)
 {
	switch (US2_state)
	{
		case START:
			US2_value=ICR2;
			US2_state=STOP;
			TCCR2B=0x02;//falling edge on ICP2;clk/8
		break;
		case STOP:
			US2_value=ICR2-US2_value;
			US2_state=DONE;
			TIMSK2=0;	 //disable timer2 interrupts
		break;
		case DONE:
		break;
		case OV_ERROR:
			//US2_value=65535;
		break;
	}
 }
 ISR (TIMER1_OVF_vect)
 {
	 US1_state=OV_ERROR;
 }
 
 ISR(TIMER2_OVF_vect)
 {
	 US2_state=OV_ERROR;
 }
 
 void US_measure_init(US_MEASURE_TYPE my_type)
{
	TIMSK2=0;
	TIMSK1=0;
	TIFR1=0xFF;
	TIFR2=0xFF;
	US2_value=0;
	US1_value=0;
	TCNT1=0;
	TCNT2=0;
	TCCR1B=0;
	TCCR2B=0;

	US1_state=START;
	US2_state=START;

	switch (my_type)
	{
		case ONE:
			TCCR2B=0;//stop timer2
			TCCR1B=0x42;//rising edge on ICP1;clk/8
			TIMSK1=0x21;//interrupt on ICP1 and ov1
			US2_state=DONE;
		break;
		case TWO:
			TCCR1B=0;//stop timer1
			TCCR2B=0x42;//rising edge on ICP2;clk/8
			TIMSK2=0x21;//interrupt on ICP2 and ov2
			US1_state=DONE;
		break;	
		case BOTH:
			TCCR1B=0x42;//rising edge on ICP1;clk/8
			TCCR2B=0x42;//rising edge on ICP2;clk/8
			TIMSK1=0x21;//interrupt on ICP1 and ov1
			TIMSK2=0x21;//interrupt on ICP2 and ov2
		break;
	}
 }
 
void US_Do_measure(US_MEASURE_TYPE my_type)
 {
	uint8_t i;

	PORTA|=0x01;//set trigger
	for(i=0;i<29;i++);
	US_measure_init(my_type);
	PORTA&=~(0x01);//reset trigger
 }
 
 uint8_t  US_Check_measure(US_Measure_value *my_result)
 {
	  
	if((US1_state<DONE)||(US2_state<DONE)) return 1;
	if(US1_state==DONE)
	{
		my_result->US1_status=US_OK;
		my_result->US_1=US1_value;
	}
	else
	{
		my_result->US1_status=ERROR;	
		US1_value=65535;
	}
	if(US2_state==DONE)
	{
		my_result->US2_status=US_OK;
		my_result->US_2=US2_value;
	}
	else
	{
		my_result->US2_status=ERROR;
		US2_value=65535;
	}
	
	
return 0;
 }