#include <util/delay.h>

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "simple_driver.h"


void	InitPORT();
void	InitADC();
uint16_t ReadADC(uint8_t ch);
double	konvert_u(uint16_t arany, uint8_t adc_ch, int adc_min, double adc_max, int u_min, double u_max);
					//arany:	a bemeneten lévő feszültségosztó aránya:	pl. 10k:30k=>4		20V=>5V
					//adc_ch:	a kiolvasandó adc csatorna 0-7
					//adc_min	0
					//adc_max	1023
					//u_min:	adc_min-nek megfelelő bemeneti feszültség mV
					//u_max:	adc_max-nak megfelelő bemeneti feszültség mV
int double_to_lcd( double num, uint8_t after_point, uint8_t address);
					//num:		kiírandó szám
					//after_point:	tizedesvessző utáni kiírandó jegyek száma
					//address:	képernyőcím

int main(void) {


int adc4=0;
int adc5=0;
char buf2[10]={0};
char buf3[10]={0};

    InitPORT();
    lcd_init ();
    InitADC();

    _delay_ms(100);
    
    lcd_control (1, 0, 0);
    lcd_cls ();
    lcd_putstr ("-=Battery monitor=- ", LCD_FIRST_LN_ADDR + 0);
    _delay_ms(200);
    lcd_cls ();

    for (;;) {
		//static display
        //			 01234567890123456789
		lcd_putstr ("-=Battery monitor=- ", LCD_FIRST_LN_ADDR + 0);
		lcd_putstr (" U1=  ,  V U2=  ,  V", LCD_SECND_LN_ADDR + 0);
	//	lcd_putstr (" I1=  ,  A I2=  ,  A", LCD_FIRST_LN_ADDR + 20); 
	//	lcd_putstr (" Q1=       Q2=      ", LCD_SECND_LN_ADDR + 20);
	      
		  
		    
    //	adc5 = ReadADC(5);
		//m_volt=konvert_u(4, 5, 0, 1023, 0, 5000);		//visszaadja a mert feszultseget mV-ban
		double_to_lcd( konvert_u(4, 5, 0, 1023, 0, 5000), 2, LCD_SECND_LN_ADDR + 4);	//PC5 csatorna kiírása

	//	adc4 = ReadADC(4);
	//	m_volt2=konvert_u(1, 4, 0, 1023, 0, 5000);		//visszaadja a mert feszultseget mV-ban
		double_to_lcd( konvert_u(1, 4, 0, 1023, 0, 5000), 2, LCD_SECND_LN_ADDR + 14);	//PC4 csatorna kiírása

		/*
		itoa( adc4, buf2, 10);

		itoa( adc5, buf3, 10);	

		lcd_putstr (buf2, LCD_SECND_LN_ADDR + 20);
		lcd_putstr (buf3, LCD_SECND_LN_ADDR + 25);
		*/

        _delay_ms(100);
        //lcd_cls();  
    } // for
} // main



void InitPORT() {

//           6543210
    DDRC = 0b1001111;
//  PC5,4, ADC5,4 bemenet, többi kimenet
	DDRB = 0xFF;
	//     76543210 
    DDRD = 0xFF;
   // PORTD=0xFF;
}

void InitADC() {

//            76543210
    ADMUX = 0b01000000;

//             76543210
    ADCSRA = 0b10000111;


} // InitADC

uint16_t ReadADC(uint8_t ch) {

    ch=ch&0b00000111; //Select ADC Channel ch must be 0-7
    ADMUX|=ch;

    ADCSRA|=(1<<ADSC); //Start Single conversion

    while(ADCSRA & (1<<ADSC)); //várok amíg átalakít

    return (ADCL | (ADCH<<8)); //adc kiolvasás

} // ReadADC


double konvert_u(uint16_t arany, uint8_t adc_ch, int adc_min, double adc_max, int u_min, double u_max)
{
	double u_inp=0.0;
	uint16_t adc=0;

	adc = ReadADC(adc_ch);	

	u_inp=(((((u_max-u_min)/(adc_max-adc_min))*adc)+adc_min)*arany);
	
	return u_inp;		//bejovo feszultseg*osztasi arany - mV
}


int double_to_lcd( double num, uint8_t after_point, uint8_t address)
{

	char tortresz[10]={0};
	char egeszresz[10]={0};
	char buffer[10]={0};
	int a=0;
	int b=0;
	int c=0;


	a=(num/1000);	//int tipus - az egeszresz adodik at	mV->V
	b=num;			
	

	itoa( a, egeszresz, 10);
	itoa( b, buffer, 10);

	c=strlen(buffer);

	switch(c)
	{

		case 6:	//m_volt 100-999V
		{
			strncpy( tortresz, &buffer[3],after_point);
			lcd_putstr (egeszresz, address);
			lcd_putstr (",", address+3);
			lcd_putstr (tortresz, address+4);
			break;
		}
			
		case 5:	//m_volt 10-99V
		{
			strncpy( tortresz, &buffer[2],after_point);
			lcd_putstr (egeszresz, address);
			lcd_putstr (",", address+2);
			lcd_putstr (tortresz, address+3);
			break;
		}

		case 4:	//m_volt 1-9.99V
		{
			strncpy( tortresz, &buffer[1],after_point);
			lcd_putstr (egeszresz, address+1);
			lcd_putstr (",", address+2);
			lcd_putstr (tortresz, address+3);
			break;
		}

		
		case 3:	//m_volt 100-999mV
		{
			strncpy( tortresz, &buffer[0],after_point);
			lcd_putstr ("0,", address+1);
			lcd_putstr (tortresz, address+3);
			break;
		}

		default:	//m_volt 0-99mV
		{
			lcd_putstr (" 0,0x", address);
			break;
		}
	}


	return 0;
}