diff options
-rw-r--r-- | drv_HD44780.c | 55 | ||||
-rw-r--r-- | drv_M50530.c | 409 | ||||
-rw-r--r-- | lcd4linux.conf.sample | 8 |
3 files changed, 312 insertions, 160 deletions
diff --git a/drv_HD44780.c b/drv_HD44780.c index 7377c9e6..7444515 100644 --- a/drv_HD44780.c +++ b/drv_HD44780.c @@ -1,4 +1,4 @@ -/* $Id: drv_HD44780.c,v 1.53 2005/06/01 11:17:54 pk_richman Exp $ +/* $Id: drv_HD44780.c,v 1.54 2005/06/09 17:41:47 reinelt Exp $ * * new style driver for HD44780-based displays * @@ -32,6 +32,9 @@ * * * $Log: drv_HD44780.c,v $ + * Revision 1.54 2005/06/09 17:41:47 reinelt + * M50530 fixes (many thanks to Szymon Bieganski) + * * Revision 1.53 2005/06/01 11:17:54 pk_richman * marked unused parameters * @@ -840,21 +843,21 @@ static void drv_HD_PP_stop(void) /****************************************/ /* - DISCLAIMER!!!! - - The following code is WORK IN PROGRESS, since it basicly 'works for us...' + DISCLAIMER!!!! + + The following code is WORK IN PROGRESS, since it basicly 'works for us...' - (C) 2005 Paul Kamphuis & Luis Correia + (C) 2005 Paul Kamphuis & Luis Correia - We have removed all of the delays from this code, as the I2C bus is slow enough... - (maximum possible speed is 100KHz only) + We have removed all of the delays from this code, as the I2C bus is slow enough... + (maximum possible speed is 100KHz only) - */ + */ static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble) { unsigned char enable; - unsigned char command; /* this is actually the first data byte on the PCF8574 */ + unsigned char command; /* this is actually the first data byte on the PCF8574 */ unsigned char data_block[2]; /* enable signal: 'controller' is a bitmask */ /* bit n .. send to controller #n */ @@ -870,24 +873,24 @@ static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble) enable |= SIGNAL_ENABLE4; /* - The new method Paul Kamphuis has concocted places the 3 needed writes to the I2C device - as a single operation, using the 'i2c_smbus_write_block_data' function. - These actual writes are performed by putting the nibble along with the 'EN' signal. + The new method Paul Kamphuis has concocted places the 3 needed writes to the I2C device + as a single operation, using the 'i2c_smbus_write_block_data' function. + These actual writes are performed by putting the nibble along with the 'EN' signal. - command = first byte to be written, which contains the nibble (DB0..DB3) - data [0] = second byte to be written, which contains the nibble plus the EN signal - data [1] = third byte to be written, which contains the nibble (DB0..DB3) + command = first byte to be written, which contains the nibble (DB0..DB3) + data [0] = second byte to be written, which contains the nibble plus the EN signal + data [1] = third byte to be written, which contains the nibble (DB0..DB3) - Then we write the block as a whole. + Then we write the block as a whole. - The main advantage we see is that we do 2 less IOCTL's from our driver. - */ + The main advantage we see is that we do 2 less IOCTL's from our driver. + */ - command = nibble; + command = nibble; data_block[0] = nibble | enable; data_block[1] = nibble; - drv_generic_i2c_command(command,data_block,2); + drv_generic_i2c_command(command, data_block, 2); } @@ -899,14 +902,16 @@ static void drv_HD_I2C_byte(const unsigned char controller, const unsigned char } -static void drv_HD_I2C_command(const unsigned char controller, const unsigned char cmd, __attribute__ ((unused))const int delay) +static void drv_HD_I2C_command(const unsigned char controller, const unsigned char cmd, __attribute__ ((unused)) + const int delay) { /* send data with RS disabled */ drv_HD_I2C_nibble(controller, ((cmd >> 4) & 0x0f)); drv_HD_I2C_nibble(controller, ((cmd) & 0x0f)); } -static void drv_HD_I2C_data(const unsigned char controller, const char *string, const int len, __attribute__ ((unused)) const int delay) +static void drv_HD_I2C_data(const unsigned char controller, const char *string, const int len, __attribute__ ((unused)) + const int delay) { int l = len; @@ -1168,8 +1173,7 @@ static int drv_HD_start(const char *section, const int quiet) info("%s: using model '%s'", Name, Models[Model].name); } else { error("%s: empty '%s.Model' entry from %s", Name, section, cfg_source()); - if (model) - free(model); + free(model); return -1; } free(model); @@ -1177,8 +1181,7 @@ static int drv_HD_start(const char *section, const int quiet) bus = cfg_get(section, "Bus", "parport"); if (bus == NULL && *bus == '\0') { error("%s: empty '%s.Bus' entry from %s", Name, section, cfg_source()); - if (bus) - free(bus); + free(bus); return -1; } diff --git a/drv_M50530.c b/drv_M50530.c index 7e8bb75..2a90fac 100644 --- a/drv_M50530.c +++ b/drv_M50530.c @@ -1,107 +1,110 @@ -# /* $Id: drv_M50530.c,v 1.18 2005/05/08 04:32:44 reinelt Exp $ - * - * new style driver for M50530-based displays - * - * Copyright (C) 2003 Michael Reinelt <reinelt@eunet.at> - * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> - * - * This file is part of LCD4Linux. - * - * LCD4Linux is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * LCD4Linux 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - * $Log: drv_M50530.c,v $ - * Revision 1.18 2005/05/08 04:32:44 reinelt - * CodingStyle added and applied - * - * Revision 1.17 2005/05/05 08:36:12 reinelt - * changed SELECT to SLCTIN - * - * Revision 1.16 2005/01/18 06:30:23 reinelt - * added (C) to all copyright statements - * - * Revision 1.15 2005/01/06 16:54:53 reinelt - * M50530 fixes - * - * Revision 1.14 2004/06/26 12:04:59 reinelt - * - * uh-oh... the last CVS log message messed up things a lot... - * - * Revision 1.13 2004/06/26 09:27:20 reinelt - * - * added '-W' to CFLAGS - * changed all C++ comments to C ones - * cleaned up a lot of signed/unsigned mistakes - * - * Revision 1.12 2004/06/20 10:09:54 reinelt - * - * 'const'ified the whole source - * - * Revision 1.11 2004/06/06 06:51:59 reinelt - * - * do not display end splash screen if quiet=1 - * - * Revision 1.10 2004/06/05 06:41:39 reinelt - * - * chancged splash screen again - * - * Revision 1.9 2004/06/05 06:13:12 reinelt - * - * splash screen for all text-based display drivers - * - * Revision 1.8 2004/06/02 09:41:19 reinelt - * - * prepared support for startup splash screen - * - * Revision 1.7 2004/06/01 06:45:29 reinelt - * - * some Fixme's processed - * documented some code - * - * Revision 1.6 2004/05/31 05:38:02 reinelt - * - * fixed possible bugs with user-defined chars (clear high bits) - * thanks to Andy Baxter for debugging the MilfordInstruments driver! - * - * Revision 1.5 2004/05/29 15:53:28 reinelt - * - * M50530: reset parport signals on exit - * plugin_ppp: ppp() has two parameters, not three - * lcd4linux.conf.sample: diskstats() corrected - * - * Revision 1.4 2004/05/26 11:37:36 reinelt - * - * Curses driver ported. - * - * Revision 1.3 2004/03/19 09:17:46 reinelt - * - * removed the extra 'goto' function, row and col are additional parameters - * of the write() function now. - * - * Revision 1.2 2004/02/15 21:43:43 reinelt - * T6963 driver nearly finished - * framework for graphic displays done - * i2c_sensors patch from Xavier - * some more old generation files removed - * - * Revision 1.1 2004/02/15 08:22:47 reinelt - * ported USBLCD driver to NextGeneration - * added drv_M50530.c (I forgot yesterday, sorry) - * removed old drivers M50530.c and USBLCD.c - * - */ +/* $Id: drv_M50530.c,v 1.19 2005/06/09 17:41:47 reinelt Exp $ + * + * new style driver for M50530-based displays + * + * Copyright (C) 2003 Michael Reinelt <reinelt@eunet.at> + * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> + * + * This file is part of LCD4Linux. + * + * LCD4Linux is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LCD4Linux 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: drv_M50530.c,v $ + * Revision 1.19 2005/06/09 17:41:47 reinelt + * M50530 fixes (many thanks to Szymon Bieganski) + * + * Revision 1.18 2005/05/08 04:32:44 reinelt + * CodingStyle added and applied + * + * Revision 1.17 2005/05/05 08:36:12 reinelt + * changed SELECT to SLCTIN + * + * Revision 1.16 2005/01/18 06:30:23 reinelt + * added (C) to all copyright statements + * + * Revision 1.15 2005/01/06 16:54:53 reinelt + * M50530 fixes + * + * Revision 1.14 2004/06/26 12:04:59 reinelt + * + * uh-oh... the last CVS log message messed up things a lot... + * + * Revision 1.13 2004/06/26 09:27:20 reinelt + * + * added '-W' to CFLAGS + * changed all C++ comments to C ones + * cleaned up a lot of signed/unsigned mistakes + * + * Revision 1.12 2004/06/20 10:09:54 reinelt + * + * 'const'ified the whole source + * + * Revision 1.11 2004/06/06 06:51:59 reinelt + * + * do not display end splash screen if quiet=1 + * + * Revision 1.10 2004/06/05 06:41:39 reinelt + * + * chancged splash screen again + * + * Revision 1.9 2004/06/05 06:13:12 reinelt + * + * splash screen for all text-based display drivers + * + * Revision 1.8 2004/06/02 09:41:19 reinelt + * + * prepared support for startup splash screen + * + * Revision 1.7 2004/06/01 06:45:29 reinelt + * + * some Fixme's processed + * documented some code + * + * Revision 1.6 2004/05/31 05:38:02 reinelt + * + * fixed possible bugs with user-defined chars (clear high bits) + * thanks to Andy Baxter for debugging the MilfordInstruments driver! + * + * Revision 1.5 2004/05/29 15:53:28 reinelt + * + * M50530: reset parport signals on exit + * plugin_ppp: ppp() has two parameters, not three + * lcd4linux.conf.sample: diskstats() corrected + * + * Revision 1.4 2004/05/26 11:37:36 reinelt + * + * Curses driver ported. + * + * Revision 1.3 2004/03/19 09:17:46 reinelt + * + * removed the extra 'goto' function, row and col are additional parameters + * of the write() function now. + * + * Revision 1.2 2004/02/15 21:43:43 reinelt + * T6963 driver nearly finished + * framework for graphic displays done + * i2c_sensors patch from Xavier + * some more old generation files removed + * + * Revision 1.1 2004/02/15 08:22:47 reinelt + * ported USBLCD driver to NextGeneration + * added drv_M50530.c (I forgot yesterday, sorry) + * removed old drivers M50530.c and USBLCD.c + * + */ /* * @@ -144,6 +147,10 @@ static unsigned char SIGNAL_IOC1; static unsigned char SIGNAL_IOC2; static unsigned char SIGNAL_GPO; +static int FONT5X11; +static int DDRAM; +static int DUTY; + /* Fixme: GPO's not yet implemented */ static int GPOS; /* static int GPO=0; */ @@ -200,9 +207,12 @@ static void drv_M5_write(const int row, const int col, const char *data, const i unsigned int cmd; unsigned int pos; - pos = row * 48 + col; - if (row > 3) - pos -= 168; + if (row < 4) { + pos = row * (DDRAM >> DUTY) + col; + } else { + pos = (row - 4) * (DDRAM >> DUTY) + (DDRAM >> DUTY) / 2 + col; + } + drv_M5_command(0x300 | pos, 20); while (l--) { @@ -216,11 +226,9 @@ static void drv_M5_defchar(const int ascii, const unsigned char *matrix) { int i; - drv_M5_command(0x300 + 192 + 8 * (ascii - CHAR0), 20); + drv_M5_command(0x300 + DDRAM + 8 * (ascii - CHAR0), 20); - /* Fixme: looks like the M50530 cannot control the bottom line */ - /* therefore we have only 7 bytes here */ - for (i = 0; i < 7; i++) { + for (i = 0; i < YRES; i++) { drv_M5_command(0x200 | (matrix[i] & 0x3f), 20); } } @@ -248,44 +256,96 @@ static void drv_M5_setGPO(const int bits) static int drv_M5_start(const char *section, const int quiet) { - char *model, *s; - int rows = -1, cols = -1, gpos = -1; + char *s; + int n; + int rows = -1, cols = -1; + unsigned int SF; - model = cfg_get(section, "Model", "generic"); - if (model != NULL && *model != '\0') { + s = cfg_get(section, "Model", "generic"); + if (s != NULL && *s != '\0') { int i; for (i = 0; Models[i].type != 0xff; i++) { - if (strcasecmp(Models[i].name, model) == 0) + if (strcasecmp(Models[i].name, s) == 0) break; } + free(s); if (Models[i].type == 0xff) { - error("%s: %s.Model '%s' is unknown from %s", Name, section, model, cfg_source()); + error("%s: %s.Model '%s' is unknown from %s", Name, section, s, cfg_source()); return -1; } Model = i; info("%s: using model '%s'", Name, Models[Model].name); } else { error("%s: empty '%s.Model' entry from %s", Name, section, cfg_source()); + free(s); return -1; } s = cfg_get(section, "Size", NULL); if (s == NULL || *s == '\0') { error("%s: no '%s.Size' entry from %s", Name, section, cfg_source()); + free(s); return -1; } if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) { - error("%s: bad size '%s'", Name, s); + error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source()); + free(s); return -1; } + free(s); + DROWS = rows; + DCOLS = cols; - if (cfg_number(section, "GPOs", 0, 0, 8, &gpos) < 0) + s = cfg_get(section, "Font", "5x7"); + if (s == NULL && *s == '\0') { + error("%s: empty '%s.Font' entry from %s", Name, section, cfg_source()); + free(s); return -1; - info("%s: controlling %d GPO's", Name, gpos); + } + if (strcasecmp(s, "5x7") == 0) { + XRES = 5; + YRES = 7; + FONT5X11 = 0; + } else if (strcasecmp(s, "5x11") == 0) { + XRES = 5; + YRES = 11; + FONT5X11 = 1; + } else { + error("%s: bad '%s.Font' entry '%s' from %s", Name, section, s, cfg_source()); + error("%s: should be '5x7' or '5x11'", Name); + free(s); + return -1; + } + free(s); + + + if (DCOLS * DROWS > 256) { + error("%s: %s.Size '%dx%d' is too big, would require %d bytes", Name, section, DCOLS, DROWS, DCOLS * DROWS, cfg_source()); + return -1; + } else if (DCOLS * DROWS > 224) { + DDRAM = 256; + CHARS = 0; + } else if (DCOLS * DROWS > 192) { + DDRAM = 224; + CHARS = FONT5X11 ? 2 : 4; + } else if (DCOLS * DROWS > 160) { + DDRAM = 192; + CHARS = FONT5X11 ? 4 : 8; + } else { + DDRAM = 160; + CHARS = FONT5X11 ? 6 : 12; + } + info("%s: using %d words DDRAM / %d words CGRAM (%d user chars)", Name, DDRAM, 256 - DDRAM, CHARS); + + if (cfg_number(section, "DUTY", 2, 0, 2, &DUTY) < 0) + return -1; + info("%s: using duty %d: 1/%d, %d lines x %d words", Name, DUTY, (XRES + 1) << DUTY, 1 << DUTY, DDRAM >> DUTY); - DROWS = rows; - DCOLS = cols; - GPOS = gpos; + + if (cfg_number(section, "GPOs", 0, 0, 8, &n) < 0) + return -1; + GPOS = n; + info("%s: controlling %d GPO's", Name, GPOS); if (drv_generic_parport_open(section, Name) != 0) { error("%s: could not initialize parallel port!", Name); @@ -304,16 +364,103 @@ static int drv_M5_start(const char *section, const int quiet) /* clear all signals */ drv_generic_parport_control(SIGNAL_EX | SIGNAL_IOC1 | SIGNAL_IOC2 | SIGNAL_GPO, 0); - /* for any mysterious reason, this delay is necessary... */ + /* for some mysterious reason, this delay is necessary... */ udelay(2000); /* set direction: write */ drv_generic_parport_direction(0); - drv_M5_command(0x00FA, 20); /* set function mode */ - drv_M5_command(0x0020, 20); /* set display mode */ - drv_M5_command(0x0050, 20); /* set entry mode */ - drv_M5_command(0x0030, 20); /* set display mode */ + + /* set function (SF) mode: + * Bit 0 : RAM 0 + * Bit 1 : RAM 1 + * Bit 2 : DUTY 0 + * Bit 3 : DUTY 1 + * Bit 4 : FONT: 0 = 5x12, 1 = 5x8 + * Bit 5 : I/O: 0 = 4-bit, 1 = 8-bit + * Bit 6 : 1 + * Bit 7 : 1 + * + * RAM layout: + * 00: 256 words DDRAM, 0 words CGRAM + * 01: 224 words DDRAM, 32 words CGRAM + * 10: 192 words DDRAM, 64 words CGRAM + * 11: 160 words DDRAM, 96 words CGRAM + * + * Duty: + * 00: 1/8 (1/12 for 5x11), 1 line + * 00: 1/16 (1/24 for 5x11), 2 lines + * 00: 1/32 (1/48 for 5x11), 4 lines + * 11: undefined + */ + + /* 11100000 : SF, 8-bit mode */ + SF = 0xE0; + + /* RAM layout */ + switch (DDRAM) { + case 160: + SF |= 0x03; + break; + case 192: + SF |= 0x02; + break; + case 224: + SF |= 0x01; + break; + case 256: + SF |= 0x00; + break; + } + + /* Duty */ + SF |= (DUTY << 2); + + /* Font */ + SF |= (!FONT5X11) << 4; + + + debug("SET FUNCTION MODE 0x%02x", SF); + drv_M5_command(SF, 20); + + + /* set display (SD) mode: + * Bit 0 : 1 = turn on character blinking + * Bit 0 : 1 = turn on cursor blinking + * Bit 0 : 1 = turn on underline display + * Bit 0 : 1 = turn on cursor + * Bit 0 : 1 = turn on display + * Bit 0 : 1 + * Bit 0 : 0 + * Bit 0 : 0 + */ + + /* SD: 0x20 = 00100000 */ + /* SD: turn off display */ + drv_M5_command(0x0020, 20); + + + /* set entry (SE) mode: + * Bit 0 : 1 = inc/dec cursor address after Read + * Bit 1 : 1 = inc/dec cursor address after Write + * Bit 2 : 0 = inc, 1 = dec + * Bit 3 : 1 = inc/dec display start addr after Read + * Bit 4 : 1 = inc/dec display start addr after Write + * Bit 5 : 0 = inc, 1 = dec + * Bit 6 : 1 + * Bit 7 : 0 + * + */ + + /* SE: 0x50 = 01010000 */ + /* SE: increment display start after Write */ + drv_M5_command(0x0050, 20); + + + /* SD: 0x30 = 00110000 */ + /* SD: turn on display */ + drv_M5_command(0x0030, 20); + drv_M5_clear(); @@ -370,9 +517,9 @@ int drv_M5_init(const char *section, const int quiet) int ret; /* display preferences */ - XRES = 5; /* pixel width of one char */ - YRES = 8; /* pixel height of one char */ - CHARS = 8; /* number of user-defineable characters */ + XRES = -1; /* pixel width of one char */ + YRES = -1; /* pixel height of one char */ + CHARS = 0; /* number of user-defineable characters */ CHAR0 = 248; /* ASCII of first user-defineable char */ GOTO_COST = 1; /* number of bytes a goto command requires */ diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index 722eac6..5ff5144 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -195,9 +195,11 @@ Display SimpleLCD { Display M50530-24x8 { Driver 'M50530' - Port '/dev/parport0' + Port '/dev/parports/0' # Port '0x378' Size '24x8' + Font '5x7' + Duty 2 Wire.EX 'STROBE' Wire.IOC1 'SLCTIN' Wire.IOC2 'AUTOFD' @@ -761,10 +763,10 @@ Layout testMySQL { #Display 'CF632' #Display 'CF633' #Display 'Curses' -#Display 'M50530-24x8' +Display 'M50530-24x8' #Display 'LCDTerm' #Display 'CT20x4' -Display 'T6963-240x64' +#Display 'T6963-240x64' #Display 'XWindow' #Display 'USBLCD' #Display 'BWCT' |