//*****************************************************************************
// File Name	: SteppingMotor.c
// 
// Title		: SteppingMotor
// Revision		: 1.0
// Notes		:	
// Target MCU	: Atmel AVR AT Tiny2313
// Editor Tabs	: 4
// 
// Revision History:
// When			Who			Description of change
// -----------	-----------	-----------------------
// 20-Dec-2007	Junichi Nagayama	Created the program
//*****************************************************************************


//	Port pins
//	1:xReset		Reset
//	2:PD0(RxD)		X
//	3:PD1(TxD)		Y
//	4:XTAL2			
//	5:XTAL1			
//	6:PD2(INT0)		/X
//	7:PD3(INT1)		/Y
//	8:PD4(T0)		
//	9:PD5(T1)		DriveSelect
//	10:GND
//	11:PD6(ICP)		
//	12:PB0(AIN0)	
//	13:PB1(AIN1)	
//	14:PB2			
//	15:PB3(OC1)		
//	16:PB4			
//	17:PB5(MOSI)	
//	18:PB6(MISO)	
//	19:PB7(SCK)		
//	20:VCC


//----- Include Files ---------------------------------------------------------
#include <avr/io.h>		// include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h>	// include interrupt support

#include "global.h"		// include our global settings

char __attribute__((section(".eeprom"))) val[] = { 0 };

void SteppingMotor(void);

volatile u08	timerFlag;
int interval;

//----- Begin Code ------------------------------------------------------------


SIGNAL(SIG_OUTPUT_COMPARE1A)
{
	timerFlag = 1;
	outb(TCNT1L, 0);		// reset TCNT1
	outb(TCNT1H, 0);		// reset TCNT1
}

int main(void)
{
	cli();
	
	// initialize
	timerFlag = 0;
	interval = 0x8;
	
	outb(TCCR1A, 0);
	outb(TCCR1B, 0x05);		// TIMER1_CLK_DIV1024
	outb(TCCR1C, 0x80);
	OCR1A = interval;		// set OCR1A
	TCNT1 = 0;				// reset TCNT1
	sbi(TIMSK, OCIE1A);		// enable TCNT1 compare match
	
	sei();
	
	// set port pins to output
	outb(DDRB,  0xff);			// All output
	outb(DDRD,  0b11011111);	// PD5 in / others out
	outb(PORTB, 0x00);			// All Zero as initial value
	outb(PORTD, 0b00100000);	// Pull up 
	
	// begin main loop
	SteppingMotor();

	return 0;
} 

void SteppingMotor(void)
{
	int i = 0;
	int j = 0;
	int direction = 1;
	int rotation = 16;
	int rot = 0;
	char step[]  = { 0x01, 0x02, 0x04, 0x08 }; 
	char step1[] = { 0x03, 0x06, 0x0c, 0x09 }; 
	char step2[] = { 0x09, 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08 }; 
	
	while(1) {
		if ((j % 90) == 89) {
			if (j == 359) j = -1;
			rot++;
			if (rot >= rotation) {
				interval <<= 1;
				rotation >>= 1;
				if (interval > 0x100) {
					interval = 0x8;
					rotation = 16;
					direction *= -1;
				}
				OCR1A = interval;
				TCNT1 = 0;
				rot = 0;
			}
		}
		j++;
		
		if (PIND & 0b00100000) {
			PORTD = step2[i];
			i += direction;
			i &= 0x7;
			
			while(!timerFlag);
			timerFlag = 0;
		} else {
			PORTD = step1[i];
			i += direction;
			i &= 0x3;
			
			while(!timerFlag);
			timerFlag = 0;
			while(!timerFlag);
			timerFlag = 0;
		}
	}
}
