From 991cae8c076d9da475bf833186219b3d2a396f29 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Sun, 16 Jan 2000 12:17:59 +0000 Subject: [lcd4linux @ 2000-01-16 12:17:59 by reinelt] Initial revision --- lcd2041.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 lcd2041.c (limited to 'lcd2041.c') diff --git a/lcd2041.c b/lcd2041.c new file mode 100644 index 0000000..4987697 --- /dev/null +++ b/lcd2041.c @@ -0,0 +1,314 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "lcd2041.h" + +#define BAR_HORI 1 +#define BAR_VERT 2 +#define BAR_DUAL 3 + +static int lcd; +static char *lcd_device=NULL; +static int bar_mode=0; + +typedef struct { + int l1; + int l2; + int chr; +} SEGMENT; + +typedef struct { + int l1; + int l2; + int lru; +} CHARACTER; + +static SEGMENT Segment[COLS+1][ROWS+1]; +static CHARACTER Character[CHAR]; + +static int lcd_open(void) +{ + int fd; + struct termios portset; + + fd = open(lcd_device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd==-1) { + fprintf (stderr, "open(%s) failed: %s\n", lcd_device, strerror(errno)); + return -1; + } + if (tcgetattr(fd, &portset)==-1) { + fprintf (stderr, "tcgetattr(%s) failed: %s\n", lcd_device, strerror(errno)); + return -1; + } + cfmakeraw(&portset); + cfsetospeed(&portset, B19200); + if (tcsetattr(fd, TCSANOW, &portset)==-1) { + fprintf (stderr, "tcsetattr(%s) failed: %s\n", lcd_device, strerror(errno)); + return -1; + } + return fd; +} + + +static void lcd_write (char *string, int len) +{ + if (lcd==-1) return; + if (write (lcd, string, len)==-1) { + if (errno==EAGAIN) { + usleep(1000); + if (write (lcd, string, len)>=0) return; + } + fprintf (stderr, "write(%s) failed: %s\n", lcd_device, strerror(errno)); + } +} + + +void lcd_clear (void) +{ + lcd_write ("\014", 1); +} + + +void lcd_put (int x, int y, char *string) +{ + char buffer[256]; + snprintf (buffer, sizeof(buffer), "\376G%c%c%s", x, y, string); + lcd_write (buffer, strlen(buffer)); +} + +void lcd_hbar (int x, int y, int dir, int max, int len) +{ + char buffer[COLS+5]; + char *p; + + if (bar_mode!=BAR_HORI) { + lcd_write ("\376h", 2); + bar_mode=BAR_HORI; + } + + if (len<1) len=1; + else if (len>max) len=max; + if (dir!=0) len=max-len; + + snprintf (buffer, sizeof(buffer), "\376G%c%c", x, y); + p=buffer+4; + + while (max>0 && p-buffer=XRES) { + *p=dir?32:255; + len-=XRES; + } else { + *p=dir?8-len:len-1; + len=0; + } + max-=XRES; + p++; + } + lcd_write (buffer, p-buffer); +} + + +void lcd_vbar (int x, int y, int dir, int max, int len) +{ + char buffer[6]; + unsigned char c; + + if (bar_mode!=BAR_VERT) { + lcd_write ("\376v", 2); + bar_mode=BAR_VERT; + } + + if (len<1) len=1; + else if (len>max) len=max; + + while (max>0 && y>0) { + if (len==0) { + c=32; + } else if (len>=XRES) { + c=255; + len-=XRES; + } else { + c=len; + len=0; + } + snprintf (buffer, sizeof(buffer), "\376G%c%c%c", x, y, c); + lcd_write (buffer, 5); + max-=XRES; + y--; + } +} + + +static void lcd_dbar_init (void) +{ + int x, y; + + bar_mode=BAR_DUAL; + + for (x=0; xmax) len1=max; + + if (len2<1) len2=1; + else if (len2>max) len2=max; + + while (max>0 && x<=COLS) { + if (len1==0) { + Segment[x][y].l1=0; + } else if (len1>=XRES) { + Segment[x][y].l1=XRES; + len1-=XRES; + } else { + Segment[x][y].l1=len1; + len1=0; + } + if (len2==0) { + Segment[x][y].l2=0; + } else if (len2>=XRES) { + Segment[x][y].l2=XRES; + len2-=XRES; + } else { + Segment[x][y].l2=len2; + len2=0; + } + max-=XRES; + x++; + } +} + +void lcd_dbar_flush (void) +{ + int i, x, y; + + for (y=0; y<=ROWS; y++) { + for (x=0; x<=COLS; x++) { + if ((Segment[x][y].l1==0 && Segment[x][y].l2==XRES) || (Segment[x][y].l1==XRES && Segment[x][y].l2==0)) + Segment[x][y].chr=lcd_dbar_char(Segment[x][y].l1, Segment[x][y].l2); + } + } + for (y=0; y<=ROWS; y++) { + for (x=0; x<=COLS; x++) { + if (Segment[x][y].l1!=-1 || Segment[x][y].l2!=-1) + Segment[x][y].chr=lcd_dbar_char(Segment[x][y].l1, Segment[x][y].l2); + } + } + + for (i=0; i0) + Character[i].lru--; + } + + for (y=0; y<=ROWS; y++) { + for (x=0; x<=COLS; x++) { + if (Segment[x][y].l1!=-1 || Segment[x][y].l2!=-1) { + char buffer[6]; + snprintf (buffer, sizeof(buffer), "\376G%c%c%c", x, y, Segment[x][y].chr); + lcd_write (buffer, 5); + } + } + } +} + + +int lcd_init (char *device) +{ + if (lcd_device) free (lcd_device); + lcd_device=strdup(device); + lcd=lcd_open(); + if (lcd==-1) return -1; + + lcd_clear(); + lcd_write ("\376B", 3); // backlight on + lcd_write ("\376K", 2); // cursor off + lcd_write ("\376T", 2); // blink off + lcd_write ("\376D", 2); // line wrapping off + lcd_write ("\376R", 2); // auto scroll off + lcd_write ("\376V", 2); // GPO off + + return 0; +} + +void lcd_contrast (int contrast) +{ + char buffer[4]; + snprintf (buffer, 4, "\376P%c", contrast); + lcd_write (buffer, 3); +} + -- cgit v1.2.3