diff options
| author | reinelt <> | 2005-06-09 17:41:47 +0000 | 
|---|---|---|
| committer | reinelt <> | 2005-06-09 17:41:47 +0000 | 
| commit | 310c3593f1fe2ca7d51e91ab2b742ce3f9c2fa76 (patch) | |
| tree | bda8384fd79787bb59050954b4c56faa57b28a80 | |
| parent | dea76e833323f15f60a7c38bb1f9af0284a70531 (diff) | |
| download | lcd4linux-310c3593f1fe2ca7d51e91ab2b742ce3f9c2fa76.tar.gz | |
[lcd4linux @ 2005-06-09 17:41:47 by reinelt]
M50530 fixes (many thanks to Szymon Bieganski)
Diffstat (limited to '')
| -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' | 
