//Distributed under the GPL v 2.0
//by fenn 02/15/07
//step/dir counter using only one external interrupt
//this code was written for an attiny26 and hasnt been thoroughly tested
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char pos=0;

#define SETBIT(PORT, BIT)  PORT |= (1<<BIT)
#define CLRBIT(PORT, BIT)  PORT &= ~(1<<BIT)

#define ISSET(PORT, BIT)  (PORT & (1<<BIT)) 
//if (ISSET(PIND, 2)) ...
#define ISNSET(PORT, BIT)  !(PORT & (1<<BIT)) 

/* pinout */
#define LED PA0
#define STEP PB4
#define DIR PB5
#define STEPDIR_PORT PINB

//SIGNAL(SIG_PIN_CHANGE)
SIGNAL(SIG_INTERRUPT0)
{ //update the position
	if((ISSET(STEPDIR_PORT, DIR))
	{ pos++; }
	else
	{ pos--; }
	//PORTA ^= 1<<LED; //toggle the LED pin
}

int main(void)
{   //set outputs on port A, others are inputs
	DDRA=	(1<<LED) |
			(1<<PA4) |
			(1<<PA5) |
			(1<<PA6) |
			(1<<PA7); 
	//DDRA=0xFF; //set port A to output
	sei(); //global interrupt enable
	GIMSK |= (1<<INT0); // turn on interrupt 0
	MCUCR |= (0<<ISC01) | (1<<ISC00); //interrupt on any change of int0 (pb6)
	//MCUCR |= (1<<ISC01) | (1<<ISC00); //interrupt on rising edge of int0 (pb6); gives half the resolution
	while (1)
	{
		//PORTA = pos; //show our current position
		PORTA=(pos<<4 & 0xF0); //show position in binary on PA4-PA7
	}
}

