/*
 * $Id: hw.c,v 1.4 2007/08/02 00:54:29 bsd Exp $
 *
 */

/*
 * HW - Hello World
 *
 * This is a very simple project designed only to familiarize oneself
 * with the use of a Makefile, the compiler, linker, and FLASH
 * download tool (such as AVRDUDE) when working with the MAVRIC /
 * MAVRIC-II board.
 *
 * This program simply blinks the on-board LED on and off, once per
 * second.  It demonstrates setting up a periodic timer interrupt as a
 * time keeping source, the use of declaring and using an interrupt
 * handler with AVR-GCC, and toggling a PORT output line.
 *
 * See: http://www.bdmicro.com/
 *
 * Configuration:
 *
 *   MAVRIC - ensure that DIPSW 9 is "on".
 *
 *   MAVRIC-II - ensure that jumper LEDEN is installed
 *
 *  */

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

#include <inttypes.h>

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 timer 0 to generate an interrupt every millisecond.
 */
void init_timer(void)
{
  /*
   * Initialize timer0 to generate an output compare interrupt, and
   * set the output compare register so that we get that interrupt
   * every millisecond.
   */
  TIFR  |= _BV(OCIE0);
  TCCR0  = _BV(WGM01)|_BV(CS02)|_BV(CS00); /* CTC, prescale = 128 */
  TCNT0  = 0;
  TIMSK |= _BV(OCIE0);    /* enable output compare interrupt */
  OCR0   = 125;          /* match in 1 ms */
}


int main(void)
{
  init_timer();

  /* enable interrupts */
  sei();

  DDRB = 0x01;  /* enable PORTB 1 as an output */

  while (1) {
    ms_sleep(512);    /* wait 0.5 seconds */
    PORTB ^= 0x01;    /* toggle LED */
  }

}

