/*
 * krokove_motory_1.cpp
 *
 * Created: 25.2.2013 21:18:54
 *  Author: Jirka
 */ 

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <stdio.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "SPI.h"
#include "driver.h"
#include "ks0108.h"
#include "avrlcd.h"
#include "avrlcd_fonts.h"
#include "avrlcd_ctrls.h"
#include "font.h"

//============Deklarace funkci============
void driver_init (void);
void display_driver_sets (void);
void display_status (void);
void display_menu (char set1, char set2);

//==========Deklarace promnnych==========
char submenu1 = 2;
char menu = 0;
//char inter_status = 0;
char inter_menu = 0;	

int main(void)
{
	//===========================================================================
	current_font = font13;
	SPI_init();							// Inicializace SPI
	ks0108SetReset(1);					// Reset nastavim na HIGH a tak musi i zustat
	_delay_ms(1000);					// Cekam nez LCD "nabehne:"
	ks0108Init(NON_INVERTED);			// Inicializace driveru LCD
	driver_init();						// Inicializace driveru pro KM
	_delay_ms(100);
	//===========================================================================
	DDRD = 0x00;						// Vstupy pro lacitka
	PORTD = 0xFF;						// Hi-Z pro tlacitka
	DDRB |= (1<<DDB0);					// Vystup pro step clock mode
	PORTB &= ~(1<<DDB0);
	sei();
	EIMSK |= (1<<INT0) | (1<<INT1);		// Povoleni externich preruseni
	EICRA |= (1<<ISC01) | (1<<ISC11);	// Nastaveni hran pro preruseni
	//===========================================================================
	ks0108ClearScreen();
	draw_text(34, 15, 127, 12, "Driver L6470", DT_NORMAL);
	draw_text(2, 45, 127, 12, "Jiri Mostek & Jan Kohnheiser", DT_NORMAL);
	_delay_ms(3000);
	ks0108ClearScreen();
	//===========================================================================

    while(1)
    {	
		SoftStop();
		ks0108ClearScreen();
		display_menu(0,0);
		
		while(menu == 0)						// Volba v Menu
		{			
			if (bit_is_clear(PIND, 7))
			{
				_delay_ms(400);
				if (bit_is_clear(PIND, 7))
				{
					menu = 2;
				}
				else
				{
					menu = 1;
				}
			}
			
			
			if (bit_is_clear(PIND, 6))
			{
				_delay_ms(400);
				if (bit_is_clear(PIND, 6))
				{
					menu = 4;
				}
				else
				{
					menu = 3;
				}				
			}
			
			if (bit_is_clear(PIND, 5))
			{
				_delay_ms(20);
				menu = 5;
			}
		}
		
		switch (menu)
		{
			case 1:	ks0108ClearScreen();						// Volba 1, Normal mode
					display_menu(1,2);
					while (menu == 1)
					{
						if (bit_is_clear(PIND, 7))
						{
							_delay_ms(10);
							Run(FORWARD, 0xFFFF);
							display_menu(1,1);
							submenu1 = 1;
							_delay_ms(10);
						}
					
						if (bit_is_clear(PIND, 6))
						{
							_delay_ms(10);
							SoftStop();
							display_menu(1,2);
							submenu1 = 2;
							_delay_ms(10);
						}
					
						if (bit_is_clear(PIND, 5))
						{
							_delay_ms(10);
							Run(BACKWARD, 0xFFFF);
							display_menu(1,3);
							submenu1 = 3;
							_delay_ms(10);
						}
					}
					break;
					
			case 2:	ks0108ClearScreen();						// Volba 2, Step mode
					display_menu(2,0);
					SoftHiZ();
					SetParam(STEP_MODE, STEP_SEL_FULL_STEP, VALUE_NULL, VALUE_NULL);
					while (menu == 2)
					{
						if (bit_is_clear(PIND, 7))
						{
							_delay_ms(10);
							StepClock(FORWARD);
							_delay_ms(40);
							for (int count = 0 ; count < 100 ; count++)
							{
								PORTB ^= (1<<DDB0);
								_delay_ms(5);
							}
						}	
						
						if (bit_is_clear(PIND, 5))
						{
							_delay_ms(10);
							StepClock(BACKWARD);
							_delay_ms(40);
							for (int count = 0 ; count < 100 ; count++)
							{
								PORTB ^= (1<<DDB0);
								_delay_ms(5);
							}
						}
					}
					
			case 3:	ks0108ClearScreen();						// Volba 3, Demo 1
					display_menu(3,0);
					while (menu == 3)
					{
						if (inter_menu == 0)
						{
							Run(FORWARD, 0x9FFF);
							_delay_ms(10000);
						}
						if (inter_menu == 0)
						{
							Run(BACKWARD, 0x9FFF);
							_delay_ms(10000);
						}
						if (inter_menu == 0)
						{
							Run(FORWARD, 0x2FFF);
							_delay_ms(10000);
						}
						if (inter_menu == 0)
						{
							Run(BACKWARD, 0x2FFF);
							_delay_ms(10000);
						}
						inter_menu = 0;
					}
					break;
					
			case 4:	ks0108ClearScreen();						// Volba 4, Demo 2
					display_menu(4, 0);
					while (menu == 4)
					{
						if (inter_menu == 0)
						{
							Run(FORWARD, 0x9FFF);
							_delay_ms(10000);
							HardStop();
						}
						if (inter_menu == 0)
						{
							Run(BACKWARD, 0x9FFF);
							_delay_ms(10000);
							HardStop();
						}
						if (inter_menu == 0)
						{
							Run(FORWARD, 0x00FF);
							_delay_ms(10000);
						}
						if (inter_menu == 0)
						{
							Run(BACKWARD, 0x00FF);
							_delay_ms(10000);
						}
						inter_menu = 0;
					}	
					break;
					
			case 5:	display_driver_sets();						// Volba 5, Zobrazi nastaveni registru
					menu = 0;
					break;
		}
    }
}

