/* vim: set sw=8 ts=8 si : */
/*************************************************************************
Title:    linuxfocus interactive lcd display
Author:   guido socher 
Copyright: GPL
**************************************************************************/

#include 
#include 
#include 
#include 
#include 
#include "lcd.h"	/* these are the prototypes and defines for lcd.c */
#include "avr-util.h"
#include "uart.h"
#include "analog.h"
#include "hardwarewd.h"

static char uart_outbuf[UART_RX_BUFFER_SIZE+1];

#define reply_ok() uart_sendstr_P("ok\n")
#define reply_err() uart_sendstr_P("err\n")


/* should be twice the length of the banner string */
#define BANNERSCROLLEN 30
/* Input Push Buttons */
#define BUTTON0 PIND6
#define BUTTON0DDR DDRD
#define BUTTON0PIN PIND
#define BUTTON1 PIND3
#define BUTTON1DDR DDRD
#define BUTTON1PIN PIND
/* LED1=red */
#define LED1 PD5
#define LED1DDR DDRD
#define LED1PORT PORTD
/* LED0=green */
#define LED0 PC5
#define LED0DDR DDRC
#define LED0PORT PORTC
int main(void)
{
	char *banner = PSTR ("linuxfocus.org");
	unsigned char i,j,banneron,rxresult,status,buttoninfo,autokickwd;
	int i16bit;
	unsigned int ignorebutton;
	char cmd;
	char *val;


	/* initialize watch dog/relai */
	autokickwd=0;
	wd_init();
	/* no messages about button press by default */
	buttoninfo=0;
	ignorebutton=0;
	/* initialize display, cursor off */
	lcd_init(LCD_DISP_ON);
	/* initialize LED as output */
	sbi(LED0DDR,LED0);
	sbi(LED1DDR,LED1);
	/* button as digital input */
	cbi(BUTTON0DDR,BUTTON0);
	cbi(BUTTON1DDR,BUTTON1);
	/* LEDs off */
	sbi(LED0PORT,LED0);
	sbi(LED1PORT,LED1);
	/* initialize rs232 */
	uart_init();
	banneron=1;
	sei(); /* enable interrupt */
	lcd_clrscr();


	while(1){
		rxresult=uart_getrxbufnl(uart_outbuf);
		if (banneron){
			/* display a scroll banner until we
			* get the first command */
			for (i=0;i= '0'){
				i=*val - '0'; // convert to integer;
			}
			j=(unsigned char)atoi((val+1));
			lcd_gotoxy(j,i);
			status=1;
		}
		if (cmd=='c'){
			switch (*val){
				case 'h':
					lcd_home();
					status=1;
					break;
				case 'c':
					lcd_clrscr();
					status=1;
					break;
				case 'l':
					/* one left */
					lcd_command(LCD_MOVE_CURSOR_LEFT);
					status=1;
					break;
				case 'r':
					/* one right */
					lcd_command(LCD_MOVE_CURSOR_RIGHT);
					status=1;
					break;
				case 'n':
					/* normal dispaly (no blink) */
					lcd_command(LCD_DISP_ON);
					status=1;
					break;
				case 'b':
					/* blink at next entry */
					lcd_command(LCD_DISP_ON_BLINK);
					status=1;
					break;
			}
		}
		if (cmd=='a'){
			/* start analog conversion for given ADC pin */
			i=(unsigned char)atoi(val);
			i16bit=convertanalog(i);
			/* display the result value e.g a0:123 */
			uart_sendchar('a');
			uart_sendchar(*val);
			uart_sendchar(':');
			itoa(i16bit,uart_outbuf,10);
			uart_sendstr(uart_outbuf);
			uart_sendchar('\n');
			status=2;
		}
		if (cmd=='s'){
			i=(unsigned char)atoi(val);
			wd_settime(i);
			status=1;
		}
		if (cmd=='b'){
			switch (*val){
				case '0':
					buttoninfo=0;
					status=1;
					break;
				case '?':
					uart_sendchar('b');
					uart_sendchar(':');
					i=buttoninfo + '0';
					uart_sendchar(i);
					uart_sendchar('\n');
					status=2;
					break;
				case '1':
					buttoninfo=1;
					status=1;
					break;
			}
		}
		if (cmd=='w'){
			switch (*val){
				case '?':
					i=wd_status();
					if (i==2) i=3;
				        if (i==1 && autokickwd==1){
						i=2;
					}
					i=i + '0';
					uart_sendchar('w');
					uart_sendchar(':');
					uart_sendchar(i);
					uart_sendchar('\n');
					status=2;
					break;
				case 's':
					wd_gettime(&i);
					uart_sendchar('s');
					uart_sendchar(':');
					itoa(i,uart_outbuf,10);
					uart_sendstr(uart_outbuf);
					uart_sendchar('\n');
					status=2;
					break;
				case '1':
					wd_start();
					autokickwd=0;
					status=1;
					break;
				case '2':
					wd_settime(110);
					wd_start();
					autokickwd=1;
					status=1;
					break;
				case '0':
					wd_stop();
					autokickwd=0;
					status=1;
					break;
			}
		}
		/* command handling done. now return status */
		if (status==1){
			reply_ok();
		}
		if (status==0){
			reply_err();
		}
	}

}