/**
* @file main.c
*
* @brief
*	Application to connect a HALIOS Chip over I2C to HACo
*
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include "bit.h"
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/sleep.h>

#include "usb.h"

#include "signal.h"

#include <util/delay.h>

#include "comDev.h"




volatile unsigned char guc_newADC = FALSE;

unsigned char guc_do_measure = FALSE;
long int gui32_Temp = 0;







void initializePeriphary(void)
{
	/** Timer0 used for trigger the ADC when overflow 
	* Disconnect the Pins from timer function
	* Mode Normal
	* Prescaler clk/1024
	*/
	TCCR0A = 0;
	TCCR0B = (1<<CS02) | ((1<<CS00));
	TIMSK0 = (1<<TOIE0);

	
	/** Use Timer1 for first three PWM generation 
	* Connect OC1A (PORTB.PIN5)
	* Connect OC1B (PORTB.PIN6)
	* Connect OC1C (PORTB.PIN7)
	* 10-bit fast PWM Mode
	* Prescaler clk/8 --> ~974 Hz
	*/
	TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1C1) | (1<<WGM11) | (1<<WGM10);
	TCCR1B = (1<<WGM12) | (1<<CS11);

	/** Configure GPIOs for Timer1 as Outputpin */
	DDRB |= (BIT6 | BIT5 | BIT7);
	
	/** Reset OCR1 register */
	OCR1A = 0;
	OCR1B = 0;
	OCR1C = 0;
	
	
	/** Use Timer4 for PWM 4 and 5 generation 
	* Connect OC4A (PORTC.PIN7)
	* Connect OC4D (PORTD.PIN7)
	* 10-bit fast PWM Mode
	* Prescaler clk/8 --> ~974 Hz
	*/
	TCCR4B = (1<<CS42);
	TCCR4C = (1<<COM4D1) | (1<<PWM4D);
	TCCR4A = (1<<COM4A1) | (1<<PWM4A);

	/** Configure GPIOs for Timer4 as Outputpin */
	DDRC |= BIT7;
	DDRD |= BIT7;
	
	/** Reset OCR4 register */
	OCR4A = 0;
	OCR4D = 0;
	
#define TIMER4C	1023
	TC4H = TIMER4C >> 8;
	OCR4C = TIMER4C;
	
	/** Using ADC */
	/* Use internal ref valtage */
	ADMUX = (1<<REFS0) | (1<<ADLAR);
	
	ADCSRB |= (1<<ADTS2);
	/* Enable ADC */
	ADCSRA = (1<<ADIE);
	//ADCSRA |= (1<<ADATE);// | (1<<ADIE);
	ADCSRA |= (1<<ADSC) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
	ADCSRA |= (1<<ADEN);


}

ISR(ADC_vect)
{
	PORTD |= BIT6;
	PORTD &= ~BIT6;
	guc_newADC = TRUE;
}

ISR(TIMER0_OVF_vect)
{
	PORTD |= BIT4;
	PORTD &= ~BIT4;
}

void calc_temp(void)
{
	/* Read ADC value and shift by two, ADCH contain the high 8 bit of ADC
	* The ADCL contain the lowest two bits. 
	*/
	 long int tmp;
	 
	 tmp = ADCL;
	 tmp |= (ADCH<<2);
	
	/** 
	* Eqation for ADC is ADC = (Vin*1023)/Vref --> Vin = (ADC*Vref)/1023
	* Vref = 3V3
	*/
	tmp *= 3300;
	tmp >>= 10;
	
	/** Equation of temperatur is 
	* V-V1 = ((V2-V1)/(T2-T1))*(T-T1)
	* T => searched value
	* V => ADC (gui32_Temp)
	* T2 => Highest expected temperature (100°C)
	* T1 => Lowest expected temperature (-20°C)
	* V2 => Expected voltage at T2 (1257mV)
	* V1 => Expected valtage at T1 (2899mV)
	* ==> const = (V2-V1)/(T2-T1) = (1257mV-2899mV)/(100°C-(-20°C)) = -13.68 mV/°C
	* ==> T = (gui32_Temp-V1)/const + T1
	*/
	gui32_Temp = (((2899 - tmp)*100)/1368)-20; 
}

int main(void)
{
	unsigned char rem_guc_transmit_ctrl;
	 
  /** Clear CPU prescaler */
  clock_prescale_set(clock_div_1);

  CLKSEL0 = (1<<EXTE) | (1<<CLKS);



  DDRD |= BIT6;
  DDRD |= (BIT4 | BIT5);

  /** Disable interrupts */
  cli();

	initializeComDev(comDev_I2C);

	initializePeriphary();

  initializeUSB();

 // wdt_enable(WDTO_2S);

	set_sleep_mode(SLEEP_MODE_IDLE);

  /** Enable interrupts */
  sei();

  for(;;)
  {
   wdt_reset();


    if (do_reset)
    {
      do_reset = FALSE;
      UERST   =  0x7f;
      UERST  =  0;
    }


    do_receiving();
    do_transmission();
	
	if (guc_newADC)
	{
		guc_newADC = FALSE;
		calc_temp();
	}	

	
		PORTD |= BIT5;
		sleep_mode();
		PORTD &= ~BIT5;
	
 }	
}