void driver_init (void)							// Nastaveni driveru
{
	SetParam(OCD_TH, NO_PRESETS, 0b00000011, VALUE_NULL);
	SetParam(STALL_TH, NO_PRESETS, 0b00100100, VALUE_NULL);
	SetParam(KVAL_RUN, NO_PRESETS, 0x07, VALUE_NULL);
	SetParam(KVAL_ACC, NO_PRESETS, 0x05, VALUE_NULL);
	SetParam(KVAL_DEC, NO_PRESETS, 0x05, VALUE_NULL);
	SetParam(KVAL_HOLD, NO_PRESETS, 0x10, VALUE_NULL);
	SetParam(MAX_SPEED, NO_PRESETS, 0x3FF, VALUE_NULL);
	SetParam(MIN_SPEED, LSPD_OPT_ON, 0x00, VALUE_NULL);
	SetParam(ACC, NO_PRESETS, 0x30, VALUE_NULL);
	SetParam(DEC, NO_PRESETS, 0x30, VALUE_NULL);
	
	SoftHiZ();
	SetParam(STEP_MODE, STEP_SEL_HALF_STEP, VALUE_NULL, VALUE_NULL);
	SoftStop();
}
void display_driver_sets (void)					// Zobrazeni nastavenych dat
{
	unsigned int a = 0;
	unsigned int b = 0;
	unsigned int c = 0;
	unsigned int d = 0;
		
	char text1 [20];
	char text2 [20];
	char text3 [20];
	char text4 [20];
	//-------------------------------------------------------------------------
	ks0108ClearScreen();
	draw_text(34, 15, 127, 12, "Driver L6470", DT_NORMAL);
	draw_text(2, 45, 127, 12, "Jiri Mostek & Jan Kohnheiser", DT_NORMAL);
	
	_delay_ms(3000);
	ks0108ClearScreen();
	//-------------------------------------------------------------------------
	a = GetParam(OCD_TH)*375;
	sprintf(text1, "  OCD_TH: %d mA", a);
	b = GetParam(STALL_TH)*31;
	sprintf(text2, "  STALL_TH: %d mA", b);
	c = GetParam(CONFIG);
	sprintf(text3, "  CONFIG: %d", c);
	d = GetParam(STEP_MODE);
	sprintf(text4, "  STEP_MODE: %d", d);
		
	draw_text(0, 2, 127, 12, text1, DT_NORMAL);
	draw_text(0, 15, 127, 12, text2, DT_NORMAL);
	draw_text(0, 28, 127, 12, text3, DT_NORMAL);
	draw_text(0, 41, 127, 12, text4, DT_NORMAL);
		
	_delay_ms(800);
	//-------------------------------------------------------------------------
	a = GetParam(KVAL_ACC);
	sprintf(text1, "  KVAL_ACC: %d", a);
	b = GetParam(KVAL_DEC);
	sprintf(text2, "  KVAL_DEC: %d", b);
	c = GetParam(KVAL_HOLD);
	sprintf(text3, "  KVAL_HOLD: %d", c);
	d = GetParam(KVAL_RUN);
	sprintf(text4, "  KVAL_RUN: %d", d);
		
	draw_text(0, 2, 127, 12, text1, DT_NORMAL);
	draw_text(0, 15, 127, 12, text2, DT_NORMAL);
	draw_text(0, 28, 127, 12, text3, DT_NORMAL);
	draw_text(0, 41, 127, 12, text4, DT_NORMAL);
		
	_delay_ms(800);
	//-------------------------------------------------------------------------
	a = GetParam(FN_SLP_ACC);
	sprintf(text1, "  FN_SLP_ACC: %d", a);
	b = GetParam(FN_SLP_DEC);
	sprintf(text2, "  FN_SLP_DEC: %d", b);
	c = GetParam(INT_SPEED);
	sprintf(text3, "  INT_SPEED: %d", c);
	d = GetParam(ST_SLP);
	sprintf(text4, "  ST_SLP: %d", d);
		
	draw_text(0, 2, 127, 12, text1, DT_NORMAL);
	draw_text(0, 15, 127, 12, text2, DT_NORMAL);
	draw_text(0, 28, 127, 12, text3, DT_NORMAL);
	draw_text(0, 41, 127, 12, text4, DT_NORMAL);
		
	_delay_ms(800);
	ks0108ClearScreen();
}				
void display_status (void)						// Vykresli kontrolky Status registru
{
	ks0108ClearScreen();
	int stat_reg;
	int stat_reg_zal;
	stat_reg = GetStatus();
	stat_reg_zal = stat_reg>>8;
	//inter_status = 1;
	
	if(bit_is_set(stat_reg, 0))													//HiZ
	{	ctrl_button(94, 47, 31, 13, "HiZ", CTRL_PRESSED);		}				
	else
	{	ctrl_button(94, 47, 31, 13, "   ", CTRL_PRESSED);		}
	
	if(bit_is_set(stat_reg, 1))													//Busy
	{	ctrl_button(63, 47, 31, 13, "Free", CTRL_PRESSED);		}				
	else
	{	ctrl_button(63, 47, 31, 13, "Busy", CTRL_PRESSED);		}
	
	if(bit_is_set(stat_reg, 2))													//Switch state
	{	ctrl_button(32, 47, 31, 13, "Sw-Cl", CTRL_PRESSED);		}				
	else
	{	ctrl_button(32, 47, 31, 13, "Sw-Op", CTRL_PRESSED);		}
	
	if(bit_is_set(stat_reg, 3))													//Switch - pressed
	{	ctrl_button(1, 47, 31, 13, "Sw-pr", CTRL_PRESSED);		}				
	else
	{	ctrl_button(1, 47, 31, 13, "   ", CTRL_PRESSED);		}
	
	
	if(bit_is_set(stat_reg, 4))													//Direction
	{	ctrl_button(94, 32, 31, 13, "Forw", CTRL_PRESSED);		}				
	else
	{	ctrl_button(94, 32, 31, 13, "Backw", CTRL_PRESSED);		}
	
	if(bit_is_set(stat_reg, 5))													//Motor Status
	{	if(bit_is_set(stat_reg, 6))		{	ctrl_button(32, 32, 62, 13, "Const Speed", CTRL_PRESSED);		}
		else							{	ctrl_button(32, 32, 62, 13, "Acceler", CTRL_PRESSED);			}	}
	else
	{	if(bit_is_set(stat_reg, 6))		{	ctrl_button(32, 32, 62, 13, "Deceler", CTRL_PRESSED);			}		
		else							{	ctrl_button(32, 32, 62, 13, "Stoped", CTRL_PRESSED);			}	}
					
	if(bit_is_set(stat_reg, 7))													//Not Performed Comand
	{	ctrl_button(1, 32, 31, 13, "C-NP", CTRL_PRESSED);	}		
	else
	{	ctrl_button(1, 32, 31, 13, "C-OK", CTRL_PRESSED);	}
	
	
	if(bit_is_set(stat_reg_zal, 0))												//Wrong Comand
	{	ctrl_button(94, 17, 31, 13, "C-WR", CTRL_PRESSED);	}
	else
	{	ctrl_button(94, 17, 31, 13, "C-OK", CTRL_PRESSED);	}
	
	if(bit_is_set(stat_reg_zal, 1))												//Under Voltage
	{	ctrl_button(63, 17, 31, 13, "Vo-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(63, 17, 31, 13, "UVLO", CTRL_PRESSED);	}
	
	if(bit_is_set(stat_reg_zal, 2))												//Theraml Warning
	{	ctrl_button(32, 17, 31, 13, "T-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(32, 17, 31, 13, "T-WA", CTRL_PRESSED);	}
				
	if(bit_is_set(stat_reg_zal, 3))												//Thermal Shut Down
	{	ctrl_button(1, 17, 31, 13, "T-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(1, 17, 31, 13, "T-SD", CTRL_PRESSED);	}
			
	if(bit_is_set(stat_reg_zal, 4))												//Over Current Detection
	{	ctrl_button(94, 2, 31, 13, "Cu-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(94, 2, 31, 13, "OCD", CTRL_PRESSED);	}
				
	if(bit_is_set(stat_reg_zal, 5))												//Step Loss Brdge A
	{	ctrl_button(63, 2, 31, 13, "SL-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(63, 2, 31, 13, "SL-A", CTRL_PRESSED);	}
				
	if(bit_is_set(stat_reg_zal, 6))												//Step Loss Bridge B
	{	ctrl_button(32, 2, 31, 13, "SL-OK", CTRL_PRESSED);	}
	else
	{	ctrl_button(32, 2, 31, 13, "SL-B", CTRL_PRESSED);	}
	
	if(bit_is_set(stat_reg_zal, 7))												//Step Clock Mode
	{	ctrl_button(1, 2, 31, 13, "SCKM", CTRL_PRESSED);	}
	else
	{	ctrl_button(1, 2, 31, 13, "Norm", CTRL_PRESSED);	}

	_delay_ms(20000);
	ks0108ClearScreen();	
	
	display_menu(menu, submenu1);													//obnoveni posledniho nastaveni
}
void display_menu (char set1, char set2)		// Zobrazi posledni menu (napr. pred prerusenim)
{
	switch (set1)
	{
		case 0:	draw_text(0, 0, 80, 12, "  1.  Normal mode", DT_NORMAL);
				draw_text(80, 0, 40, 12, "TL1  - ", DT_NORMAL);
				draw_text(0, 13, 80, 12, "  2.  Step mode", DT_NORMAL);
				draw_text(80, 13, 40, 12, "TL1 ---", DT_NORMAL);
				draw_text(0, 26, 80, 12, "  3.  Demo 1", DT_NORMAL);
				draw_text(80, 26, 40, 12, "TL2  - ", DT_NORMAL);
				draw_text(0, 39, 80, 12, "  4.  Demo 2", DT_NORMAL);
				draw_text(80, 39, 40, 12, "TL2 ---", DT_NORMAL);
				draw_text(0, 52, 80, 12, "  5.  Settings", DT_NORMAL);
				draw_text(80, 52, 40, 12, "TL3", DT_NORMAL);
																				break;
		case 1:	draw_text(35, 2, 58, 11, "Normal mode", DT_INVERT);
				line(0, 41, 127, 41, BLACK);
				switch(set2)
				{
					case 1:	ctrl_button(2, 45, 36, 13, "FOR", CTRL_PRESSED);
							ctrl_button(44, 45, 36, 13, "STOP", CTRL_NORMAL);
							ctrl_button(86, 45, 36, 13, "BACK", CTRL_NORMAL);	break;
					case 2:	ctrl_button(2, 45, 36, 13, "FOR", CTRL_NORMAL);
							ctrl_button(44, 45, 36, 13, "STOP", CTRL_PRESSED);
							ctrl_button(86, 45, 36, 13, "BACK", CTRL_NORMAL);	break;
					case 3:	ctrl_button(2, 45, 36, 13, "FOR", CTRL_NORMAL);
							ctrl_button(44, 45, 36, 13, "STOP", CTRL_NORMAL);
							ctrl_button(86, 45, 36, 13, "BACK", CTRL_PRESSED);	break;
					default:													break;
				}																break;
		case 2:	draw_text(35, 2, 58, 11, "   Step mode ", DT_INVERT);					
				ctrl_button(2, 45, 54, 13, "ST  FOR", CTRL_NORMAL);	
				ctrl_button(70, 45, 54, 13, "ST  BACK", CTRL_NORMAL);			break;		
		case 3: draw_text(43, 2, 42, 11, "   Demo 1  ", DT_INVERT);				break;
		case 4: draw_text(43, 2, 42, 11, "   Demo 2  ", DT_INVERT);				break;
		case 5:	display_driver_sets();											break;
		default:																break;
	}
}
ISR(INT0_vect)									// Navrat do Menu
{
	SoftStop();
	if (menu != 0)
	{
		ks0108ClearScreen();
	}	
	menu = 0;	
	inter_menu = 1;
}
ISR(INT1_vect)									// Zobrazeni Status registru
{
	display_status();
}