#define F_CPU 8000000UL  //    
#include <avr/io.h> //   
#include <util/delay.h> //   
#include <avr/interrupt.h> //   
#define LED_pin PA5
#define LED_ON PORTA |=(1<<LED_pin)
#define LED_OFF PORTA &=(~(1<<LED_pin))
#define PWM_1 PB2 // OC0A (EN1)
#define PWM_2 PA7 // OC0B (EN2)
#define PWM_1_value OCR0A
#define PWM_2_value OCR0B
#define IN1 PA0 //  PORTA
#define IN2 PA1
#define IN3 PB1 //  PORTB
#define IN4 PB0
void delay_microsecond (unsigned int delay_time) { 
    
	
    for(unsigned int delay_us = 0; delay_us<delay_time; delay_us++) {
	
	    _delay_us(1);
	
	}
}
void delay_millisecond (unsigned int delay_time) { 
    for(unsigned int delay_ms = 0; delay_ms<delay_time; delay_ms++) {
	
	    _delay_ms(1);
	
	}
}
void step_1_one_phase (void) {
    PORTB &=(~((1<<IN3)|(1<<IN4)));
	
	PORTA &=(~(1<<IN2)); 
  
    PORTA |=(1<<IN1); 
}
void step_2_one_phase (void) {
    PORTA &=(~((1<<IN1)|(1<<IN2)));
	
	PORTB &=(~(1<<IN3));
  
    PORTB |=(1<<IN4);
  
}
void step_3_one_phase (void) {
    PORTB &=(~((1<<IN3)|(1<<IN4))); 
	 
	PORTA &=(~(1<<IN1));
  
    PORTA |=(1<<IN2);
  
	
}
void step_4_one_phase (void) {
    PORTA &=(~((1<<IN1)|(1<<IN2))); 
	
	PORTB &=(~(1<<IN4));
    
    PORTB |=(1<<IN3);
  
}
void step_1_two_phase (void) {
    PORTB |=(1<<IN4);  
  
    PORTB &=(~(1<<IN3));
  
    PORTA |=(1<<IN1);
  
    PORTA &=(~(1<<IN2));
}
void step_2_two_phase (void) {
    PORTA &=(~(1<<IN2));
	
	PORTA |=(1<<IN1);
  
    PORTB |=(1<<IN3);
  
    PORTB &=(~(1<<IN4));
  
}
void step_3_two_phase (void) {
    PORTB |=(1<<IN3);
  
    PORTB &=(~(1<<IN4));
	
	PORTA &=(~(1<<IN1));
  
    PORTA |=(1<<IN2);
  
	
}
void step_4_two_phase (void) {
    PORTA |=(1<<IN2);
  
    PORTA &=(~(1<<IN1));
    
    PORTB |=(1<<IN4);
  
    PORTB &=(~(1<<IN3));
  
}
void stepper_OFF (void) { 
	
	
	PORTA &=(~((1<<IN1)|(1<<IN2)));
	
	PORTB &=(~((1<<IN3)|(1<<IN4)));
	
}
unsigned char step_counter = 0; 
void L293D_step (unsigned int step_quantity, unsigned char direction, unsigned int step_delay, unsigned char phase) { 
    while(step_quantity>0) { 
        switch(direction) { 
	
			case 'F':
				if(step_counter<3) { step_counter++; } else { step_counter=0; }
			break;
		
			case 'B':
				if(step_counter>0) { step_counter--; } else { step_counter=3; }
			break;
		
		}
		
		switch(phase) { 
		
		    case 1: 
			
				switch(step_counter) { 
	
					case 0:
						step_1_two_phase_DL();
					break;
		
					case 1:
						step_2_two_phase_DL();
					break;
		
					case 2:
						step_3_two_phase_DL();
					break;
		
					case 3:
						step_4_two_phase_DL();
					break;
	
				}
			
			break;
			
			case 2:
			
				switch(step_counter) { 
	
					case 0:
						step_1_two_phase_DL();
					break;
		
					case 1:
						step_2_two_phase_DL();
					break;
		
					case 2:
						step_3_two_phase_DL();
					break;
		
					case 3:
						step_4_two_phase_DL();
					break;
	
				}
			
			break;
		
		}
		
    delay_millisecond(step_delay); 
	
	step_quantity--; 
	
	} 
}
void PWM_init (void) { 
    DDRB |=(1<<PWM_1);
    DDRA |=(1<<PWM_2);
    TCCR0A = (1<<WGM01)|(1<<WGM00)|(1<<COM0A1)|(0<<COM0A0)|(1<<COM0B1)|(0<<COM0B0); 
	
    TCCR0B = (0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00); 
	
    OCR0A = 255; 
    OCR0B = 255;
} 
int main (void) { 
    DDRA |=(1<<LED_pin);
	
    DDRA |=(1<<IN1)|(1<<IN2);
    DDRB |=(1<<IN3)|(1<<IN4);
	
    PWM_init(); 
	
    delay_millisecond(2000);
	
    while(1==1) { 
	   
	LED_ON;
		
        L293D_step(16,'F',100,2); 
		
	
		
	delay_millisecond(2000);
		
	LED_OFF;
		
	L293D_step(16,'B',100,2);
		
	
		
	delay_millisecond(2000);
		  
    } 
}