/***************************************************************************
liblcd 1.0.0
Copyright 1999 by Nathan Anderson, ALL RIGHTS RESERVED
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library (in a file called "COPYING"); if not,
visit or write to:
Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA
***************************************************************************
liblcd is a simple Linux user-space driver for RS232-driven LCD
alphanumeric and graphical displays. It is more tailored to the specific
model of LCD I'm using (Scott Electronics SGX-120L / G12032,
; it is a graphical display), but it should work
with most any LCD that can understand ASCII. Many of the codes are the
same on the different serial LCDs (though slight subtleties and big
differences exist...it depends upon how the model of the display implements
its functionality). Even if your display is not a graphical one, you
should be able to take advantage of the text functions.
The driver can either be statically linked to your project...
$ gcc -o project project.c liblcd.o
...or it can live as a shared library and dynamically link to your
project...
$ gcc -o project project.c -llcd
You must lcd_open( ) the special device you wish to use, and then
lcd_init( ) the display. After that, you can lcd_write( ) to the buffer
and then lcd_flush( ) to send the buffer to the LCD. Or, if you just
wait for the 80-character buffer to fill up, it will flush itself.
Use the included Makefile to build the library. Running 'make' will build
an object file that can be statically linked. If you wish to make a .so,
then run 'make install' (as 'root') which will build and install the shared
library version for you.
I apologize for the lack of documentation. In the (hopefully) near future
I hope to make up for that. In the meantime, if something isn't obvious to
you, feel free to contact me at .
-- Nathan Anderson
***************************************************************************/
#define LIBLCD_C
#include "liblcd.h"
int lcd_open( const char * device, const speed_t speed )
{
char fnname[ ] = "lcd_open";
termios newtio;
int rc;
if( speed != B2400 && speed != B9600 )
return lcd_err( ELCDBAUD, fnname );
rc = open( device, O_WRONLY | O_NOCTTY );
if( rc < 0 )
{
perror( device );
return lcd_err( ELCDOPEN, fnname );
}
fd_com = rc;
tcgetattr( fd_com, &oldtio );
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag = speed | CS8 | CLOCAL;
newtio.c_oflag = 0;
tcflush( fd_com, TCOFLUSH );
tcsetattr( fd_com, TCSANOW, &newtio );
status = SLCDOPEN;
return 0;
}
int lcd_init( char initopts )
{
char fnname[ ] = "lcd_init";
char lcdinitstr[ 4 ] = "\0";
char localbuf[ 2 ] = "\0\0";
int rc;
if( status < SLCDOPEN )
return lcd_err( ELCDNOPN, fnname );
memset( buf, '\0', BUFSIZE );
/* 14 == turn on backlight,
15 == turn off backlight,
2 == inverse color,
3 == normal color,
12 == clear LCD screen */
if( ( initopts & BACKLIGHT ) == BACKLIGHT )
localbuf[ 0 ] = 14;
else
localbuf[ 0 ] = 15;
strcat( lcdinitstr, ( const char * ) localbuf );
if( ( initopts & INVERSETXT ) == INVERSETXT )
localbuf[ 0 ] = 2;
else
localbuf[ 0 ] = 3;
strcat( lcdinitstr, ( const char * ) localbuf );
if( ( initopts & CLEARSCR ) == CLEARSCR )
{
localbuf[ 0 ] = 12;
strcat( lcdinitstr, ( const char * ) localbuf );
}
rc = ( int ) write( fd_com, lcdinitstr, strlen( lcdinitstr ) );
if( rc < 0 )
return lcd_err( ELCDINIT, fnname );
status = SLCDINIT;
return 0;
}
int lcd_reopen( const char * device )
{
char fnname[ ] = "lcd_reopen";
int rc;
rc = open( device, O_WRONLY | O_NOCTTY );
if( rc < 0 )
{
perror( device );
return lcd_err( ELCDOPEN, fnname );
}
fd_com = rc;
tcgetattr( fd_com, &oldtio );
status = SLCDINIT;
return 0;
}
int lcd_close( )
{
char fnname[ ] = "lcd_close";
if( status < SLCDOPEN )
return lcd_err( ELCDNOPN, fnname );
tcsetattr( fd_com, TCSAFLUSH, &oldtio );
close( fd_com );
status = 0;
return 0;
}
int lcd_err( int errcode, const char * callingfn )
{
if( errcode > NUM_ERR )
errcode = NUM_ERR + 1; /* false error */
fprintf( stderr, "%s( ): %s.\n", callingfn, err_str[ errcode - 1 ] );
return errcode;
}
int lcd_clear( )
{
char fnname[ ] = "lcd_clear";
char code[ 2 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
sprintf( code, "%c", 12 );
lcd_write( code );
lcd_flush( );
return 0;
}
int lcd_gotoxy( int x, int y )
{
char fnname[ ] = "lcd_gotoxy";
char code = 16;
char cmd[ 5 ];
int pos;
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( x > 19 || y > 3 )
return lcd_err( ELCDVOOB, fnname );
pos = x + ( y * 20 );
sprintf( cmd, "%c%d ", code, pos );
lcd_write( cmd );
return 0;
}
int lcd_write( const char * str )
{
char fnname[ ] = "lcd_write";
char * localbuf;
int buffree;
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
buffree = BUFSIZE - strlen( buf );
if( strlen( str ) <= buffree )
strcat( buf, str );
else
{
int leftover;
leftover = strlen( str ) - buffree;
localbuf = ( char * ) malloc( leftover * sizeof( char ) );
strcpy( localbuf, str + ( strlen( str ) - leftover ) );
strncat( buf, str, buffree );
lcd_flush( );
lcd_write( localbuf );
free( localbuf );
}
return 0;
}
int lcd_flush( )
{
char fnname[ ] = "lcd_flush";
int rc;
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
rc = ( int ) write( fd_com, buf, strlen( buf ) );
if( rc < 0 )
return lcd_err( ELCDWRIT, fnname );
memset( buf, '\0', BUFSIZE );
return 0;
}
int lcd_backlight( int state )
{
char fnname[ ] = "lcd_backlight";
char code[ 2 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( state < 0 || state > 1 )
return lcd_err( ELCDVOOB, fnname );
if( state == ON )
sprintf( code, "%c", 14 );
else
sprintf( code, "%c", 15 );
lcd_write( code );
return 0;
}
int lcd_inversetxt( int state )
{
char fnname[ ] = "lcd_inversetxt";
char code[ 2 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( state < 0 || state > 1 )
return lcd_err( ELCDVOOB, fnname );
if( state == ON )
sprintf( code, "%c", 2 );
else
sprintf( code, "%c", 3 );
lcd_write( code );
return 0;
}
int lcd_g_setcolor( int color )
{
char fnname[ ] = "lcd_g_setcolor";
char code[ 5 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( color != BLACK && color != WHITE )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cI%d ", 27, color );
lcd_write( code );
return 0;
}
int lcd_g_loadimg( int rompage )
{
char fnname[ ] = "lcd_g_loadimg";
char code[ 5 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( rompage < 0 || rompage > 7 )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cE%d ", 27, rompage );
lcd_write( code );
return 0;
}
int lcd_g_drawline( int x1, int y1, int x2, int y2 )
{
char fnname[ ] = "lcd_g_drawline";
char code[ 17 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( ( x1 < 0 || x1 > 119 ) || ( x2 < 0 || x2 > 119 ) ||
( y1 < 0 || y1 > 31 ) || ( y2 < 0 || y2 > 31 ) )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cL%d %d %d %d ", 27, x1, y1, x2, y2 );
lcd_write( code );
return 0;
}
int lcd_g_drawbox( int x1, int y1, int x2, int y2 )
{
char fnname[ ] = "lcd_g_drawbox";
char code[ 17 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( ( x1 < 0 || x1 > 119 ) || ( x2 < 0 || x2 > 119 ) ||
( y1 < 0 || y1 > 31 ) || ( y2 < 0 || y2 > 31 ) )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cL%d %d %d %d ", 27, x1, y1, x2, y1 );
lcd_write( code );
sprintf( code, "%cL%d %d %d %d ", 27, x2, y1, x2, y2 );
lcd_write( code );
sprintf( code, "%cL%d %d %d %d ", 27, x2, y2, x1, y2 );
lcd_write( code );
sprintf( code, "%cL%d %d %d %d ", 27, x1, y2, x1, y1 );
lcd_write( code );
return 0;
}
int lcd_g_plotdot( int x, int y )
{
char fnname[ ] = "lcd_g_plotdot";
char code[ 10 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( ( x < 0 || x > 119 ) || ( y < 0 || y > 31 ) )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cP%d %d ", 27, x, y );
lcd_write( code );
return 0;
}
int lcd_g_revline( int row )
{
char fnname[ ] = "lcd_g_revline";
char code[ 6 ];
if( status < SLCDINIT )
return lcd_err( ELCDNINI, fnname );
if( row < 0 || row > 15 )
return lcd_err( ELCDVOOB, fnname );
sprintf( code, "%cR%d ", 27, row );
lcd_write( code );
return 0;
}