/* vim: set sw=8 ts=8 si : */ /************************************************************************* Title: linuxfocus interactive lcd display Author: guido socher <guido(at)linuxfocus.org> Copyright: GPL **************************************************************************/ #include <io.h> #include <progmem.h> #include <interrupt.h> #include <string-avr.h> #include <stdlib.h> #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 /* auto kick WD timeout */ #define AWDTOUT 20 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<BANNERSCROLLEN;i++) { lcd_clrscr(); rolltext_lcd_p(banner,i); ignorebutton=65000; // delay but read input while(ignorebutton){ rxresult=uart_getrxbufnl(uart_outbuf); ignorebutton--; if (rxresult){ lcd_clrscr(); ignorebutton=0; banneron=0; i=BANNERSCROLLEN; } } } } if (buttoninfo && ignorebutton==0){ if (bit_is_clear(BUTTON0PIN,BUTTON0)){ uart_sendchar('#'); uart_sendchar('0'); uart_sendchar('\n'); ignorebutton=55000; // debounce, ignore button for a while } if (bit_is_clear(BUTTON1PIN,BUTTON1)){ uart_sendchar('#'); uart_sendchar('1'); uart_sendchar('\n'); ignorebutton=55000; // debounce, ignore button for a while } } if (ignorebutton) ignorebutton--; if (rxresult==0){ continue; } /* valid command are: * l=10 led 1 off * l=01 led 0 on * b=1 info messages for button press * d=someting write someting to display * D=someting clear then write someting to display * a=0 get analog value of ADC0 * g=115 go to line 1 pos 15 on the lcd * c=c command clear display * c=h command home * c=r one right * c=l one left * c=b blink cursor * c=n normal cursor * w=1 enable watch dog * w=2 enable watch dog, any d= or D= command will kick the wd * w=0 disable watch dog * w=? show whether wd is on or off, or if there * was a timeout (3) * w=s get current time out * s=1-255 set watchdog timeout to multiple of 16sec * you must set s periodically. It will decrement. * */ /* now parse the comands and act on them */ if (strlen(uart_outbuf) < 3) { reply_err(); continue; } if (uart_outbuf[1] != '='){ reply_err(); continue; } val=&(uart_outbuf[2]); cmd=uart_outbuf[0]; status=0; /* act on the commands */ if (cmd=='l'){ /* change LEDs */ i16bit=atoi(val); switch (i16bit){ case 0: sbi(LED0PORT,LED0); /* off */ status=1; break; case 10: sbi(LED1PORT,LED1); /* off */ status=1; break; case 1: cbi(LED0PORT,LED0); /* on */ status=1; break; case 11: cbi(LED1PORT,LED1); /* on */ status=1; break; } } if (cmd=='D'){ if (autokickwd) wd_settime(AWDTOUT); lcd_clrscr(); /* display string */ lcd_puts(val); status=1; } if (cmd=='d'){ if (autokickwd) wd_settime(AWDTOUT); /* display string */ lcd_puts(val); status=1; } if (cmd=='g'){ i=*val; if (i < '5' && 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(AWDTOUT); 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(); } } }
mirror server hosted at Truenetwork, Russian Federation.