#include <avr/io.h>
#include <util/delay.h>

int 	MP=150,refres=25,ADCref=25,csalw=5; //global

#define seg1_10_ON()	PORTD &= ~(1<<PIND5)
#define seg1_10_OFF()	PORTD |=  (1<<PIND5)
#define seg1_1_ON()		PORTD &= ~(1<<PIND6)
#define seg1_1_OFF()	PORTD |=  (1<<PIND6)
#define seg1_01_ON()	PORTD &= ~(1<<PIND7)
#define seg1_01_OFF()	PORTD |=  (1<<PIND7)
#define seg2_10_ON()	PORTC &= ~(1<<PINC2)
#define seg2_10_OFF()	PORTC |=  (1<<PINC2)
#define seg2_1_ON()		PORTC &= ~(1<<PINC1)
#define seg2_1_OFF()	PORTC |=  (1<<PINC1)
#define seg2_01_ON()	PORTC &= ~(1<<PINC0)
#define seg2_01_OFF()	PORTC |=  (1<<PINC0)
#define seg3_10_ON()	PORTB &= ~(1<<PINB7)
#define seg3_10_OFF()	PORTB |=  (1<<PINB7)
#define seg3_1_ON()		PORTD &= ~(1<<PIND0)
#define seg3_1_OFF()	PORTD |=  (1<<PIND0)
#define seg3_01_ON()	PORTD &= ~(1<<PIND1)
#define seg3_01_OFF()	PORTD |=  (1<<PIND1)
#define seg4_10_ON()	PORTD &= ~(1<<PIND2)
#define seg4_10_OFF()	PORTD |=  (1<<PIND2)
#define seg4_1_ON()		PORTD &= ~(1<<PIND3)
#define seg4_1_OFF()	PORTD |=  (1<<PIND3)
#define seg4_01_ON()	PORTD &= ~(1<<PIND4)
#define seg4_01_OFF()	PORTD |=  (1<<PIND4)

// B0 = a	B1= b	B2 = c	B3 = d	B4 = e	B5 = g	B6 = f	

#define nulla 	(1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | (0<<PINB5) | (1<<PINB6)
#define egy 	(0<<PINB0) | (1<<PINB1) | (1<<PINB2) | (0<<PINB3) | (0<<PINB4) | (0<<PINB5) | (0<<PINB6)
#define ketto 	(1<<PINB0) | (1<<PINB1) | (0<<PINB2) | (1<<PINB3) | (1<<PINB4) | (1<<PINB5) | (0<<PINB6)
#define harom 	(1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (0<<PINB4) | (1<<PINB5) | (0<<PINB6)
#define negy 	(0<<PINB0) | (1<<PINB1) | (1<<PINB2) | (0<<PINB3) | (0<<PINB4) | (1<<PINB5) | (1<<PINB6)
#define ot 		(1<<PINB0) | (0<<PINB1) | (1<<PINB2) | (1<<PINB3) | (0<<PINB4) | (1<<PINB5) | (1<<PINB6)
#define hat 	(1<<PINB0) | (0<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | (1<<PINB5) | (1<<PINB6)
#define het 	(1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (0<<PINB3) | (0<<PINB4) | (0<<PINB5) | (0<<PINB6)
#define nyolc 	(1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | (1<<PINB5) | (1<<PINB6)
#define kilenc 	(1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (0<<PINB4) | (1<<PINB5) | (1<<PINB6)
#define hiba 	(0<<PINB0) | (0<<PINB1) | (0<<PINB2) | (0<<PINB3) | (0<<PINB4) | (1<<PINB5) | (0<<PINB6)

void d10us(unsigned long val) {
           while(val--) _delay_us(1);
}

