#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

// define constant values
#define MISO PB6
#define MOSI PB5
#define SCK  PB7


// functions declarations
void SPI_MasterInit(void);
void SPI_MasterTransmit(char cData);
void latch(void);
void ledout(uint8_t row, uint16_t pattern);

// main
int main(void){

  // initialize SPI for LED driver
  SPI_MasterInit();

  // declare vars
  uint8_t i,l;
  uint16_t j,k,m;
   

  // Set PB0 PB1 PB2 PB3 PB4 to output
  // for controlling the LED driver
  DDRB |= 0x1F;
  PORTB = 0x01;

  ledout(3, 0x0300);
  while (1) {
    for(l=1;l<8;l++){
      for(m=0xff;m<0xff00;m*=2){
	for(j=0;j<100;j++){
	  for(i=0;i<l+1;i++){
	    ledout(i, m);
	    for(k=0;k<5000;k++);
	  }
	}
      }
    }
  }
  return 0;
}


void SPI_MasterInit(void){
  /* Set MOSI and SCK output, all others input */
  DDRB = (1<<MOSI)|(1<<SCK)|(1<<PB4);
  /* Enable SPI, Master, set clock rate fck/16 -> 1mhz sck rate -> 7812.5 fps */
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData){
  /* Start transmission */
  SPDR = cData;
  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));
}


void latch(void){
  // latch
  PORTB ^= 0x01;
}

void ledout(uint8_t row, uint16_t pattern){ 
  PORTB = (row<<2)|0x01;
  SPI_MasterTransmit(0x00);
  SPI_MasterTransmit(pattern >> 8);
  latch();
}
