// Template - Roman Pavelka, 2011
// written for atmega8

#define F_CPU 16000000
#define BAUD 1000000
//#define MYUBRR F_CPU/8/BAUD-1
#define MYUBRR 1

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#include "./libs/usart.h"
#include "./libs/spi.h"
//#include "./libs/mcp4922.h"
//#include "./libs/adc.h"
//#include "./libs/timer.h"


#define LEN 128

void act(void);
void drive(unsigned char t);

int main (void) {
  USART_Init(MYUBRR);
  PORTC  = 0b00000000; // drive port
  DDRC  =  0b00000011; // drive port out

  DDRB  =  0b00101110; //MOSI out CONV out, DAC CS out
  PORTB =  0b00101010; // SCK, MOSI, CONV, DAC high
  SPI_MasterInit();

  sei();

  while (1) ;
  return 0;
}


void act(void) {

  unsigned char data[2*LEN];
  unsigned char i,j;

  for(j=0;j<40;j++) {
    for(i=0;i<LEN;i++) {
      drive(i);
      _delay_us(5);
    }
  }

  for(i=0;i<LEN;i++) {
    drive(i);

    PORTB |= 0b00000100;
    _delay_us(4); // converting
    PORTB &= 0b11111011;

    data[2*i]=SPI_MasterTransmit(0x0);
    data[2*i+1]=SPI_MasterTransmit(0x0);
  }

  PORTC=0;

  for(i=0;i<LEN;i++) {
    USART_Transmit(data[2*i]);
//    USART_Transmit(data[2*i+1]);
  }

}


void value(void) {

  unsigned char i,j;
  long resultH,resultL;

  resultH=0;
  resultL=0;

  for(j=0;j<32;j++) {
    for(i=0;i<LEN;i++) {
      drive(i);
      _delay_us(5);
    }
  }

  for(j=0;j<4;j++) {
    for(i=0;i<LEN/2;i++) {
      drive(i);

      PORTB |= 0b00000100;
      _delay_us(4); // converting
      PORTB &= 0b11111011;

      resultH+=(unsigned char)SPI_MasterTransmit(0x0);
      resultL+=(unsigned char)SPI_MasterTransmit(0x0);
    }
    for(i=LEN/2;i<(LEN/4)*3;i++) { //dela podivnou kvantitatizaci vysledku
      drive(i);

      PORTB |= 0b00000100;
      _delay_us(4); // converting
      PORTB &= 0b11111011;

      resultH-=(unsigned char)SPI_MasterTransmit(0x0);
      resultL-=(unsigned char)SPI_MasterTransmit(0x0);
    }
  }

  PORTC=0; // drive off

//  resultH *= 256;
//  USART_Transmit_longnum(resultH+resultL);

  USART_Transmit_longnum(resultH);

  USART_Transmit('\n');
}


ISR(USART_RXC_vect) {
  cli();
  char c; 

  c=UDR; //must be read to untrigger interupt

  if (c=='a')
    act();
  else if (c=='v')
    value();

  sei();
}


void drive(unsigned char t) {
  if (t<LEN/2) 
    PORTC  = 0b00000001;
  else
    PORTC  = 0b00000010;
}