//ICC-AVR application builder : 2011-01-29 ¿ÀÀü 11:28:32
// Target : M128
// Crystal: 16.000Mhz

#include <iom128v.h>
#include <macros.h>
#include <stdio.h>

#define LEDPORT	   PORTB
#define RST(m)	   m? (LEDPORT|=0x80):(LEDPORT&=0x7F)
#define CS0(m)	   m? (LEDPORT|=0x10):(LEDPORT&=0xEF)
#define CS1(m)	   m? (LEDPORT|=0x20):(LEDPORT&=0xDF)
#define CS2(m)	   m? (LEDPORT|=0x40):(LEDPORT&=0xBF)

volatile unsigned char R_level[32], G_level[32], B_level[32], c;
volatile unsigned i=0;

void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x06;
 UBRR0L = 0x67; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x98;
}

#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
 //uart has received a character in UDR
 while(!((UCSR0A&0x80)==0x80));
 c=UDR0;
 if(c == 'a'){
    if(i<30) i++;
 }
 else if(c == 'z'){
    if(i>0) i--;
 }
 else if(c == '0') i=0;
 else if(c == '1') i=3;
 else if(c == '2') i=7;
 else if(c == '3') i=10;
 else if(c == '4') i=13;
 else if(c == '5') i=17;
 else if(c == '6') i=20;
 else if(c == '7') i=23;
 else if(c == '8') i=27;
 else if(c == '9') i=31;
}

int putchar(char c)
{
	while (((UCSR0A>>UDRE0)&0x01) == 0) ;  // UDRE, data register empty
    UDR0 = c;
    return c;
}

int getchar(void)
{
    while ((UCSR0A & 0x80) == 0);
    return UDR0;
}

void delay_LED(void)
{
    int i;	
	for( i=0 ; i<100 ; i++ );
}

void delay_SPI(void)
{
    int i;	
	for( i=0 ; i<100 ; i++ );
}

void delay(unsigned int time)
{
    int i;
	for(i=0;i<time;i++);
}

void level_init(void)
{
 	int i;
	for(i=0;i<32;i++){
	   R_level[i]=i;
	   G_level[i]=i;
	   B_level[i]=i;
	}
}

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x01;
 DDRB  = 0x36;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
 PORTE = 0x00;
 DDRE  = 0x00;
 PORTF = 0x00;
 DDRF  = 0x00;
 PORTG = 0x00;
 DDRG  = 0x00;
}

//SPI initialize
// clock rate: 4000000hz
void spi_init(void)
{
 SPCR = 0x5C; //setup SPI
 SPSR = 0x00; //setup SPI
 DDRB=0xff;
 PORTB=0xff;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();
 spi_init();
 uart0_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

unsigned char SPI_Tx(unsigned char instruction)
{
 SPDR = instruction;
 while( !(SPSR&0x80) );
 return SPDR;
}

void send(unsigned char CS, unsigned char instruction){
	 switch(CS){
	 	case 0 : CS0(0); delay_SPI();
	 	  	   	 SPI_Tx(instruction);
	 			 CS0(1); delay_SPI();
				 break;
				 
		case 1 : CS1(0); delay_SPI();
	 	  	   	 SPI_Tx(instruction);
	 			 CS1(1); delay_SPI();
				 break;
				 
		case 2 : CS2(0); delay_SPI();
	 	  	   	 SPI_Tx(instruction);
	 			 CS2(1); delay_SPI();
				 break;
				 
		default : break;
	}		
}

void color(unsigned char chip, unsigned char R, unsigned char G, unsigned char B)
{
 switch(chip){
    case 0 : send(0,0x00|R);
	  	   	 send(0,0x20|G);
			 send(0,0x40|B);
			 break;
			 
	case 1 : send(1,0x00|R);
	  	   	 send(1,0x20|G);
			 send(1,0x40|B);
			 break;
			 
	case 2 : send(2,0x00|R);
	  	   	 send(2,0x20|G);
			 send(2,0x40|B);
			 break;
			 
    default : break;
 }
}

void LEDdriver_init(void)
{
 RST(0);
 delay_LED();
 RST(1);
 
 send(0,0x6f);
 send(0,0x81);
 send(0,0xa2);
 send(0,0xc3);
 
 send(1,0x6f);
 send(1,0x81);
 send(1,0xa1);
 send(1,0xc1);
 
 send(2,0x6f);
 send(2,0x81);
 send(2,0xa1);
 send(2,0xc1);
}

//
void main(void)
{
 char a=0;
 init_devices();
 
 //insert your functional code here...
 LEDdriver_init();
 level_init();
 //color(0,0,0,31);
 //color(1,31,0,0);
 //color(2,0,31,0);
 DDRG=0x03;
 printf("asdf");
 while(1)
 {
    color(0,R_level[i],G_level[i],B_level[i]);
	color(1,R_level[31-i],G_level[31-i],B_level[31-i]);
	color(2,R_level[i],G_level[i],B_level[i]);
	
	if(((PING&0x0C)>>2) == 0x01){
	   while(!(((PING & 0x0c)>>2) == 0x00));
	   if(i<30) i++;
	}
	if(((PING&0x0C)>>2) == 0x02){
	   while(!(((PING & 0x0c)>>2) == 0x00));
	   if(i>0) i--;
	}
 }
}

