#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <utils.h>
#include "adc.h"
#include "uart.h"

#define AD_I_LOAD	0
#define AD_I_GEN	1
#define AD_V		2

#define LOADSW		PB0
#define GENSW		PB1
#define DUMPSW		PB2
#define PORT_SW		PORTB
#define DDR_SW		DDRB

#define LOAD_ON		PORT_SW |= _BV(LOADSW)
#define LOAD_OFF	PORT_SW &= ~_BV(LOADSW)
#define GEN_ON		PORT_SW |= _BV(GENSW)
#define GEN_OFF	PORT_SW &= ~_BV(GENSW)
#define DUMP_ON		PORT_SW |= _BV(DUMPSW)
#define DUMP_OFF	PORT_SW &= ~_BV(DUMPSW)

typedef enum {
	generated,
	consumed
} power_source;


volatile uint16_t syscounter = 0;
uint16_t voltage = 0;
int16_t current_in = 0;
int16_t current_out = 0;

void timer_init(void) {
	// clock is 8MHz
	TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10) ; // CTC Mode for Timer 1 (16Bit) with prescale of 64
	OCR1A   = 1250;                                // 100Hz
	TIMSK   = _BV(OCIE1A);
	sei();	// enable interrupts
}

void ports_init(void) {
	DDR_SW |= _BV(LOADSW) | _BV(GENSW) | _BV(DUMPSW);
	PORT_SW &= ~(_BV(LOADSW) | _BV(GENSW) | _BV(DUMPSW));
}

void measure(void) {
    voltage = adc_read_avg(AD_V, 4) / 6.6;

    current_in = adc_read_avg(AD_I_GEN, 4);
    current_in -= 510;
    current_in *= 72;

    current_out = adc_read_avg(AD_I_LOAD, 4);
    current_out -= 511;
    current_out *= 72;
}

uint8_t get_power(uint16_t voltage, int16_t currents) {
    return (voltage * (currents/100)) / 100;
}



int main(void) {
	ports_init();
	adc_init();
	timer_init();
	
    uart_init(UART_BAUD_SELECT(9600,F_OSC));

    char s[10];

    LOAD_ON;
    GEN_ON;
    DUMP_OFF;
	
	while(1) {

	    measure();

        uart_puts_P("Voltage:   ");
        uart_puts ( itoa ( voltage, s, 10 ) );
        uart_puts_P("dV\r\n");

        uart_puts_P("Load:      ");
        uart_puts ( itoa ( current_out, s, 10 ) );
        uart_puts_P("mA  ");

        uart_puts ( itoa ( get_power(voltage, current_out), s, 10 ) );
        uart_puts_P("W\r\n");


        uart_puts_P("Generator: ");
        uart_puts ( itoa ( current_in, s, 10 ) );
        uart_puts_P("mA  ");

        uart_puts ( itoa ( get_power(voltage, current_in), s, 10 ) );
        uart_puts_P("W\r\n");





        wait(100);
        wait(100);
        wait(100);
        wait(100);
        //wait(100);
        //wait(100);
        wait(100);
        wait(100);

		
	}
	
	return(0);
}

// system timer
SIGNAL(TIMER1_COMPA_vect) {
	syscounter++;
}