void clear()
		{
			PORTB |= (1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | (1<<PINB5) | (1<<PINB6);
		}

void multiplex(int s110,int s11,int s101,int s210,int s21,int s201,int s310,int s31,int s301,int s410,int s41,int s401)
		{
			int szamok[11] = {nulla,egy,ketto,harom,negy,ot,hat,het,nyolc,kilenc,hiba};

			clear();
			PORTB &= ~szamok[s110];
			seg1_10_ON();
			d10us(MP);
			seg1_10_OFF();
			clear();
			PORTB &= ~szamok[s11];
			seg1_1_ON();
			d10us(MP);
			seg1_1_OFF();
			clear();
			PORTB &= ~szamok[s101];
			seg1_01_ON();
			d10us(MP);

			seg1_01_OFF();
			clear();	
			PORTB &= ~szamok[s210];
			seg2_10_ON();
			d10us(MP);
			seg2_10_OFF();
			clear();
			PORTB &= ~szamok[s21];
			seg2_1_ON();
			d10us(MP);
			seg2_1_OFF();
			clear();
			PORTB &= ~szamok[s201];
			seg2_01_ON();
			d10us(MP);

			seg2_01_OFF();
			clear();
			PORTB &= ~szamok[s310];
			seg3_10_ON();
			d10us(MP);
			seg3_10_OFF();
			clear();
			PORTB &= ~szamok[s31];
			seg3_1_ON();
			d10us(MP);
			seg3_1_OFF();
			clear();
			PORTB &= ~szamok[s301];
			seg3_01_ON();
			d10us(MP);

			seg3_01_OFF();
			clear();
			PORTB &= ~szamok[s410];
			seg4_10_ON();
			d10us(MP);
			seg4_10_OFF();
			clear();
			PORTB &= ~szamok[s41];
			seg4_1_ON();
			d10us(MP);
			seg4_1_OFF();
			clear();
			PORTB &= ~szamok[s401];
			seg4_01_ON();
			d10us(MP);
			seg4_01_OFF();
			clear();	
		}

void init()
		{
			DDRC = (1<<PINC0) | (1<<PINC1) | (1<<PINC2) | (0<<PINC3) | (0<<PINC4) |
				   (0<<PINC5);
			DDRB = (1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | 
				   (1<<PINB5) | (1<<PINB6) | (1<<PINB7);
			DDRD = (1<<PIND0) | (1<<PIND1) | (1<<PIND2) | (1<<PIND3) | (1<<PIND4) | 
				   (1<<PIND5) | (1<<PIND6) | (1<<PIND7);

			PORTC = (1<<PINC0) | (1<<PINC1) | (1<<PINC2);
			
			PORTD = (1<<PIND0) | (1<<PIND1) | (1<<PIND2) | (1<<PIND3) | (1<<PIND4) | 
				    (1<<PIND5) | (1<<PIND6) | (1<<PIND7);

			PORTB = (1<<PINB0) | (1<<PINB1) | (1<<PINB2) | (1<<PINB3) | (1<<PINB4) | 
				    (1<<PINB5) | (1<<PINB6) | (1<<PINB7);
		}

void init_ADC()
		{
			ADMUX = (1<<REFS1) | (1<<REFS0); // internal 2.56V
			ADCSRA = (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0); // előosztás 2
		}

int	ReadADC1(void)
		{
           ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (1<<MUX0);
           ADCSRA |= (1<<ADSC);
           while(ADCSRA & (1<<ADSC));
           return (ADCL | (ADCH<<8));
		}

int	ReadADC2(void)
		{
           ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (0<<MUX0);
           ADCSRA |= (1<<ADSC);
           while(ADCSRA & (1<<ADSC));
           return (ADCL | (ADCH<<8));
		}

int	ReadADC3(void)
		{
           ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0);
           ADCSRA |= (1<<ADSC);
           while(ADCSRA & (1<<ADSC));
           return (ADCL | (ADCH<<8));
		}

int	ReadADC4(void)
		{
           ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
           ADCSRA |= (1<<ADSC);
           while(ADCSRA & (1<<ADSC));
           return (ADCL | (ADCH<<8));
		}

int main(void)
		{
			init();
			init_ADC();
			int ADC1=0,ADC2=0,ADC3=0,ADC4=0;
			int eloFinal,Final=0,refBuff,csal=0;
			while(1)
			{
				refBuff=refres;

				if(Final>csal) { csal++; }
				if(Final<csal) { csal--; }

				while(refBuff)
				{
					refBuff--;
					
					eloFinal=(ADC1*2560)/1024;
					Final=eloFinal;
					int ADC1T = Final/100;
					int ADC1E = Final%100/10;
					int ADC1TD= Final%100%10;
					if(ADC1T>9) 
					{ 
						ADC1T=10;
						ADC1E=10;
						ADC1TD=10;
					}

					multiplex(ADC1T,ADC1E,ADC1TD,ADC1/100,ADC1%100/10,ADC1%100%10,0,0,0,0,0,0);

				}








				ADC1=ReadADC1();
				ADC2=ReadADC2();
				ADC3=ReadADC3();
				ADC4=ReadADC4();

			}
		}
