[lcd4linux @ 2005-06-09 17:41:47 by reinelt]

M50530 fixes (many thanks to Szymon Bieganski)

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@568 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
This commit is contained in:
reinelt
2005-06-09 17:41:47 +00:00
parent d318a5df2f
commit 6184295b8a
3 changed files with 313 additions and 161 deletions
+29 -26
View File
@@ -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!!!!
(C) 2005 Paul Kamphuis & Luis Correia
The following code is WORK IN PROGRESS, since it basicly 'works for us...'
We have removed all of the delays from this code, as the I2C bus is slow enough...
(maximum possible speed is 100KHz only)
(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)
*/
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;
}
+279 -132
View File
@@ -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;
}
if (cfg_number(section, "GPOs", 0, 0, 8, &gpos) < 0)
return -1;
info("%s: controlling %d GPO's", Name, gpos);
free(s);
DROWS = rows;
DCOLS = cols;
GPOS = gpos;
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;
}
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);
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 */
+5 -3
View File
@@ -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'