From 72fd720c2d1a819d454771f99e86d852416e568e Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Mon, 7 Apr 2003 06:03:10 +0000 Subject: [lcd4linux @ 2003-04-07 06:02:58 by reinelt] further parallel port abstraction --- T6963.c | 259 ++++++++++++++++++++++++---------------------------------------- 1 file changed, 98 insertions(+), 161 deletions(-) (limited to 'T6963.c') diff --git a/T6963.c b/T6963.c index 85aedbc..e7b7263 100644 --- a/T6963.c +++ b/T6963.c @@ -1,4 +1,4 @@ -/* $Id: T6963.c,v 1.5 2003/02/22 07:53:10 reinelt Exp $ +/* $Id: T6963.c,v 1.6 2003/04/07 06:03:00 reinelt Exp $ * * driver for display modules based on the Toshiba T6963 chip * @@ -20,6 +20,9 @@ * * * $Log: T6963.c,v $ + * Revision 1.6 2003/04/07 06:03:00 reinelt + * further parallel port abstraction + * * Revision 1.5 2003/02/22 07:53:10 reinelt * cfg_get(key,defval) * @@ -53,116 +56,82 @@ #include #include #include -#include -#include -#include #include -#include - -#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H) -#define WITH_PPDEV -#include -#include -#else -#error The T6963 driver needs ppdev -#error cannot compile T6963 driver -#endif #include "debug.h" #include "cfg.h" #include "display.h" #include "bar.h" +#include "parport.h" #include "udelay.h" #include "pixmap.h" -/* - * /CE (Chip Enable) <==> /Strobe - * C/D (Command/Data) <==> /Select - * /RD (Read) <==> /AutoFeed - * /WR (Write) <==> Init - * - */ - -#define CE_L PARPORT_CONTROL_STROBE -#define CE_H 0 - -#define CD_L PARPORT_CONTROL_SELECT -#define CD_H 0 - -#define RD_L PARPORT_CONTROL_AUTOFD -#define RD_H 0 - -#define WR_L 0 -#define WR_H PARPORT_CONTROL_INIT - - #define XRES 6 #define YRES 8 static LCD Lcd; -static char *PPdev=NULL; -static int PPfd=-1; - unsigned char *Buffer1, *Buffer2; +static unsigned char SIGNAL_CE; +static unsigned char SIGNAL_CD; +static unsigned char SIGNAL_RD; +static unsigned char SIGNAL_WR; + + +// Fixme: +static int bug=0; + // perform normal status check void T6_status1 (void) { - int direction; int n; - unsigned char ctrl, data; - - // turn off data line drivers - direction=1; - ioctl (PPfd, PPDATADIR, &direction); - // lower RD and CE - ctrl = RD_L | WR_H | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + // turn off data line drivers + parport_direction (1); - ndelay(150); // Access Time: 150 ns + // lower CE and RD + parport_control (SIGNAL_CE | SIGNAL_RD, 0); + // Access Time: 150 ns + ndelay(150); + // wait for STA0=1 and STA1=1 n=0; do { rep_nop(); if (++n>1000) { debug("hang in status1"); + bug=1; break; } - ioctl (PPfd, PPRDATA, &data); - } while ((data & 0x03) != 0x03); + } while ((parport_read() & 0x03) != 0x03); // rise RD and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE); - // turn on data line drivers - direction=0; - ioctl (PPfd, PPDATADIR, &direction); + // Output Hold Time: 50 ns + ndelay(50); + // turn on data line drivers + parport_direction (0); } -// Fixme: -static int bug=0; + // perform status check in "auto mode" void T6_status2 (void) { - int direction; int n; - unsigned char ctrl, data; // turn off data line drivers - direction=1; - ioctl (PPfd, PPDATADIR, &direction); - + parport_direction (1); + // lower RD and CE - ctrl = RD_L | WR_H | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, 0); - ndelay(150); // Access Time: 150 ns + // Access Time: 150 ns + ndelay(150); // wait for STA3=1 n=0; @@ -173,114 +142,110 @@ void T6_status2 (void) bug=1; break; } - ioctl (PPfd, PPRDATA, &data); - } while ((data & 0x08) != 0x08); + } while ((parport_read() & 0x08) != 0x08); // rise RD and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE); + + // Output Hold Time: 50 ns + ndelay(50); // turn on data line drivers - direction=0; - ioctl (PPfd, PPDATADIR, &direction); + parport_direction (0); } static void T6_write_cmd (unsigned char cmd) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status1(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &cmd); - + parport_data (cmd); + // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse width + // Pulse width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); } + static void T6_write_data (unsigned char data) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status1(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &data); + parport_data (data); // lower C/D - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, 0); - ndelay(20); // C/D Setup Time + // C/D Setup Time + ndelay(20); // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse Width + // Pulse Width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); // rise CD - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, SIGNAL_CD); } + static void T6_write_auto (unsigned char data) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status2(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &data); + parport_data (data); // lower C/D - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, 0); - ndelay(20); // C/D Setup Time + // C/D Setup Time + ndelay(20); // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse Width + // Pulse Width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); // rise CD - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, SIGNAL_CD); } + static void T6_send_byte (unsigned char cmd, unsigned char data) { T6_write_data(data); T6_write_cmd(cmd); } + static void T6_send_word (unsigned char cmd, unsigned short data) { T6_write_data(data&0xff); @@ -288,6 +253,7 @@ static void T6_send_word (unsigned char cmd, unsigned short data) T6_write_cmd(cmd); } + static void T6_memset(unsigned short addr, unsigned char data, int len) { int i; @@ -324,40 +290,15 @@ static void T6_memcpy(unsigned short addr, unsigned char *data, int len) } -static int T6_open (void) -{ - debug ("using ppdev %s", PPdev); - PPfd=open(PPdev, O_RDWR); - if (PPfd==-1) { - error ("open(%s) failed: %s", PPdev, strerror(errno)); - return -1; - } - -#if 0 - if (ioctl(PPfd, PPEXCL)) { - debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno)); - } else { - debug ("ioctl(%s, PPEXCL) succeded."); - } -#endif - - if (ioctl(PPfd, PPCLAIM)) { - error ("ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno)); - return -1; - } - - return 0; -} - int T6_clear (void) { int rows; rows=(Lcd.rows>8 ? 8 : Lcd.rows); - + T6_memset(0x0000, 0, Lcd.cols*rows); // clear text area T6_memset(0x0200, 0, Lcd.cols*rows*8); // clear graphic area - + if (Lcd.rows>8) { T6_memset(0x8000, 0, Lcd.cols*(Lcd.rows-rows)); // clear text area #2 T6_memset(0x8200, 0, Lcd.cols*(Lcd.rows-rows)*8); // clear graphic area #2 @@ -369,23 +310,10 @@ int T6_clear (void) return pix_clear(); } + int T6_init (LCD *Self) { - char *port; - Lcd=*Self; - - if (PPdev) { - free (PPdev); - PPdev=NULL; - } - - port=cfg_get ("Port",NULL); - if (port==NULL || *port=='\0') { - error ("T6963: no 'Port' entry in %s", cfg_file()); - return -1; - } - PPdev=strdup(port); if (pix_init (Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres)!=0) { error ("T6963: pix_init(%d, %d, %d, %d) failed", Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres); @@ -404,11 +332,23 @@ int T6_init (LCD *Self) return -1; } - udelay_init(); + if ((SIGNAL_CE=parport_wire ("CE", "STROBE"))==0xff) return -1; + if ((SIGNAL_CD=parport_wire ("CD", "SELECT"))==0xff) return -1; + if ((SIGNAL_RD=parport_wire ("RD", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_WR=parport_wire ("WR", "INIT"))==0xff) return -1; - if (T6_open()!=0) + if (parport_open() != 0) { + error ("HD44780: could not initialize parallel port!"); return -1; + } + + // rise CE, CD, RD and WR + parport_control (SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR, + SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR); + // set direction: write + parport_direction (0); + debug ("setting %d columns", Lcd.cols); T6_send_word (0x40, 0x0000); // Set Text Home Address @@ -428,16 +368,19 @@ int T6_init (LCD *Self) return 0; } + int T6_put (int row, int col, char *text) { return pix_put(row,col,text); } + int T6_bar (int type, int row, int col, int max, int len1, int len2) { return pix_bar(type,row,col,max,len1,len2); } + int T6_flush (void) { int i, j, e; @@ -470,19 +413,13 @@ int T6_flush (void) return 0; } + int T6_quit (void) { - debug ("closing ppdev %s", PPdev); - if (ioctl(PPfd, PPRELEASE)) { - error ("ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno)); - } - if (close(PPfd)==-1) { - error ("close(%s) failed: %s", PPdev, strerror(errno)); - return -1; - } - return 0; + return parport_close(); } + LCD T6963[] = { { name: "TLC1091", rows: 16, -- cgit v1.2.3