/*
 * $Id: main.c,v 1.1 2010/10/19 05:18:47 bsd Exp $
 *
 */

/*
 * GP2D12 - a complete test program using the Sharp GP2D12 on the
 * BDMICRO MAVRIC and MAVRIC-II microcontroller boards.  This program
 * is intended to demonstrate how to use the BDMICRO MAVRIC or
 * MAVRIC-II microcontroller boards in conjunction with a Sharp GP2D12
 * Infrared Ranger Module.  Feel free to copy the relevent function
 * definitions into your own applications and to customize them for
 * your needs.
 *
 * See: http://www.bdmicro.com/
 *
 * Configuration:
 *
 *   Simply attach your the GP2D12 signal line to A/D Converter
 *   channel 0 (PORTF0 pin), hook up power and ground.  It's OK to use
 *   one of the supplied VCC pins on your microcontroller board to
 *   supply power to the GP2D12.
 *
 *   If desired, attach a terminal to UART0 for 9600, 8N1; the GP2D12
 *   will be sampled 10 times per second and printed to UART0.  The
 *   raw A/D converted result is printed as well as the value
 *   converted to Volts.
 * 
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#include <stdio.h>

#include "adc.h"

#define BAUD 9600L   /* use 9600 baud for UART0 connection */

/* baud rate register value for desired baud rate */
#define BAUD_RR ((CPU_FREQ/(16L*BAUD) - 1))


#define CPU_FREQ 16000000L  /* set to clock frequency in Hz */

#if CPU_FREQ == 16000000L
#define OCR_1MS 125
#elif CPU_FREQ == 14745600L
#define OCR_1MS 115
#endif

volatile uint16_t ms_count;


/*
 * ms_sleep() - delay for specified number of milliseconds
 */
void ms_sleep(uint16_t ms)
{
  TCNT0  = 0;
  ms_count = 0;
  while (ms_count != ms)
    ;
}


/* 
 * millisecond counter interrupt vector 
 */
SIGNAL(SIG_OUTPUT_COMPARE0)
{
  ms_count++;
}


/*
 * Initialize timer0 to use the main crystal clock and the output
 * compare interrupt feature to generate an interrupt approximately
 * once per millisecond to use as a general purpose time base.
 */
void init_timer0(void)
{
  TCCR0 = 0;
  TIFR  |= _BV(OCIE0)|_BV(TOIE0);
  TIMSK |= _BV(TOIE0)|_BV(OCIE0);         /* enable output compare interrupt */
  TCCR0  = _BV(WGM01)|_BV(CS02)|_BV(CS00); /* CTC, prescale = 128 */
  TCNT0  = 0;
  OCR0   = OCR_1MS;                     /* match in aprox 1 ms */
}




int def_putc(char ch, FILE * f)
{
  /* output character to UART0 */
  while ((UCSR0A & _BV(UDRE)) == 0)
    ;
  UDR0 = ch;
  return 0;
}




int main(void)
{
  uint16_t ir;
  double volts;

  init_timer0();

  /* enable UART0 */
  UBRR0H = (BAUD_RR >> 8) & 0xff;
  UBRR0L = BAUD_RR & 0xff;
  UCSR0B = _BV(TXEN); /* enable transmitter only */

  /* enable interrupts */
  sei();

  /* initialize stdio */
  fdevopen(def_putc, NULL);

  /* print out a greeting message */
  printf("\n\nGP2D12 Test\n\n");

  /* initialize A/D Converter */
  adc_init();

  while (1) {
    ms_sleep(100);         /* sleep for 0.1 second */
    ir = adc_readn(0, 5);  /* sample channel 0 5 times, take average */
    volts = ((double)ir) * 5.0 / 1024.0; /* convert to Volts */
    printf("ir = %3u = %5.3f Volts\r", ir, volts);
  }
}


