Added HD44780 delay options.

This commit is contained in:
robijn
2001-11-01 15:38:49 +00:00
parent 12016257ff
commit 46174150ce
6 changed files with 63 additions and 26 deletions
+10
View File
@@ -119,6 +119,16 @@ Size=20x4
# If you want to use more than 3 HD44780 controllers on the LPT, you need to # If you want to use more than 3 HD44780 controllers on the LPT, you need to
# specify this. See documentation. # specify this. See documentation.
#DelayMult=2
# If your display is slow and cannot keep up with the flow of data from
# LCDd, garbage can appear on the LCDd. Set this delay factor to 2 or 4
# to increase the delays. Default: 1.
DelayBus=true
# You can reduce the inserted dalays by setting this to false.
# On fast PCs it is possible your LCD does not respond correctly.
# Default: true.
[LB216] [LB216]
# LB216 driver # LB216 driver
+16 -10
View File
@@ -118,10 +118,12 @@ hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
} }
port_out (lptPort, 0x03);
if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, enableLines | 0x03); port_out (lptPort, enableLines | 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, ALLEXT ^ OUTMASK); port_out (lptPort + 2, ALLEXT ^ OUTMASK);
hd44780_functions->uPause (1); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, 0x03); port_out (lptPort, 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
@@ -130,7 +132,7 @@ hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver
port_out (lptPort, enableLines | 0x03); port_out (lptPort, enableLines | 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, ALLEXT ^ OUTMASK); port_out (lptPort + 2, ALLEXT ^ OUTMASK);
hd44780_functions->uPause (1); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, 0x03); port_out (lptPort, 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
@@ -139,7 +141,7 @@ hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver
port_out (lptPort, enableLines | 0x03); port_out (lptPort, enableLines | 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, ALLEXT ^ OUTMASK); port_out (lptPort + 2, ALLEXT ^ OUTMASK);
hd44780_functions->uPause (1); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, 0x03); port_out (lptPort, 0x03);
if (extIF) if (extIF)
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
@@ -149,7 +151,7 @@ hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver
port_out (lptPort, enableLines | 0x02); port_out (lptPort, enableLines | 0x02);
if (extIF) if (extIF)
port_out (lptPort + 2, ALLEXT ^ OUTMASK); port_out (lptPort + 2, ALLEXT ^ OUTMASK);
hd44780_functions->uPause (1); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, 0x02); port_out (lptPort, 0x02);
if (extIF) if (extIF)
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
@@ -187,13 +189,15 @@ lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned
enableLines = EnMask[displayID - 1]; enableLines = EnMask[displayID - 1];
port_out (lptPort, portControl | h); port_out (lptPort, portControl | h);
hd44780_functions->uPause (2); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, enableLines | portControl | h); port_out (lptPort, enableLines | portControl | h);
hd44780_functions->uPause (4); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, portControl | h); port_out (lptPort, portControl | h);
port_out (lptPort, portControl | l);
if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, enableLines | portControl | l); port_out (lptPort, enableLines | portControl | l);
hd44780_functions->uPause (4); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort, portControl | l); port_out (lptPort, portControl | l);
} }
@@ -204,14 +208,15 @@ lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned
enableLines = EnMask[(displayID - 1)]; enableLines = EnMask[(displayID - 1)];
port_out (lptPort, portControl | h); port_out (lptPort, portControl | h);
hd44780_functions->uPause (2); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, enableLines ^ OUTMASK); port_out (lptPort + 2, enableLines ^ OUTMASK);
hd44780_functions->uPause (4); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
port_out (lptPort, portControl | l); port_out (lptPort, portControl | l);
if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, enableLines ^ OUTMASK); port_out (lptPort + 2, enableLines ^ OUTMASK);
hd44780_functions->uPause (4); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, 0 ^ OUTMASK); port_out (lptPort + 2, 0 ^ OUTMASK);
} }
} }
@@ -233,6 +238,7 @@ unsigned char lcdstat_HD44780_readkeypad (unsigned int YData)
if (!extIF) { if (!extIF) {
port_out (lptPort + 2, ( ((~YData & 0x03C0) << 6 )) ^ OUTMASK); port_out (lptPort + 2, ( ((~YData & 0x03C0) << 6 )) ^ OUTMASK);
} }
if( delayBus ) hd44780_functions->uPause (1);
// Read inputs // Read inputs
readval = ~ port_in (lptPort + 1) ^ INMASK; readval = ~ port_in (lptPort + 1) ^ INMASK;
+3 -1
View File
@@ -133,8 +133,9 @@ lcdtime_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned
sem_wait (semid); sem_wait (semid);
port_out (lptPort + 2, portControl ^ OUTMASK); port_out (lptPort + 2, portControl ^ OUTMASK);
port_out (lptPort, ch); port_out (lptPort, ch);
if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, (enableLines|portControl) ^ OUTMASK); port_out (lptPort + 2, (enableLines|portControl) ^ OUTMASK);
hd44780_functions->uPause (1); if( delayBus ) hd44780_functions->uPause (1);
port_out (lptPort + 2, portControl ^ OUTMASK); port_out (lptPort + 2, portControl ^ OUTMASK);
sem_signal (semid); sem_signal (semid);
} }
@@ -160,6 +161,7 @@ unsigned char lcdtime_HD44780_readkeypad (unsigned int YData)
if (!extIF) { if (!extIF) {
port_out (lptPort + 2, ( ((~YData & 0x0100) >> 8) | ((~YData & 0x0200) >> 6)) ^ OUTMASK); port_out (lptPort + 2, ( ((~YData & 0x0100) >> 8) | ((~YData & 0x0200) >> 6)) ^ OUTMASK);
} }
if( delayBus ) hd44780_functions->uPause (1);
// Read inputs // Read inputs
readval = ~ port_in (lptPort + 1) ^ INMASK; readval = ~ port_in (lptPort + 1) ^ INMASK;
+8
View File
@@ -138,13 +138,19 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign
// Output the actual data // Output the actual data
port_out (lptPort, ch); port_out (lptPort, ch);
if( delayBus ) hd44780_functions->uPause (1);
// then set EN high // then set EN high
port_out (lptPort + 2, (enableLines|portControl|backlight_bit) ^ OUTMASK); port_out (lptPort + 2, (enableLines|portControl|backlight_bit) ^ OUTMASK);
if( delayBus ) hd44780_functions->uPause (1);
// 80 nS setup from valid data to EN low will be met without any delay // 80 nS setup from valid data to EN low will be met without any delay
// unless you are running a REALLY FAST ISA bus (like 75 MHZ!) // unless you are running a REALLY FAST ISA bus (like 75 MHZ!)
// 230 nS minimum E high time provided by ISA bus delays as well... // 230 nS minimum E high time provided by ISA bus delays as well...
// ABOVE TEXT ignored now, using delays if delayBus is specified
// Set EN low and we're done... // Set EN low and we're done...
port_out (lptPort + 2, (portControl|backlight_bit) ^ OUTMASK); port_out (lptPort + 2, (portControl|backlight_bit) ^ OUTMASK);
@@ -167,6 +173,8 @@ unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData)
port_out (lptPort, ~YData & 0x00FF ); port_out (lptPort, ~YData & 0x00FF );
port_out (lptPort + 2, ( ((~YData & 0x0100) >> 7) | ((~YData & 0x0200) >> 7 )) ^ OUTMASK); port_out (lptPort + 2, ( ((~YData & 0x0100) >> 7) | ((~YData & 0x0200) >> 7 )) ^ OUTMASK);
if( delayBus ) hd44780_functions->uPause (1);
// Read inputs // Read inputs
readval = ~ port_in (lptPort + 1) ^ INMASK; readval = ~ port_in (lptPort + 1) ^ INMASK;
+24 -15
View File
@@ -112,11 +112,16 @@ static int numDisplays = 0;
// input span list but is kept to save some cpu cycles. // input span list but is kept to save some cpu cycles.
static int *dispSizes = NULL; static int *dispSizes = NULL;
// Keypad and backlight option // Keypad, backlight extended interface and delay options
char have_keypad = 0; // off by default char have_keypad = 0; // off by default
char have_backlight = 0; // off by default char have_backlight = 0; // off by default
char extIF = 0; // off by default char extIF = 0; // off by default
// These vars is not static, so it's accessable from all sub-drivers int delayMult = 1; // Delay multiplier for slow displays
char delayBus = 0; // Delay if the computer can send data too fast over
// its bus to LPT port
// These vars is not static, so it's accessable from
// all sub-drivers
// Indeed, this should become cleaner... later... // Indeed, this should become cleaner... later...
// Autorepeat values // Autorepeat values
@@ -193,6 +198,11 @@ HD44780_init (lcd_logical_driver * driver, char *args)
//// READ THE CONFIG FILE //// READ THE CONFIG FILE
port = driver->config_get_int( DriverName, "port", 0, 0x278 ); port = driver->config_get_int( DriverName, "port", 0, 0x278 );
extIF = driver->config_get_bool( DriverName, "extended", 0, 0 );
have_keypad = driver->config_get_bool( DriverName, "keypad", 0, 0 );
have_backlight = driver->config_get_bool( DriverName, "backlight", 0, 0 );
delayMult = driver->config_get_int( DriverName, "delaymult", 0, 1 );
delayBus = driver->config_get_bool( DriverName, "delaybus", 0, 0 );
// Get and search for the connection type // Get and search for the connection type
s = driver->config_get_string( DriverName, "connectiontype", 0, "4bit" ); s = driver->config_get_string( DriverName, "connectiontype", 0, "4bit" );
@@ -213,10 +223,6 @@ HD44780_init (lcd_logical_driver * driver, char *args)
} }
} }
extIF = driver->config_get_bool( DriverName, "extended", 0, 0 );
have_keypad = driver->config_get_bool( DriverName, "keypad", 0, 0 );
have_backlight = driver->config_get_bool( DriverName, "backlight", 0, 0 );
// Get and parse size // Get and parse size
s = driver->config_get_string( DriverName, "size", 0, "20x4" ); s = driver->config_get_string( DriverName, "size", 0, "20x4" );
if( sscanf( s, "%dx%d", &(driver->wid), &(driver->hgt) ) != 2 ) { if( sscanf( s, "%dx%d", &(driver->wid), &(driver->hgt) ) != 2 ) {
@@ -336,8 +342,10 @@ common_init ()
// IO delay to avoid a task switch // IO delay to avoid a task switch
// //
void void
uPause (int delayCalls) uPause (int usecs)
{ {
int delay = usecs * delayMult; // To correct for slower displays
#if defined DELAY_GETTIMEOFDAY #if defined DELAY_GETTIMEOFDAY
struct timeval current_time,delay_time,wait_time; struct timeval current_time,delay_time,wait_time;
@@ -346,7 +354,7 @@ uPause (int delayCalls)
// Calculate when delay is over // Calculate when delay is over
delay_time.tv_sec = 0; delay_time.tv_sec = 0;
delay_time.tv_usec = delayCalls; delay_time.tv_usec = delay;
timeradd(&current_time,&delay_time,&wait_time); timeradd(&current_time,&delay_time,&wait_time);
do { do {
@@ -354,18 +362,19 @@ uPause (int delayCalls)
} while (timercmp(&current_time,&wait_time,<)); } while (timercmp(&current_time,&wait_time,<));
#elif defined DELAY_NANOSLEEP #elif defined DELAY_NANOSLEEP
struct timespec delay,remaining; struct timespec delay_time,remaining;
delay.tv_sec = 0; delay_time.tv_sec = 0;
delay.tv_nsec = delayCalls * 1000; delay_time.tv_nsec = delay * 1000;
while ( nanosleep(&delay,&remaining) == -1 ) while ( nanosleep(&delay_time,&remaining) == -1 )
{ {
delay.tv_sec = remaining.tv_sec; delay_time.tv_sec = remaining.tv_sec;
delay.tv_nsec = remaining.tv_nsec; delay_time.tv_nsec = remaining.tv_nsec;
} }
#else // using I/O timing #else // using I/O timing
// Assuming every call takes 1us (which can be quite incorrect)
int i; int i;
for (i = 0; i < delayCalls; ++i) for (i = 0; i < delay; ++i)
port_in (port); port_in (port);
#endif #endif
} }
+2
View File
@@ -24,6 +24,8 @@
extern char have_keypad; // non-zero if the keypad code is activated extern char have_keypad; // non-zero if the keypad code is activated
extern char have_backlight; // non-zero if we can control the backlight extern char have_backlight; // non-zero if we can control the backlight
extern char extIF; // non-zero if we should control > 2 LCDs extern char extIF; // non-zero if we should control > 2 LCDs
extern char delayBus; // non-zero if axtra delays for the bus speed
// should be inserted.
int HD44780_init (struct lcd_logical_driver *driver, char *args); int HD44780_init (struct lcd_logical_driver *driver, char *args);
/* The following methods can all be hidden. They are used through function ptrs /* The following methods can all be hidden. They are used through function ptrs