Support for nanosleep and gettimeofday delay methods added
This commit is contained in:
@@ -6,6 +6,11 @@
|
||||
* Copyright (c) 1999 Andrew McMeikan <andrewm@engineer.com>
|
||||
* modular driver 1999-2000 Benjamin Tse <blt@Comports.com>
|
||||
*
|
||||
* Modified July 2000 by Charles Steinkuehler for enhanced
|
||||
* performance and reduced CPU usage
|
||||
* - provided required setup time for RS valid to E high
|
||||
* - 1 uS call to uPause removed as it is unnecessary
|
||||
*
|
||||
* The connections are:
|
||||
* printer port LCD
|
||||
* D0 (2) D0 (7)
|
||||
@@ -93,8 +98,21 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign
|
||||
else
|
||||
dispID = EnMask[displayID - 1];
|
||||
|
||||
port_out (lptPort, ch);
|
||||
port_out (lptPort + 2, (dispID | portControl) ^ OUTMASK);
|
||||
hd44780_functions->uPause (1);
|
||||
// 40 nS setup time for RS valid to EN high, so set RS
|
||||
port_out (lptPort + 2, portControl ^ OUTMASK);
|
||||
|
||||
// then set EN high
|
||||
port_out (lptPort + 2, (dispID | portControl) ^ OUTMASK);
|
||||
|
||||
// Output the actual data
|
||||
port_out (lptPort, ch);
|
||||
|
||||
// 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!)
|
||||
// 230 nS minimum E high time provided by ISA bus delays as well...
|
||||
|
||||
// Set EN low and we're done...
|
||||
port_out (lptPort + 2, portControl ^ OUTMASK);
|
||||
|
||||
// 10 nS data hold time provided by the length of ISA write for EN
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
* Modular driver created and generic support for multiple displays added
|
||||
* Dec 1999, Benjamin Tse <blt@Comports.com>
|
||||
*
|
||||
* Modified July 2000 by Charles Steinkuehler to use one of 3 methods for delay
|
||||
* timing. I/O reads, gettimeofday, and nanosleep. Of the three, nanosleep
|
||||
* seems to work best, so that's what is set by default.
|
||||
*
|
||||
* This file is released under the GNU General Public License. Refer to the
|
||||
* COPYING file distributed with this package.
|
||||
*
|
||||
* Copyright (c) 2000, 1999, 1995 Benjamin Tse <blt@Comports.com>
|
||||
* 2000, Charles Steinkuehler <cstein@newtek.com>
|
||||
* 1999 Andrew McMeikan <andrewm@engineer.com>
|
||||
* 1998 Richard Rognlie <rrognlie@gamerz.net>
|
||||
* 1997 Matthias Prinke <m.prinke@trashcan.mcnet.de>
|
||||
@@ -33,6 +38,22 @@
|
||||
#include <errno.h>
|
||||
#include <sys/perm.h>
|
||||
|
||||
// Uncomment one of the lines below to select your desired delay generation
|
||||
// mechanism. If both defines are commented, the original I/O read timing
|
||||
// loop is used. Using DELAY_NANOSLEEP seems to provide the best performance.
|
||||
//#define DELAY_GETTIMEOFDAY
|
||||
#define DELAY_NANOSLEEP
|
||||
|
||||
#if defined DELAY_GETTIMEOFDAY
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
// Only one alternate delay method at a time, please ;-)
|
||||
#undef DELAY_NANOSLEEP
|
||||
#elif defined DELAY_NANOSLEEP
|
||||
#include <sched.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "../../shared/str.h"
|
||||
|
||||
#include "lcd.h"
|
||||
@@ -209,6 +230,18 @@ HD44780_init (lcd_logical_driver * driver, char *args)
|
||||
} else
|
||||
fprintf (stderr, "Error mallocing for display sizes list\n");
|
||||
}
|
||||
#if defined DELAY_NANOSLEEP
|
||||
// Change to Round-Robin scheduling for nanosleep
|
||||
{
|
||||
// Set priority to 1
|
||||
struct sched_param param;
|
||||
param.sched_priority=1;
|
||||
if (( sched_setscheduler(0, SCHED_RR, ¶m)) == -1) {
|
||||
fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Set up io port correctly, and open it...
|
||||
if ((ioperm (port, 1, 255)) == -1) {
|
||||
fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno));
|
||||
@@ -293,10 +326,37 @@ common_init (enum ifWidth ifwidth)
|
||||
void
|
||||
uPause (int delayCalls)
|
||||
{
|
||||
#if defined DELAY_GETTIMEOFDAY
|
||||
struct timeval current_time,delay_time,wait_time;
|
||||
|
||||
// Get current time first thing
|
||||
gettimeofday(¤t_time,NULL);
|
||||
|
||||
// Calculate when delay is over
|
||||
delay_time.tv_sec = 0;
|
||||
delay_time.tv_usec = delayCalls;
|
||||
timeradd(¤t_time,&delay_time,&wait_time);
|
||||
|
||||
do {
|
||||
gettimeofday(¤t_time,NULL);
|
||||
} while (timercmp(¤t_time,&wait_time,<));
|
||||
|
||||
#elif defined DELAY_NANOSLEEP
|
||||
struct timespec delay,remaining;
|
||||
|
||||
delay.tv_sec = 0;
|
||||
delay.tv_nsec = delayCalls * 1000;
|
||||
while ( nanosleep(&delay,&remaining) == -1 )
|
||||
{
|
||||
delay.tv_sec = remaining.tv_sec;
|
||||
delay.tv_nsec = remaining.tv_nsec;
|
||||
}
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < delayCalls; ++i)
|
||||
port_in (port);
|
||||
//TODO: put in option for nanosleep rather than dummy I/O call
|
||||
#endif
|
||||
}
|
||||
|
||||
// displayID - ID of display to use (0 = all displays)
|
||||
|
||||
Reference in New Issue
Block a user