/***************************************************************************
 *   Copyright (C) 16.04.2004 by                                           *
 *   Matthias Kranz (matthias.kranz@ifi.lmu.de)                            *
 *   Paul Holleis (paul.holleis@ifi.lmu.de)                                *
 *                                                                         *
 *   Last modified 26.08.2004                                              *
 *                                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 **************************************************************************/

//********* GENERAL SETUP ****************************************************/
// the pic to use
#include <18f452.h>
// device directive must precede include
#device *=16 ADC=10
// delay must be defined before first use of
// #use rs232 (see compiler manual); 20MHz crystal used
#define CLOCKCYCLE 20000000
#use delay(clock=CLOCKCYCLE)
// no watchdogtimer (wdt), no low-voltage programming (lvp)
// oscillator = hs, no brownout, no code protect
#fuses NOWDT, HS, NOBROWNOUT, NOPROTECT, NOLVP

#include <std.h>
// use warnings only to translate compiler error codes to text.
// not needed during normal operation.
//#include <warnings.h>

// for atoi or similar stuff, include the next line:
//#include <stdlib.h>

//********* PROGRAMMING STYLE ************************************************/
// case sensitive programming
#CASE
// see compiler handbook for description of warnings.
// we are glad with ignoring the following warnings.
#ignore_warnings 201,202,203,205,207,208,216

//********* ADDITIONAL INCLUDES **********************************************/
// (un)comment the following to (un)define the standard spm pins
//#define SPM_USED
#ifdef SPM_USED
	#include "spm2-433-28.h"	
#endif

// (un)comment the following to (un)define the standard i2c pins
//#define USE_I2C
#ifdef USE_I2C
	#include <i2c.h>
#endif

//********* COMMUNICATION SETUP **********************************************/
#ifdef __STD
  // serial line setup (STDSTREAM) & stdout (no stream)
  #use rs232(baud=STDSTREAM_SPEED,xmit=PIC_TX_PIN,rcv=PIC_RX_PIN,STREAM=STDSTREAM)
  #use rs232(baud=STDSTREAM_SPEED,xmit=PIC_TX_PIN,rcv=PIC_RX_PIN)
#else
  // stdout (no stream)
  #use rs232(baud=STDOUT_SPEED,xmit=PIN_C6,rcv=PIN_C7)
#endif
#ifdef SPM_USED
  // spm out (SPMSTREAM)
  #use rs232(baud=SPM_SPEED, xmit=SPM_TX_PIN, rcv=SPM_RX_PIN,STREAM=SPMSTREAM)
#endif

//********* INPUT PORT A SETUP************************************************/
// if analog sensors are to be used
#define PORT_A_ANALOG

//********* MISCELLANEOUS ****************************************************/
// use fast io if it works for you (which is very rare...).
//#use fast_io(A)
//#use fast_io(B)

/******************************************************************************
 * defines
 *****************************************************************************/

/******************************************************************************
 * includes
 *****************************************************************************/

/******************************************************************************
 * structs
 *****************************************************************************/

/******************************************************************************
 * global variables
 *****************************************************************************/

/******************************************************************************
 * function signatures
 *****************************************************************************/
// MISCELLANEOUS
void main();
void print_help();


// Array-Größe berechnen:
// sizeof(array)/sizeof(array[0])

// LED
void led_on();
void leds_b_off();
void leds_b_on();
void led_off();
void leds_a_on();
void leds_a_off();
void led_red_on();
void led_red_off();
void led_red_blink();
void led_red_blink_n(int blinks);
void led_red_blink_t(int blinktime);
void led_red_blink_nt(int blinks, int blinktime);

// Output
void print_to_stdstream();
void print_to_spmstream();
void print_to_stdout();

// input
// digital input
void test_digital_input_port_b();
void define_low_port_b0();
void define_low_port_b1();
void define_low_port_b2();
void define_low_port_b3();
void define_low_port_b4();
void define_low_port_b5();
void define_low_port_b6();
void define_low_port_b7();
void define_all_digital_ports();

// analog input
void read_analog_input_port_a0();
void read_analog_input_port_a1();
void read_analog_input_port_a2();
void read_analog_input_port_a3();
void read_analog_input_port_a4();
void read_analog_input_port_a5();
void read_analog_input_port_a6();
void read_analog_input_port_a7();
long read_analog_input_port_a(int port);

/******************************************************************************
 * Code
 *****************************************************************************/
void main()
{
	// variables come first
	
	// pre-main, doing some general setup for the program
	#ifdef PORT_A_ANALOG
	  // if analog sensors are to be used
	  setup_port_a( ALL_ANALOG );    
	  // general analog/digital converter setup
    setup_adc( ADC_CLOCK_INTERNAL );
  #endif
  // spm setup
	#ifdef SPM_USED
		spm_init();
	#endif
	// your code below
	while (TRUE)
	{
		
	}		
}

void define_all_digital_ports()
{
  define_low_port_b0();
  define_low_port_b1();
  define_low_port_b2();
  define_low_port_b3();
  define_low_port_b4();
  define_low_port_b5();
  define_low_port_b6();
  define_low_port_b7();	
}

void define_low_port_b0()
{
	output_low(PIN_B0);
}

void define_low_port_b1()
{
	output_low(PIN_B1);
}

void define_low_port_b2()
{
	output_low(PIN_B2);
}

void define_low_port_b3()
{
	output_low(PIN_B3);
}

void define_low_port_b4()
{
	output_low(PIN_B4);
}

