Do not configure scheduler twice. Try to read from 0x3BD (3rd LPT port) if
DELAY_IOCALLS is configured. DELAY_IOCALLS is never selected automatically but has to be configured by the user anyway. Did not use writes to 0x80 as readings make me think this tries to delay by 1ms where we want 1us.
This commit is contained in:
@@ -94,15 +94,6 @@
|
||||
#include "hd44780-drivers.h"
|
||||
#include "hd44780-charmap.h"
|
||||
|
||||
/* Only one alternate delay method at a time, please ;-) */
|
||||
#if defined DELAY_GETTIMEOFDAY
|
||||
# undef DELAY_NANOSLEEP
|
||||
#elif defined DELAY_NANOSLEEP
|
||||
# include <sched.h>
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
|
||||
static char *defaultKeyMapDirect[KEYPAD_MAXX] = { "A", "B", "C", "D", "E" };
|
||||
|
||||
static char *defaultKeyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = {
|
||||
@@ -279,25 +270,12 @@ HD44780_init(Driver *drvthis)
|
||||
report(RPT_ERR, "%s: error mallocing", drvthis->name);
|
||||
}
|
||||
|
||||
/* Set up timing */
|
||||
if (timing_init() == -1) {
|
||||
report(RPT_ERR, "%s: timing_init() failed (%s)", drvthis->name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#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) {
|
||||
report(RPT_ERR, "%s: sched_setscheduler() failed (%s)",
|
||||
drvthis->name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate framebuffer */
|
||||
p->framebuf = (unsigned char *) calloc(p->width * p->height, sizeof(char));
|
||||
if (p->framebuf == NULL) {
|
||||
@@ -627,7 +605,7 @@ HD44780_position(Driver *drvthis, int x, int y)
|
||||
DDaddr = x + relY * p->line_address;
|
||||
} else {
|
||||
/*
|
||||
* 16x1 is a special case: char 0 starts at 0x00, but char 8
|
||||
* 16x1 is a special case: char 0 starts at 0x00, but char 8
|
||||
* starts at 0x40.
|
||||
*/
|
||||
if (p->dispSizes[dispID - 1] == 1 && p->width == 16) {
|
||||
@@ -1401,7 +1379,7 @@ unsigned char HD44780_scankeypad(PrivateData *p)
|
||||
if (p->hd44780_functions->readkeypad(p, Ypattern)) {
|
||||
/*
|
||||
* Yes, a key on the matrix is pressed
|
||||
*
|
||||
*
|
||||
* Step 3: Determine the row
|
||||
* Do a 'binary search' to minimize I/O
|
||||
* Requires 4 I/O reads
|
||||
|
||||
+52
-33
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/** \file server/drivers/timing.h
|
||||
* Utility header file for timing functions
|
||||
*
|
||||
* Made by Guillaume Filion, moved from the HD44780 driver.
|
||||
@@ -7,7 +7,9 @@
|
||||
* 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.
|
||||
*
|
||||
@@ -19,12 +21,14 @@
|
||||
#ifndef _TIMING_H
|
||||
#define _TIMING_H
|
||||
|
||||
// Uncomment one of the lines below this paragraph to select your desired
|
||||
// delay generation mechanism.
|
||||
// Mechanism DELAY_NANOSLEEP seems to provide the best performance.
|
||||
// Mechanism DELAY_IOCALLS can be quite inaccurate.
|
||||
// Mechanism DELAY_AUTOSELECT lets the system determine a mechanism, and is
|
||||
// the default.
|
||||
/*
|
||||
* Uncomment one of the lines below this paragraph to select your desired
|
||||
* delay generation mechanism.
|
||||
* Mechanism DELAY_NANOSLEEP seems to provide the best performance.
|
||||
* Mechanism DELAY_IOCALLS can be quite inaccurate.
|
||||
* Mechanism DELAY_AUTOSELECT lets the system determine a mechanism, and is
|
||||
* the default.
|
||||
*/
|
||||
|
||||
#define DELAY_AUTOSELECT
|
||||
//#define DELAY_GETTIMEOFDAY
|
||||
@@ -40,7 +44,7 @@
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
// Autoselect... Does this always work well ?
|
||||
/* Autoselect... Does this always work well ? */
|
||||
#ifdef DELAY_AUTOSELECT
|
||||
# if defined HAVE_SCHED_H && defined HAVE_SCHED_SETSCHEDULER
|
||||
# define DELAY_NANOSLEEP
|
||||
@@ -49,7 +53,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Include the correct time.h stuff (regardless of selected mechanism)
|
||||
/* Include the correct time.h stuff (regardless of selected mechanism) */
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
@@ -61,8 +65,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Only one alternate delay method at a time, please ;-)
|
||||
// And include extra header files here...
|
||||
/* Only one alternate delay method at a time, please ;-) */
|
||||
#if defined DELAY_GETTIMEOFDAY
|
||||
# undef DELAY_NANOSLEEP
|
||||
# undef DELAY_IOCALLS
|
||||
@@ -70,14 +73,19 @@
|
||||
# undef DELAY_GETTIMEOFDAY
|
||||
# undef DELAY_NANOSLEEP
|
||||
# include "port.h"
|
||||
#else // assume DELAY_NANOSLEEP
|
||||
#else /* assume DELAY_NANOSLEEP */
|
||||
# undef DELAY_GETTIMEOFDAY
|
||||
# undef DELAY_IOCALLS
|
||||
# include <sched.h>
|
||||
#endif
|
||||
|
||||
/* Convenience macros for operations on timevals.
|
||||
NOTE: `timercmp' does not work for >= or <=. */
|
||||
/*
|
||||
* Convenience macros for operations on timevals. These are usually defined
|
||||
* in sys/time.h. If your system does not have them, the defines from below
|
||||
* are used.
|
||||
*
|
||||
* NOTE: `timercmp' does not work for >= or <=.
|
||||
*/
|
||||
#ifndef timerisset
|
||||
# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
|
||||
#endif
|
||||
@@ -114,36 +122,48 @@
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Initialisation
|
||||
//
|
||||
static inline int timing_init() {
|
||||
|
||||
/**
|
||||
* Do necessary initialization for the selected waiting method.
|
||||
* \return 0 if successful, -1 on error.
|
||||
*/
|
||||
static inline int
|
||||
timing_init()
|
||||
{
|
||||
#if defined DELAY_NANOSLEEP
|
||||
// Change to Round-Robin scheduling for nanosleep
|
||||
/* Change to Round-Robin scheduling for nanosleep */
|
||||
{
|
||||
// Set priority to 1
|
||||
/* Set priority to 1 */
|
||||
struct sched_param param;
|
||||
param.sched_priority=1;
|
||||
if (( sched_setscheduler(0, SCHED_RR, ¶m)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#elif defined DELAY_IOCALLS
|
||||
if (port_access(0x3BD) == -1) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// IO delay to avoid a task switch
|
||||
//
|
||||
static inline void timing_uPause (int usecs) {
|
||||
|
||||
/**
|
||||
* Delay operation for some time using either gettimeofday (more or less an
|
||||
* active waiting loop), nanosleep, or an I/O call.
|
||||
* \param usecs Microsecond to pause
|
||||
*/
|
||||
static inline void
|
||||
timing_uPause(int usecs)
|
||||
{
|
||||
#if defined DELAY_GETTIMEOFDAY
|
||||
struct timeval current_time,delay_time,wait_time;
|
||||
|
||||
// Get current time first thing
|
||||
/* Get current time first thing */
|
||||
gettimeofday(¤t_time,NULL);
|
||||
|
||||
// Calculate when delay is over
|
||||
/* Calculate when delay is over */
|
||||
delay_time.tv_sec = 0;
|
||||
delay_time.tv_usec = usecs;
|
||||
timeradd(¤t_time,&delay_time,&wait_time);
|
||||
@@ -162,13 +182,12 @@ static inline void timing_uPause (int usecs) {
|
||||
delay_time.tv_sec = remaining.tv_sec;
|
||||
delay_time.tv_nsec = remaining.tv_nsec;
|
||||
}
|
||||
#else // using I/O timing
|
||||
// Assuming every port I/O takes 1us
|
||||
// FIXME: Does this work at all? Where does 'port' come from?
|
||||
for (int i=0; i < usecs; ++i)
|
||||
port_in(port);
|
||||
#else /* using I/O timing */
|
||||
int i;
|
||||
for (i = 0; i < usecs; ++i)
|
||||
port_in(0x3BD); /* Assuming every port I/O takes 1us */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // _TIMING_H
|
||||
#endif /* _TIMING_H */
|
||||
|
||||
Reference in New Issue
Block a user