/*

avr @ 16Mhz

 +-------------------------------------+
 |                          Sig Vd Gnd |
 |  +---------+   5V O     PB0 [o o o] | <- program button 
 |  | 7805  O |   Vd O     PB1 [o o o] | 
 |  +---------+   V+ .     PB2 [o o o] | -> Pass 2
 |                         PB3 [o o o] | -> Pass 1
 |                         PB4 [o o o] | -> fail
 |                         PB5 [o o o] | 
 |                         PB6 [o o o] | 
 |                         PB7 [o o o] | 
 |                         PA0 [o o o] | <- input
 |                         PA1 [o o o] | 
 |        +----------+     PA2 [o o o] | 
 |        |O         |     PA3 [o o o] | 
 |        |          |     PA4 [o o o] | 
 |        |          |     PA5 [o o o] | 
 |        |          |     PA6 [o o o] | 
 |        |          |     PA7 [o o o] | 
 |        |          |     PC7 [o o o] | 
 |        |          |     PC6 [o o o] | 
 |        |          |     PC5 [o o o] | 
 |        | ATMEGA32 |     PC4 [o o o] | 
 |        |          |     PC3 [o o o] | 
 |        |          |     PC2 [o o o] | 
 |        |          |     PC1 [o o o] | 
 |        |          |     PC0 [o o o] | 
 |        |          |     PD7 [o o o] | 
 |        |          |     PD2 [o o o] |
 |        |          |     PD3 [o o o] |
 |        |          |     PD4 [o o o] | 
 |        |          |     PD5 [o o o] | 
 |        +----------+     PD6 [o o o] | 
 |      E.D.S BABYBOARD III            |
 +-------------------------------------+


*/
#include<avr/io.h>

#define OUTPUT  1
#define INPUT   0

#define SetBit(BIT, PORT)     PORT |= (1<<BIT)
#define ClearBit(BIT, PORT)   PORT &= ~(1<<BIT)
#define IsHigh(BIT, PORT)    (PORT & (1<<BIT)) != 0
#define IsLow(BIT, PORT)     (PORT & (1<<BIT)) == 0

#define CH1On()                 SetBit(0, PORTB)
#define CH1Off()                ClearBit(0, PORTB)

#define CH2On()                 SetBit(1, PORTB)
#define CH2Off()                ClearBit(1, PORTB)

#define CH3On()                 SetBit(1, PORTB)
#define CH3Off()                ClearBit(1, PORTB)

#define CH4On()                 SetBit(1, PORTB)
#define CH4Off()                ClearBit(1, PORTB)

#define CH5On()                 SetBit(1, PORTB)
#define CH5Off()                ClearBit(1, PORTB)

#define CH6On()                 SetBit(1, PORTB)
#define CH6Off()                ClearBit(1, PORTB)








void Delay(unsigned int delay);
void InitADC( void );
void readADC(void) ;
void Delay2(unsigned int delay) ;
void startADC(unsigned char channel) ;
void waitADC(void) ;
 
 
int main( void ) {
 
  unsigned int i, d;

    // set up directions 
  DDRA = (INPUT << PA0 | INPUT << PA1 |INPUT << PA2 |INPUT << PA3 |INPUT << PA4 |INPUT << PA5 |INPUT << PA6 |INPUT << PA7);
  DDRB = (OUTPUT << PB0 | OUTPUT << PB1 | OUTPUT << PB2 |OUTPUT << PB3 |OUTPUT << PB4 |OUTPUT << PB5 |INPUT << PB6 |INPUT << PB7);
  DDRC = (INPUT << PC0 | INPUT << PC1 |INPUT << PC2 |INPUT << PC3 |INPUT << PC4 |INPUT << PC5 |INPUT << PC6 |INPUT << PC7);
  DDRD = (INPUT << PD0 | INPUT << PD1 |INPUT << PD2 |INPUT << PD3 |INPUT << PD4 |INPUT << PD5 |INPUT << PD6 |INPUT << PD7);        


  InitADC();
  startADC(0);
 
 // i = 8000 ;   // 2048 = .5ms ;   8000 = 2ms
 
  while(1)  {
    d = 65000;
    
    
    waitADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(1);      
    CH1On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH1Off();  
               
    
    readADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(2);    
    CH2On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH2Off();  
   
   
    readADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(3);    
    CH3On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH3Off();    
    
    
    waitADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(4);      
    CH4On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH4Off();  
               
    
    readADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(5);    
    CH5On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH5Off();  
   
   
    readADC();
    i = (ADC*6)+2000;
    d -= i;
    startADC(0);    
    CH6On();    
    for(; i != 0; i--) asm volatile ("nop"::); // 900 is 0.5ms, 5000 is 2.5ms
    CH6Off();       
   
    Delay(14000); 
    Delay(d); 
  }
  
}



void Delay(unsigned int delay) {
  unsigned int x;
  for (x = delay; x != 0; x--) {
    asm volatile ("nop"::); 
  }
}

void Delay2(unsigned int delay) {
  unsigned int x;
  for (x = delay; x != 0; x--) {
    Delay(65535); 
  }
}







void InitADC( void ) {
  // VCC voltager ref, ADC2 (PB4) as default input
  ADMUX = 2;
  // Enable ADC, ADC prescaler /64
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (0<<ADPS1);
 
}

void startADC(unsigned char channel) {
  ADMUX = channel & 0x07;
  SetBit(ADIF, ADCSRA);
  SetBit(ADSC, ADCSRA);   
}

void waitADC(void) {
  while(IsLow(ADIF, ADCSRA));  // wait for conversion done, ADIF flag active
}

void readADC(void) {

    SetBit(ADIF, ADCSRA);
    SetBit(ADSC, ADCSRA);    

    while(IsLow(ADIF, ADCSRA));  // wait for conversion done, ADIF flag active

}
