/*
 * TB6560.c
 *
 * Created: 21.08.2015 17:00:04
 *  Author: Chris
 */ 
 

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

const uint16_t Ramp[] = {				// Beschleunigungsrampe
55956,42067,33733,28178,24210,21233,18919,17067,15552,14289,13221,12305,11511,10817,10204,9659,9172,8733,8337,7976,7646,7344,
7067,6810,6573,6352,6147,5956,5776,5608,5451,5302,5162,5030,4905,4786,4674,4567,4465,4368,4276,4188,4104,4023,3946,3872,3801,
3733,3668,3605,3545,3486,3430,3376,3324,3274,3225,3178,3132,3088,3046,3004,2964,2925,2888,2851,2815,2781,2747,2715,2683,2652,
2622,2593,2565,2537,2510,2483,2458,2433,2408,2384,2361,2338,2316,2294,2273,2252,2232,2212,2192,2173,2154,2136,2118,2101,2084,
2067,2050,2034,
};

volatile uint16_t speed=55956;				//Frequenz
volatile uint8_t a_timer=0, b_timer=99;		//Variablen für Beschleunigung/Bremsen
volatile uint8_t status=1;					//Status
volatile uint16_t i=0;						//Variable für Schritte zählen 

////////////////////////////////////////////////////////////////////////// Delay

void delay_us(uint16_t ms){
	for (uint16_t t=0; t<=ms;t++){
		_delay_us(1);
	}
}

void delay_ms(uint16_t ms){
	for (uint16_t t=0; t<=ms;t++){
		_delay_ms(1);
	}
}

////////////////////////////////////////////////////////////////////////// Beschleunigung
void a_fast(void){							
	if (a_timer < 98){
		a_timer++;
		speed = Ramp[a_timer];
	}
	else{
		status++;
	}
}

////////////////////////////////////////////////////////////////////////// Bemsen
void b_fast(void){
	if (b_timer > 0){
		b_timer--;
		speed = Ramp[b_timer];
	}
	else{
		status++;	
	}
}

////////////////////////////////////////////////////////////////////////// Step
void step(uint16_t steps){
	if (steps > i){
	PORTD ^= (1 << PD5);
	}
	i++;
}


////////////////////////////////////////////////////////////////////////// Timer/Counter1 Compare Match
ISR (TIMER1_COMPA_vect)		// Stepfrequenz
{	
	PORTD ^= (1 << PD5);
}

////////////////////////////////////////////////////////////////////////// Timer/Counter0 Overflow
ISR (TIMER0_OVF_vect){		
	
	switch (status){
		case 1 : status=1;a_fast();break;
		case 2 : b_fast();break;
		case 3 : status=1;PORTD ^= (1 << PD4);delay_ms(500);a_timer=0;b_timer=99;break;
	}
	
}


int main()
{

	DDRD = (1 << DDD5) | (1 << DDD4);		// PD5=Step PD4=Dir Ausgang

	delay_ms(500);
	
	////////////////////////////////////////////////////////////////////////// Timer 1
	
	TIMSK |=  (1 << OCIE1A) | (1 << TOIE1);		// Output Compare A Match Interrupt Enable
	OCR1A = (uint16_t)(0.5*speed);				// Frequenz
	TCCR1B |= (1 << WGM12);						// CTC Modus
	TCCR1B |= (1 << CS10);						// Prescaler: 1/8
	
	////////////////////////////////////////////////////////////////////////// Timer 0	
			
	TIMSK |= (1 << TOIE0);					// IRQ bei Überlauf 
 	TCCR0 |= (1 << CS02);					// Prescaler: 1/1024
	
	sei();									// IRQs enable

	while (1){				// endlos
 		
		OCR1A = (uint16_t)(0.5*speed);		// Vergleichswert einstellen
	
 	}
	
}