void define_low_port_b5()
{
	output_low(PIN_B5);
}

void define_low_port_b6()
{
	output_low(PIN_B6);
}

void define_low_port_b7()
{
	output_low(PIN_B7);
}

long read_analog_input_port_a(int port)
{
	long value;
	value = 0;
 	switch(port) 
	{
		case 0: 	set_adc_channel(ADC_CHANNEL_0); break;
		case 1: 	set_adc_channel(ADC_CHANNEL_1); break;
		case 2: 	set_adc_channel(ADC_CHANNEL_2); break;
		case 3: 	set_adc_channel(ADC_CHANNEL_3); break;
		case 4: 	set_adc_channel(ADC_CHANNEL_4); break;
		case 5: 	set_adc_channel(ADC_CHANNEL_5); break;
		case 6: 	set_adc_channel(ADC_CHANNEL_6); break;
		case 7: 	set_adc_channel(ADC_CHANNEL_7); break;
	}
	delay_us(50);
	value = read_adc();
	return(value);
}

void read_analog_input_port_a0()
{
	long load;
	load = 0;
 	set_adc_channel(0);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a1()
{
	long load;
	load = 0;
 	set_adc_channel(1);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a2()
{
	long load;
	load = 0;
 	set_adc_channel(2);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a3()
{
	long load;
	load = 0;
 	set_adc_channel(3);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a4()
{
	long load;
	load = 0;
 	set_adc_channel(4);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a5()
{
	long load;
	load = 0;
 	set_adc_channel(5);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a6()
{
	long load;
	load = 0;
 	set_adc_channel(6);
	delay_us(50);
	load = read_adc();
}
void read_analog_input_port_a7()
{
	long load;
	load = 0;
 	set_adc_channel(7);
	delay_us(50);
	load = read_adc();
}


void test_digital_input_port_b()
{
		if (input(PIN_B1)) {printf("B1");}
		if (input(PIN_B2)) {printf("B2");}
		if (input(PIN_B3)) {printf("B3");}
		if (input(PIN_B4)) {printf("B4");}
		if (input(PIN_B5)) {printf("B5");}
		if (input(PIN_B6)) {printf("B6");}
		if (input(PIN_B7)) {printf("B7");}
		printf("\n");
} 

void led_red_blink_nt(int blinks, int blinktime)
{
	int i;
	if (i>0) 
	{
		for (i = 0; i < blinks; i++)
		{
			led_red_blink_t(blinktime);
		}
	}
}

void led_red_blink_n(int blinks)
{
	int i = 0;
	if (i > 0) 
	{
		for (i = 0; i < blinks; i++)
 		{
			led_red_blink();
		}
	}
}

void led_red_blink_t(int blinktime)
{
  	output_high (PIN_A4);
  	delay_ms(blinktime);
  	output_low (PIN_A4);
  	delay_ms(blinktime);
}


void led_red_blink()
{
  	output_high (PIN_A4);
  	delay_ms(50);
  	output_low (PIN_A4);
  	delay_ms(50);
}

void led_red_on()
{
		output_low(PIN_A4);
}

void led_red_off()
{	
		output_high (PIN_A4);
}

void led_on()
{
	output_low(PIN_A4);
}

void leds_b_on()
{
	output_low(PIN_B1);
	output_low(PIN_B2);
	output_low(PIN_B3);
	output_low(PIN_B4);
	output_low(PIN_B5);
	output_low(PIN_B6);
	output_low(PIN_B7);
}
   
void leds_b_off()
{
	output_high(PIN_B1);
	output_high(PIN_B2);
	output_high(PIN_B3);
	output_high(PIN_B4);
	output_high(PIN_B5);
	output_high(PIN_B6);
	output_high(PIN_B7);
}

void leds_a_on()
{
	output_low(PIN_A1);
	output_low(PIN_A2);
	output_low(PIN_A3);
	output_low(PIN_A4);
	output_low(PIN_A5);
	output_low(PIN_A6);
}
   
void leds_a_off()
{
	output_high(PIN_A1);
	output_high(PIN_A2);
	output_high(PIN_A3);
	output_high(PIN_A4);
	output_high(PIN_A5);
	output_high(PIN_A6);
}
   
void led_off()
{
	output_high(PIN_A4);
}

void print_to_stdstream() 
{
	fprintf(STDSTREAM, "Hello World to stream STDSTREAM\n");
}

void print_to_stdout()
{
	printf("Hello World to stdout \n");
}

void print_to_spmstream() 
{
	#ifdef  SPM_USED
	fprintf(SPMSTREAM, "Hello World to stream SPMSTREAM\n\r");
	fprintf(SPMSTREAM, "make sure to use \\n\\r as newline & carriage return\n\r");
	#else
	printf("spmstream not defined!!!\n");
	#endif
}
	
void print_help()
{
   fprintf(STDSTREAM, "Smart ITs File Version Information.\r\n");
   fprintf(STDSTREAM, "http://hcilab.org/\r\n");
   fprintf(STDSTREAM, "Software compiled on ");
   fprintf(STDSTREAM, __DATE__);
   fprintf(STDSTREAM, "\n\r");
   fprintf(STDSTREAM, "Software compiled at ");
   fprintf(STDSTREAM, __TIME__);
   fprintf(STDSTREAM, "\n\r");
   fprintf(STDSTREAM, "Source code file is ");
   fprintf(STDSTREAM, __FILE__);
   fprintf(STDSTREAM, "\n\r");

}

