/*
**  File:       MAVRIC-II.C
**
**  Purpose:    Demo Program in ICCAVR for BDMICO's MAVRIC-II board.
**              http://www.bdmicro.com
**
**  Chip:		ATMEGA128 running at 16MHz
**
**  Version:    1.0.0, 3:rd of December 2003
**
**  Author:     Lars Wictorsson
**              LAWICEL / SWEDEN
**              http://www.lawicel.com   lars@lawicel.com
**
**  Copyright:  The copyright to the computer program(s) herein is the
**              property of LAWICEL HB, Sweden. The program(s) may be used
**              and/or copied only with the written permission of LAWICEL HB
**              in accordance with the terms and conditions stipulated in
**              the agreement/contract under which the program(s) have been
**              supplied.
**
**  Support:    No Support is given on this free demo program.
**
**	Remarks:	This program is tested with ICCAVR version 6.29.
**
**  History:    2003-12-03  1.0.0   Created (LWI)
*/

#include <iom128v.h>
#include <macros.h>

#define LED_ON      PORTB |= 0x01
#define LED_OFF     PORTB &= ~0x01

unsigned long ulTimerTick = 0;
unsigned char ucTimerFlag = 1;

//
// All ports are set to inputs, except PB0 which is set to output and off.
//
void port_init(void)
{
 PORTA = 0xFF;
 DDRA  = 0x00;
 PORTB = 0xFE;
 DDRB  = 0x01;
 PORTC = 0xFF; //m103 output only
 DDRC  = 0x00;
 PORTD = 0xFF;
 DDRD  = 0x00;
 PORTE = 0xFF;
 DDRE  = 0x00;
 PORTF = 0xFF;
 DDRF  = 0x00;
 PORTG = 0x1F;
 DDRG  = 0x00;
}

// TIMER1 initialisation - prescale:1
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1000Hz
// actual value: 1000,000Hz (0,0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xC1; //setup
 TCNT1L = 0x80;
 OCR1AH = 0x3E;
 OCR1AL = 0x80;
 OCR1BH = 0x3E;
 OCR1BL = 0x80;
 OCR1CH = 0x3E;
 OCR1CL = 0x80;
 ICR1H  = 0x3E;
 ICR1L  = 0x80;
 TCCR1A = 0x00;
 TCCR1B = 0x01; //start Timer
}

#pragma interrupt_handler timer1_ovf_isr:15
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xC1; //reload counter high value
 TCNT1L = 0x80; //reload counter low value
 if (ulTimerTick > 0) {
  ulTimerTick--;
 }
 else {
  ucTimerFlag = 1;
 }
}

//
// Routine waits n Milliseconds from Timer 1.
//
void WaitMS(unsigned long ulTime)
{
 CLI();
 ulTimerTick = ulTime;
 ucTimerFlag = 0;
 SEI();
 while(ucTimerFlag == 0);
}

// UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9615 (0,2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x06;
 UBRR0L = 0x67; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x18;
}

//call this routine to initialise all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();
 timer1_init();
 uart0_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x04; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

//
void main(void)
{
 init_devices();
 //insert your functional code here...
 
 puts("Testing MAVRIC-II Board from BDMICRO www.bdmicro.com\r");
 
 while(1) { // A forever loop
  LED_ON;
  WaitMS(250L);
  LED_OFF;
  WaitMS(750L);
 }
}


