diff --git a/server/drivers/hd44780.c b/server/drivers/hd44780.c index 5c4a86a..80116e9 100644 --- a/server/drivers/hd44780.c +++ b/server/drivers/hd44780.c @@ -27,6 +27,9 @@ * * Modified October 2001 to read the configfile. * + * Moved the delay timing code by Charles Steinkuehler to timing.h. + * Guillaume Filion , December 2001 + * * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. * @@ -49,31 +52,7 @@ # include "config.h" #endif #include "port.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 TIME_WITH_SYS_TIME -# include -# include -# else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -# endif - -// Only one alternate delay method at a time, please ;-) -#if defined DELAY_GETTIMEOFDAY -# undef DELAY_NANOSLEEP -#elif defined DELAY_NANOSLEEP -# include -# include -#endif +#include "timing.h" #include "shared/str.h" #include "render.h" @@ -116,7 +95,6 @@ static int *dispSizes = NULL; char have_keypad = 0; // off by default char have_backlight = 0; // off by default char extIF = 0; // off by default -int delayMult = 0; // Delay multiplier for slow displays char delayBus = 0; // Delay if the computer can send data too fast over // its bus to LPT port @@ -175,7 +153,7 @@ void HD44780_draw_frame (char *dat); char HD44780_getkey (); void HD44780_position (int x, int y); -static void uPause (int delayCalls); +//static void uPause (int delayCalls); unsigned char HD44780_scankeypad(); static int parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets[], int *dOffsize, int *dispSizeArray[], char *spanlist); @@ -253,19 +231,8 @@ HD44780_init (lcd_logical_driver * driver, char *args) 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 + if (timing_init() == -1) + return -1; // Make sure the frame buffer is there... if (!HD44780->framebuf) @@ -317,7 +284,7 @@ HD44780_init (lcd_logical_driver * driver, char *args) if ((hd44780_functions = (HD44780_functions *) malloc (sizeof (HD44780_functions))) == NULL) { return -1; } - hd44780_functions->uPause = uPause; + hd44780_functions->uPause = timing_uPause; hd44780_functions->scankeypad = HD44780_scankeypad; connectionMapping[connectiontype_index].init_fn (hd44780_functions, driver, args, port); @@ -350,47 +317,6 @@ common_init () hd44780_functions->uPause (1600); } -///////////////////////////////////////////////////////////////// -// IO delay to avoid a task switch -// -void -uPause (int usecs) -{ - int delay = usecs * delayMult; // To correct for slower displays - -#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 = delay; - 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_time,remaining; - - delay_time.tv_sec = 0; - delay_time.tv_nsec = delay * 1000; - while ( nanosleep(&delay_time,&remaining) == -1 ) - { - delay_time.tv_sec = remaining.tv_sec; - delay_time.tv_nsec = remaining.tv_nsec; - } -#else // using I/O timing - // Assuming every call takes 1us (which can be quite incorrect) - int i; - for (i = 0; i < delay; ++i) - port_in (port); -#endif -} - ///////////////////////////////////////////////////////////////// // Clean-up // diff --git a/server/drivers/sed1330.c b/server/drivers/sed1330.c index 3ebb22f..87d4a18 100644 --- a/server/drivers/sed1330.c +++ b/server/drivers/sed1330.c @@ -4,6 +4,9 @@ * This driver drives the LCD in text mode. * Probably the driver can easily be adapted to work for 1335 and 1336 too. * + * Moved the delay timing code by Charles Steinkuehler to timing.h. + * Guillaume Filion , December 2001 + * * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. * @@ -167,36 +170,13 @@ #include "shared/str.h" #include "shared/report.h" #include "configfile.h" +#include "timing.h" +#define uPause timing_uPause #include #include #include -// 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 TIME_WITH_SYS_TIME -# include -# include -# else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -# endif - -// Only one alternate delay method at a time, please ;-) -#if defined DELAY_GETTIMEOFDAY -# undef DELAY_NANOSLEEP -#elif defined DELAY_NANOSLEEP -# include -# include -#endif - // LPT lines #define A0 SEL #define nRESET STRB @@ -375,19 +355,8 @@ sed1330_init( lcd_logical_driver * driver, char *args ) port_access(data->port+1); port_access(data->port+2); - -#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, "SED1330: init failed (%s)", strerror (errno)); - return -1; - } - } -#endif + if (timing_init() == -1) + return -1; // Set the functions the driver supports... driver->init = sed1330_init; @@ -453,49 +422,6 @@ sed1330_init( lcd_logical_driver * driver, char *args ) return 0; } - -///////////////////////////////////////////////////////////////// -// Pause a specified number of milliseconds -// INTERNAL -// -void -uPause (int delay) -{ - -#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 = delay; - 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_time,remaining; - - delay_time.tv_sec = 0; - delay_time.tv_nsec = delay * 1000; - while ( nanosleep(&delay_time,&remaining) == -1 ) - { - delay_time.tv_sec = remaining.tv_sec; - delay_time.tv_nsec = remaining.tv_nsec; - } -#else // using I/O timing - // Assuming every call takes 1us (which can be quite incorrect) - int i; - for (i = 0; i < delay; ++i) - port_in (port); -#endif -} - - ///////////////////////////////////////////////////////////////// // Send a command and accompanying data // INTERNAL diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c index c5c5ed7..e64d7dc 100644 --- a/server/drivers/sed1520.c +++ b/server/drivers/sed1520.c @@ -11,6 +11,9 @@ // Michael Reinelt / lcd4linux and is (C) 2000 by him. // // The rest of fontmap.c and this driver is // // // +// Moved the delay timing code by Charles Steinkuehler to timing.h. // +// Guillaume Filion , December 2001 // +// // // (C) 2001 Robin Adams ( robin@adams-online.de ) // // // // This driver is released under the GPL. See file COPYING in this // @@ -24,9 +27,10 @@ #include #include #include -#include #include #include "port.h" +#include "timing.h" +#define uPause timing_uPause #include "sed1520fm.c" #ifdef HAVE_CONFIG_H @@ -50,8 +54,6 @@ unsigned int sed1520_lptport = LPTPORT; -static void uPause (int delayCalls); - lcd_logical_driver *sed1520; ///////////////////////////////////////////////////////////////// @@ -196,16 +198,8 @@ sed1520_init (struct lcd_logical_driver *driver, char *args) driver->wid = 20; driver->hgt = 4; - { - struct sched_param param; - param.sched_priority = 1; - if ((sched_setscheduler (0, SCHED_RR, ¶m)) == -1) - { - fprintf (stderr, "sed1520_init: failed (%s)\n", - strerror (errno)); - return -1; - } - } + if (timing_init() == -1) + return -1; // Initialize the Port and the sed1520s if(port_access(sed1520_lptport)) return -1; @@ -540,20 +534,3 @@ sed1520_draw_frame (char *dat) writedata (dat[j + (i * 122)], CS1); } } - -///////////////////////////////////////////////////////////////// -// This function delays a legth given by delayCalls -// x 10 Nanoseconds -// -void -uPause (int delayCalls) -{ - struct timespec delay, remaining; - delay.tv_sec = 0; - delay.tv_nsec = delayCalls * 10; - while (nanosleep (&delay, &remaining) == -1) - { - delay.tv_sec = remaining.tv_sec; - delay.tv_nsec = remaining.tv_nsec; - } -} diff --git a/server/drivers/stv5730.c b/server/drivers/stv5730.c index d8c0f6c..dea0b39 100644 --- a/server/drivers/stv5730.c +++ b/server/drivers/stv5730.c @@ -8,6 +8,9 @@ // tains a heartbeat icon and some characters that can be used as // // hbars / vbars. // // // +// Moved the delay timing code by Charles Steinkuehler to timing.h. // +// Guillaume Filion , December 2001 // +// // // (C) 2001 Robin Adams ( robin@adams-online.de ) // // // // This driver is released under the GPL. See file COPYING in this // @@ -22,9 +25,9 @@ #include #include #include -#include #include #include "port.h" +#include "timing.h" #ifdef HAVE_CONFIG_H # include "config.h" @@ -120,7 +123,8 @@ unsigned char stv5730_to_ascii[256] = lcd_logical_driver *stv5730; -static void stv5730_upause (int delayCalls); +//static void stv5730_upause (int delayCalls); +#define stv5730_upause timing_uPause ///////////////////////////////////////////////////////////////// // This function returns true if a powered and working STV5730 @@ -332,16 +336,8 @@ stv5730_init (struct lcd_logical_driver *driver, char *args) driver->wid = STV5730_WID; driver->hgt = STV5730_HGT; - { - struct sched_param param; - param.sched_priority = 1; - if ((sched_setscheduler (0, SCHED_RR, ¶m)) == -1) - { - fprintf (stderr, "stv5730_init: failed (%s)\n", - strerror (errno)); - return -1; - } - } + if (timing_init() == -1) + return -1; // Initialize the Port and the stv5730 if (port_access (stv5730_lptport) || port_access (stv5730_lptport + 1)) @@ -705,20 +701,3 @@ stv5730_draw_frame (char *dat) }; } } - -///////////////////////////////////////////////////////////////// -// This function delays a legth given by delayCalls -// x 10 Nanoseconds -// -void -stv5730_upause (int delayCalls) -{ - struct timespec delay, remaining; - delay.tv_sec = 0; - delay.tv_nsec = delayCalls * 10; - while (nanosleep (&delay, &remaining) == -1) - { - delay.tv_sec = remaining.tv_sec; - delay.tv_nsec = remaining.tv_nsec; - } -} diff --git a/server/drivers/timing.h b/server/drivers/timing.h new file mode 100644 index 0000000..381ee94 --- /dev/null +++ b/server/drivers/timing.h @@ -0,0 +1,110 @@ +#ifndef _TIMING_H +#define _TIMING_H + +/* + * Utility header file for timing functions + * + * Made by Guillaume Filion, moved from the HD44780 driver. + * + * From hd44780.c: + * 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) 2001 Guillaume Filion + * 2000 Charles Steinkuehler + */ + +// 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 +#ifdef HAVE_SCHED_H +# define DELAY_NANOSLEEP +#else +# define DELAY_GETTIMEOFDAY +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +// Only one alternate delay method at a time, please ;-) +#if defined DELAY_GETTIMEOFDAY +# undef DELAY_NANOSLEEP +#elif defined DELAY_NANOSLEEP +# include +# include +#endif + +static int delayMult = 0; // Delay multiplier for slow displays + +///////////////////////////////////////////////////////////////// +// Initialisation +// +static inline int timing_init() { +#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, "timing_init: failed (%s)\n", strerror (errno)); + return -1; + } + } +#endif + return 0; +} + +///////////////////////////////////////////////////////////////// +// IO delay to avoid a task switch +// +static inline void timing_uPause (int usecs) { + int delay = usecs * delayMult; // To correct for slower displays + +#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 = delay; + 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_time,remaining; + + delay_time.tv_sec = 0; + delay_time.tv_nsec = delay * 1000; + while ( nanosleep(&delay_time,&remaining) == -1 ) + { + 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 1ms, we'll do at least one. + int i=0; + do { port_in (port); } while (i++ < delay/1000); +#endif +} + + +#endif // _TIMING_H diff --git a/shared/report.c b/shared/report.c index 0747add..1696724 100644 --- a/shared/report.c +++ b/shared/report.c @@ -3,7 +3,7 @@ * */ -#include +#include #include "report.h" #include