/*

avr @ 16Mhz
9600 baud


on pro mini:

0   rxd   
1   txd   

2   pd2    
3   pd3    
4   pd4    
5   pd5   
6   pd6    
7   pd7    
8   pb0    
9   pb1    
10  pb2    
11  pb4
12  pb3
13  pb5


A0  pc0  (adc0)
A1  pc1  (adc1)   
A2  pc2  (adc2)  
A3  pc3  (adc3)  
A4  pc4  (adc4)  
A5  pc5  (adc5)  
A6        adc6
A7        adc7



*/
#include <avr/io.h>
#include "usart.h"
#include <avr/interrupt.h>

#define NOP()    asm volatile ("nop"::)
#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 InBoundsI(v, l, h)   ((v) >= (h)) ? (0) : ((v) <= (l)) ? (0) : (1)


volatile int AdcValue;

void AnalogInit ( void );
void timerInit  ( void ) ;

int main( void ) {
 
 
    // set up directions 
  DDRB = (INPUT << PB0 | INPUT << PB1 | INPUT << PB2 |INPUT << PB3 |INPUT << PB4 |INPUT << PB5 |INPUT << PB6 |INPUT << PB7);
  DDRD = (INPUT << PD0 | INPUT << PD1 | INPUT << PD2 |INPUT << PD3 |INPUT << PD4 |INPUT << PD5 |INPUT << PD6 |INPUT << PD7);        
  DDRC = (INPUT << PD0 | INPUT << PD1 | INPUT << PD2 |INPUT << PD3 |INPUT << PD4 |INPUT << PD5 |INPUT << PD6 |INPUT << PD7); 

//  PORTB = 0x0C; 

//  USART_Init( 103 ); // 9600 baud
//  USART_Init( 51 );  //19200 baud
    USART_Init( 16 );  // a bad 57600 baud
   
   
  AnalogInit();
  timerInit();
  
  sei();
  
  while(1) {
    USART_printhex(AdcValue );       
  }
  return 0;     
}




// 7112Hz
void timerInit(void) {

// Fast pwm mode, overflows @ OCR1A 
  TCCR1A |= (1<<WGM10)|(1<<WGM11);
  // set prescaler to /1 and FAST PWM mode
  TCCR1B |= (1<<CS10)|(1<<WGM12)|(1<<WGM13);
  
  // about 7111.11 hz
  OCR1A = 2250;
  
  // set interrupt mask register 
 // TIMSK1 |= (1<<TOIE1);  no, the adc will automatically be started on overflow

}


void AnalogInit (void) {  

  // auto trigger on timer 1 overflow, how cool is that!
  ADCSRB = 1 << ADTS2 |
           1 << ADTS1 ;

  // Activate ADC with Prescaler of 128, yielding max of 9.6ksps
  ADCSRA =  1 << ADEN  |
            0 << ADSC  | 
            1 << ADATE | /* auto start when timer1 overflows */
            0 << ADIF  |
            1 << ADIE  | /* enable interrupt */
            1 << ADPS2 |
            1 << ADPS1 |
            1 << ADPS0 ;
                        
  ADMUX = (1<<REFS0);     // channel 0     
  AdcValue = 0;
  
}


ISR(ADC_vect) { 
  TIFR1 |= (1<<TOV1); // flag has to be cleared for another start event
  AdcValue = ADC;  // save value
  //ADCSRA |= _BV(ADSC); // start next conversion

  return;
}
















