diff --git a/acconfig.h b/acconfig.h index 2366c9c..241692d 100644 --- a/acconfig.h +++ b/acconfig.h @@ -45,6 +45,10 @@ #undef MTXORB_DRV +#undef SED1520_DRV + +#undef STV5730_DRV + /* Define the package name */ #undef PACKAGE diff --git a/acinclude.m4 b/acinclude.m4 index 9d1fcd5..e56264c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -9,7 +9,7 @@ AC_ARG_ENABLE(drivers, drivers=[mtxorb,cfontz,curses,text,lb216,bayrad,glk]) if test "$drivers" = "all"; then - drivers=[mtxorb,cfontz,curses,text,lb216,hd44780,joy,irman,lircin,bayrad,glk] + drivers=[mtxorb,cfontz,curses,text,lb216,hd44780,joy,irman,lircin,bayrad,glk,stv5730,sed1520] AC_MSG_RESULT(all) fi @@ -73,6 +73,14 @@ fi DRIVERS="$DRIVERS lircin.o" AC_DEFINE(LIRCIN_DRV) ;; + sed1520) + DRIVERS="$DRIVERS sed1520.o" + AC_DEFINE(SED1520_DRV) + ;; + stv5730) + DRIVERS="$DRIVERS stv5730.o" + AC_DEFINE(STV5730_DRV) + ;; *) AC_MSG_ERROR([Unknown driver $driver]) ;; diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 6755353..42f4704 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -8,6 +8,8 @@ EXTRA_libLCDdrivers_a_SOURCES = MtxOrb.c MtxOrb.h text.c text.h \ hd44780-serialLpt.c hd44780-serialLpt.h \ hd44780-winamp.c hd44780-winamp.h \ hd44780-low.h hd44780-drivers.h \ + sed1520.c sed1520.h sed1520fm.c \ + stv5730.c stv5730.h \ port.h joy.c joy.h irmanin.c irmanin.h \ bayrad.h bayrad.c \ CFontz.c CFontz.h lircin.c lircin.h debug.h \ diff --git a/server/drivers/lcd.c b/server/drivers/lcd.c index 10bbf45..65a7ae2 100644 --- a/server/drivers/lcd.c +++ b/server/drivers/lcd.c @@ -65,6 +65,14 @@ #include "bayrad.h" #endif +#ifdef SED1520_DRV +#include "sed1520.h" +#endif + +#ifdef STV5730_DRV +#include "stv5730.h" +#endif + #ifdef GLK_DRV #include "glk.h" #endif @@ -122,6 +130,12 @@ lcd_physical_driver drivers[] = { #endif #ifdef GLK_DRV {"glk", glk_init,}, +#endif +#ifdef SED1520_DRV + {"sed1520", sed1520_init,}, +#endif +#ifdef STV5730_DRV + {"stv5730", stv5730_init,}, #endif {NULL, NULL,}, diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c new file mode 100644 index 0000000..8c43937 --- /dev/null +++ b/server/drivers/sed1520.c @@ -0,0 +1,559 @@ +////////////////////////////////////////////////////////////////////////// +// This is a driver for 122x32 pixel graphic displays based on the // +// SED1520 Controller connected to the parallel port. Check // +// www.adams-online.de/lcd for where to buy // +// and how to build the hardware. This Controller has no built in // +// character generator. Therefore all fonts and pixels are generated // +// by this driver. // +// // +// This driver is based on drv_base.c and hd44780.c. // +// The HD44780 font in sed1520fm.c was shamelessly stolen from // +// Michael Reinelt / lcd4linux and is (C) 2000 by him. // +// The rest of fontmap.c and this driver is // +// // +// (C) 2001 Robin Adams ( robin@adams-online.de ) // +// // +// This driver is released under the GPL. See file COPYING in this // +// package for further details. // +////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "port.h" +#include "sed1520fm.c" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef LPTPORT +#define LPTPORT 0x378 +#endif + +#define A0 0x08 +#define CS2 0x04 +#define CS1 0x02 +#define WR 0x01 +#define IODELAY 500 + +#include "shared/str.h" +#include "lcd.h" +#include "sed1520.h" + + +unsigned int sed1520_lptport = LPTPORT; + +static void uPause (int delayCalls); + +lcd_logical_driver *sed1520; + +///////////////////////////////////////////////////////////////// +// writes command value to one or both sed1520 selected by chip +// +void +writecommand (int value, int chip) +{ + port_out ( sed1520_lptport,value); + port_out ( sed1520_lptport + 2,WR + CS1 - (chip & CS1) + (chip & CS2)); + port_out ( sed1520_lptport + 2,CS1 - (chip & CS1) + (chip & CS2)); + uPause (IODELAY); + port_out ( sed1520_lptport + 2,WR + CS1 - (chip & CS1) + (chip & CS2)); + uPause (IODELAY); +} + +///////////////////////////////////////////////////////////////// +// writes data value to one or both sed 1520 selected by chip +// +void +writedata (int value, int chip) +{ + port_out ( sed1520_lptport,value); + port_out ( sed1520_lptport + 2,A0 + WR + CS1 - (chip & CS1) + (chip & CS2)); + port_out ( sed1520_lptport + 2,A0 + CS1 - (chip & CS1) + (chip & CS2)); + uPause (IODELAY); + port_out ( sed1520_lptport + 2,A0 + WR + CS1 - (chip & CS1) + (chip & CS2)); + uPause (IODELAY); +} + +///////////////////////////////////////////////////////////////// +// selects a page (=row) on both sed1520s +// +void +selectpage (int page) +{ + writecommand (0xB8 + (page & 3), CS1 + CS2); +} + +///////////////////////////////////////////////////////////////// +// selects a column on the sed1520s specified by chip +// +void +selectcolumn (int column, int chip) +{ + writecommand ((column & 0x7F), chip); +} + +///////////////////////////////////////////////////////////////// +// draws char z from fontmap to the framebuffer at position +// x,y. These are zero-based textmode positions. +// The Fontmap is stored in rows while the framebuffer is stored +// in columns, so we need a little conversion. +// +void +drawchar2fb (int x, int y, unsigned char z) +{ + int i, j, k; + + if (x < 0 || x > 19 || y < 0 || y > 3) + return; + + for (i = 6; i > 0; i--) + { + k = 0; + for (j = 0; j < 7; j++) + { + k = k + + (((fontmap[(int) z][j] * 2) & (1 << i)) / (1 << i)) * + (1 << j); + } + lcd.framebuf[(y * 122) + (x * 6) + (6 - i)] = k; + } + +} + +///////////////////////////////////////////////////////////////// +// This initialises the stuff. We support supplying port as +// a command line argument. +// +int +sed1520_init (struct lcd_logical_driver *driver, char *args) +{ + char *argv[64], *str; + int argc, i; + + sed1520 = driver; + + if (args) + if ((str = (char *) malloc (strlen (args) + 1))) + strcpy (str, args); + else + { + fprintf (stderr, "Error mallocing\n"); + return -1; + } + else + str = NULL; + + argc = get_args (argv, args, 64); + for (i = 0; i < argc; i++) + { + if (0 == strcmp (argv[i], "-p") + || 0 == strcmp (argv[i], "--port\0")) + { + if (i + 1 >= argc) + { + fprintf (stderr, + "sed1520_init: %s requires an argument\n", + argv[i]); + return -1; + } + else + { + int myport; + if (sscanf (argv[i + 1], "%i", &myport) != 1) + { + fprintf (stderr, + "sed1520_init: Couldn't read port address -" + " using default value 0x%x\n", sed1520_lptport); + return -1; + } + else + { + sed1520_lptport = myport; + ++i; + } + } + } + else if (0 == strcmp (argv[i], "-h") + || 0 == strcmp (argv[i], "--help")) + { + int i; + printf + ("LCDproc sed1520 driver\n\t-p n\t--port n\tSelect the output device to use port n\n"); + printf ("put the options in quotes like this: '-p 0x278'\n"); + printf ("\t-h\t--help\t\tShow this help information\n"); + return -1; + } + } + + 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; + } + } + + // Initialize the Port and the sed1520s + if(port_access(sed1520_lptport)) return -1; + if(port_access(sed1520_lptport+2)) return -1; + + port_out (sed1520_lptport,0); + port_out (sed1520_lptport +2,WR + CS2); + writecommand (0xE2, CS1 + CS2); + writecommand (0xAF, CS1 + CS2); + writecommand (0xC0, CS1 + CS2); + selectpage (3); + // The Framebuffer LCDproc allocates by default is too small, + // so we free() it and allocate one of adequate size. + if (!driver->framebuf) + free (driver->framebuf); + + driver->framebuf = malloc (488); + if (!driver->framebuf) + { + sed1520_close (); + return -1; + } + + // clear screen + memset (driver->framebuf, 0, 122 * 4); + + driver->cellwid = 6; + driver->cellhgt = 8; // FIXME: lcd.cellwid always stays 5 + // regardless what it is set to here. This is + // a bug but not inside this driver. + driver->clear = sed1520_clear; + driver->string = sed1520_string; + driver->chr = sed1520_chr; + driver->vbar = sed1520_vbar; + driver->hbar = sed1520_hbar; + driver->num = sed1520_num; + driver->init = sed1520_init; + driver->close = sed1520_close; + driver->flush = sed1520_flush; + driver->flush_box = sed1520_flush_box; + driver->set_char = sed1520_set_char; + + driver->icon = sed1520_icon; + driver->draw_frame = sed1520_draw_frame; + // We dont't need init for vbar,hbar and friends. + driver->init_hbar = NULL; + driver->init_vbar = NULL; + driver->init_num = NULL; + // Neither contrast nor backlight are controllable. + driver->contrast = NULL; + driver->backlight = NULL; + // There are some unused input lines that may be used for input, + // but nothing is programmed so far. + driver->getkey = NULL; + return 200; // 200 is arbitrary. (must be 1 or more) +} + +///////////////////////////////////////////////////////////////// +// Frees the frambuffer and exits the driver. +// +void +sed1520_close () +{ + if (lcd.framebuf != NULL) + free (lcd.framebuf); + lcd.framebuf = NULL; +} + +///////////////////////////////////////////////////////////////// +// Clears the LCD screen +// +void +sed1520_clear () +{ + memset (lcd.framebuf, 0, 488); +} + +///////////////////////////////////////////////////////////////// +// +// Flushes all output to the lcd... +// +void +sed1520_flush () +{ + lcd.draw_frame (lcd.framebuf); +} + +///////////////////////////////////////////////////////////////// +// Prints a string on the lc display, at position (x,y). The +// upper-left is (1,1), and the lower right should be (20,4). +// +void +sed1520_string (int x, int y, char string[]) +{ + int i; + x--; // Convert 1-based coords to 0-based... + y--; + + for (i = 0; string[i]; i++) + { + drawchar2fb (x + i, y, string[i]); + } +} + +///////////////////////////////////////////////////////////////// +// Writes char c at position x,y into the framebuffer. +// x and y are 1-based textmode coordinates. +// +void +sed1520_chr (int x, int y, char c) +{ + y--; + x--; + drawchar2fb (x, y, c); +} + +///////////////////////////////////////////////////////////////// +// This function draws a number num into the last 3 rows of the +// framebuffer at 1-based position x. It should draw a 4-row font, +// but methinks this would look a little stretched. When +// num=10 a colon is drawn. +// FIXME: make big numbers use less memory +// +void +sed1520_num (int x, int num) +{ + int z, c, i, s; + x--; + + if (x < 0 || x > 19 || num < 0 || num > 10) + return; + if (num != 10 && (x < 0 || x > 17)) + return; + if (num == 10 && (x < 0 || x > 19)) + return; + + if (num == 10) + { // Doppelpunkt + for (z = 0; z < 3; z++) + { // Zeilen a 8 Punkte + for (c = 0; c < 6; c++) + { // 6 Spalten + s = 0; + for (i = 0; i < 8; i++) + { // 8 bits aus zeilen + s >>= 1; + if (*(fontbigdp[(z * 8) + i] + c) == '.') + s += 128; + } + lcd.framebuf[(z * 122) + 122 + (x * 6) + c] = s; + } + } + } + else + { + + for (z = 0; z < 3; z++) + { // Zeilen a 8 Punkte + for (c = 0; c < 18; c++) + { // 18 Spalten + s = 0; + for (i = 0; i < 8; i++) + { // 8 bits aus zeilen + s >>= 1; + if (*(fontbignum[num][z * 8 + i] + c) == '.') + s += 128; + } + lcd.framebuf[(z * 122) + 122 + (x * 6) + c] = s; + } + } + } +} + + +///////////////////////////////////////////////////////////////// +// Changes the font of character n to a pattern given by *dat. +// HD44780 Controllers only posses 8 programmable chars. But +// we store the fontmap completely in RAM, so every character +// can be altered. !Important: Characters have to be redraw +// by drawchar2fb() to show their new shape. Because we use +// a non-standard 6x8 font a *dat not calculated from +// lcd.width and lcd.height will fail. +// +void +sed1520_set_char (int n, char *dat) +{ + + int row, col, i; + if (n < 0 || n > 255) + return; + if (!dat) + return; + for (row = 0; row < 8; row++) + { + i = 0; + for (col = 0; col < 6; col++) + { + i <<= 1; + i |= (dat[(row * 6) + col] > 0); + } + fontmap[n][row] = i; + } +} + + +///////////////////////////////////////////////////////////////// +// Draws a vertical from the bottom up to the last 3 rows of the +// framebuffer at 1-based position x. len is given in pixels. +// +void +sed1520_vbar (int x, int len) +{ + int i, j, k; + x--; + + + for (j = 0; j < 3; j++) + { + i = 0; + k = 0; + for (i = 0; i < 8; i++) + { + if (len > i) + k += 1 << (7 - i); + } + + lcd.framebuf[((3 - j) * 122) + (x * 6)] = 0; + lcd.framebuf[((3 - j) * 122) + (x * 6) + 1] = 0; + lcd.framebuf[((3 - j) * 122) + (x * 6) + 2] = k; + lcd.framebuf[((3 - j) * 122) + (x * 6) + 3] = k; + lcd.framebuf[((3 - j) * 122) + (x * 6) + 4] = k; + lcd.framebuf[((3 - j) * 122) + (x * 6) + 5] = 0; + len -= 8; + } + +} + + +///////////////////////////////////////////////////////////////// +// Draws a horizontal bar from left to right at 1-based position +// x,y into the framebuffer. len is given in pixels. +// +void +sed1520_hbar (int x, int y, int len) +{ + int i; + x--; + y--; + + if (y < 0 || y > 3 || x < 0 || len < 0 || (x + (len / 6)) > 19) + return; + + for (i = 0; i < len; i++) + lcd.framebuf[(y * 122) + (x * 6) + i] = 0x3C; +} + +///////////////////////////////////////////////////////////////// +// Reprogrammes character dest to contain an icon given by +// which. Calls set_char() to do this. +// +void +sed1520_icon (int which, char dest) +{ + char icons[3][6 * 8] = { + { + 1, 1, 1, 1, 1, 1, // Empty Heart + 1, 0, 1, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 1, 1, + 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1,} + , + { + 1, 1, 1, 1, 1, 1, // Filled Heart + 1, 0, 1, 0, 1, 1, + 0, 1, 0, 1, 0, 1, + 0, 1, 1, 1, 0, 1, + 0, 1, 1, 1, 0, 1, + 1, 0, 1, 0, 1, 1, + 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1,} + , + { + 0, 0, 0, 0, 0, 0, // Ellipsis + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0,} + , + }; + sed1520_set_char (dest, &icons[which][0]); +} + +///////////////////////////////////////////////////////////////// +// Send a rectangular area from lft,top to rgt,bot to the display +// These coordinates are probably one-based, too. It's so fast to +// flush the whole display that it makes no sense to flush less then +// the whole display. Therefore this function redraws the whole +// display. +// FIXME: Check if this function is worth implementing. +// +void +sed1520_flush_box (int lft, int top, int rgt, int bot) +{ + sed1520_flush (); +} + +///////////////////////////////////////////////////////////////// +// Outputs the whole framebuffer *dat to the display. This Display +// contains 2 Controllers, each of them controlling one half of the +// screen. +// +void +sed1520_draw_frame (char *dat) +{ + int i, j; + if (!dat) + return; + for (i = 0; i < 4; i++) + { + selectpage (i); + selectcolumn (0, CS2) ; + for (j = 0; j < 61; j++) + writedata (dat[j + (i * 122)], CS2); + selectcolumn (0, CS1) ; + for (j = 61; j < 122; j++) + 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/sed1520.h b/server/drivers/sed1520.h new file mode 100644 index 0000000..10495a1 --- /dev/null +++ b/server/drivers/sed1520.h @@ -0,0 +1,20 @@ +#ifndef SED1520_H +#define SED1520_H + +extern lcd_logical_driver *sed1520; + +int sed1520_init (struct lcd_logical_driver *driver, char *args); +void sed1520_close (); +void sed1520_clear (); +void sed1520_flush (); +void sed1520_string (int x, int y, char string[]); +void sed1520_chr (int x, int y, char c); +void sed1520_vbar (int x, int len); +void sed1520_hbar (int x, int y, int len); +void sed1520_num (int x, int num); +void sed1520_set_char (int n, char *dat); +void sed1520_icon (int which, char dest); +void sed1520_flush_box (int lft, int top, int rgt, int bot); +void sed1520_draw_frame (char *dat); + +#endif diff --git a/server/drivers/sed1520fm.c b/server/drivers/sed1520fm.c new file mode 100644 index 0000000..16afdc5 --- /dev/null +++ b/server/drivers/sed1520fm.c @@ -0,0 +1,1117 @@ +////////////////////////////////////////////////////////////////////////// +// This file contains a HD44780 font and a font for big numbers. // +// The HD44780 font in this file was shamelessly stolen from // +// Michael Reinelt / lcd4linux and is // +// Copyright 1999, 2000 by Michael Reinelt (reinelt@eunet.at) // +// The rest of this file is // +// // +// (C) 2001 Robin Adams ( robin@adams-online.de ) // +// // +// This file is released under the GPL. See file COPYING in this // +// package for further details. // +////////////////////////////////////////////////////////////////////////// + +#define b______ 0x00 +#define b_____O 0x01 +#define b____O_ 0x02 +#define b____OO 0x03 +#define b___O__ 0x04 +#define b___O_O 0x05 +#define b___OO_ 0x06 +#define b___OOO 0x07 +#define b__O___ 0x08 +#define b__O__O 0x09 +#define b__O_O_ 0x0a +#define b__O_OO 0x0b +#define b__OO__ 0x0c +#define b__OO_O 0x0d +#define b__OOO_ 0x0e +#define b__OOOO 0x0f +#define b_O____ 0x10 +#define b_O___O 0x11 +#define b_O__O_ 0x12 +#define b_O__OO 0x13 +#define b_O_O__ 0x14 +#define b_O_O_O 0x15 +#define b_O_OO_ 0x16 +#define b_O_OOO 0x17 +#define b_OO___ 0x18 +#define b_OO__O 0x19 +#define b_OO_O_ 0x1a +#define b_OO_OO 0x1b +#define b_OOO__ 0x1c +#define b_OOO_O 0x1d +#define b_OOOO_ 0x1e +#define b_OOOOO 0x1f +#define b_OOOOO 0x1f +#define bOOOOOO 0x3f + +unsigned char fontmap[256][8] = { + [0x20] {b______, + b______, + b______, + b______, + b______, + b______, + b______, + b______}, + [0x21] {b___O__, + b___O__, + b___O__, + b___O__, + b______, + b______, + b___O__, + b______}, + [0x22] {b__O_O_, + b__O_O_, + b__O_O_, + b______, + b______, + b______, + b______, + b______}, + [0x23] {b__O_O_, + b__O_O_, + b_OOOOO, + b__O_O_, + b_OOOOO, + b__O_O_, + b__O_O_, + b______}, + [0x24] {b___O__, + b__OOOO, + b_O_O__, + b__OOO_, + b___O_O, + b_OOOO_, + b___O__, + b______}, + [0x25] {b_OO___, + b_OO__O, + b____O_, + b___O__, + b__O___, + b_O__OO, + b____OO, + b______}, + [0x26] {b__OO__, + b_O__O_, + b_O_O__, + b__O___, + b_O_O_O, + b_O__O_, + b__OO_O, + b______}, + [0x27] {b__OO__, + b___O__, + b__O___, + b______, + b______, + b______, + b______, + b______}, + [0x28] {b____O_, + b___O__, + b__O___, + b__O___, + b__O___, + b___O__, + b____O_, + b______}, + [0x29] {b__O___, + b___O__, + b____O_, + b____O_, + b____O_, + b___O__, + b__O___, + b______}, + [0x2a] {b______, + b___O__, + b_O_O_O, + b__OOO_, + b_O_O_O, + b___O__, + b______, + b______}, + [0x2b] {b______, + b___O__, + b___O__, + b_OOOOO, + b___O__, + b___O__, + b______, + b______}, + [0x2c] {b______, + b______, + b______, + b______, + b__OO__, + b___O__, + b__O___, + b______}, + [0x2d] {b______, + b______, + b______, + b_OOOOO, + b______, + b______, + b______, + b______}, + [0x2e] {b______, + b______, + b______, + b______, + b______, + b__OO__, + b__OO__, + b______}, + [0x2f] {b______, + b_____O, + b____O_, + b___O__, + b__O___, + b_O____, + b______, + b______}, + [0x30] {b__OOO_, + b_O___O, + b_O__OO, + b_O_O_O, + b_OO__O, + b_O___O, + b__OOO_, + b______}, + [0x31] {b___O__, + b__OO__, + b___O__, + b___O__, + b___O__, + b___O__, + b__OOO_, + b______}, + [0x32] {b__OOO_, + b_O___O, + b_____O, + b____O_, + b___O__, + b__O___, + b_OOOOO, + b______}, + [0x33] {b_OOOOO, + b____O_, + b___O__, + b____O_, + b_____O, + b_O___O, + b__OOO_, + b______}, + [0x34] {b____O_, + b___OO_, + b__O_O_, + b_O__O_, + b_OOOOO, + b____O_, + b____O_, + b______}, + [0x35] {b_OOOOO, + b_O____, + b_O____, + b_OOOO_, + b_____O, + b_O___O, + b__OOO_, + b______}, + [0x36] {b___OO_, + b__O___, + b_O____, + b_OOOO_, + b_O___O, + b_O___O, + b__OOO_, + b______}, + [0x37] {b_OOOOO, + b_____O, + b____O_, + b___O__, + b__O___, + b__O___, + b__O___, + b______}, + [0x38] {b__OOO_, + b_O___O, + b_O___O, + b__OOO_, + b_O___O, + b_O___O, + b__OOO_, + b______}, + [0x39] {b__OOO_, + b_O___O, + b_O___O, + b__OOOO, + b_____O, + b____O_, + b__OO__, + b______}, + [0x3a] {b______, + b__OO__, + b__OO__, + b______, + b__OO__, + b__OO__, + b______, + b______}, + [0x3b] {b______, + b__OO__, + b__OO__, + b______, + b__OO__, + b___O__, + b__O___, + b______}, + [0x3c] {b____O_, + b___O__, + b__O___, + b_O____, + b__O___, + b___O__, + b____O_, + b______}, + [0x3d] {b______, + b______, + b_OOOOO, + b______, + b_OOOOO, + b______, + b______, + b______}, + [0x3e] {b_O____, + b__O___, + b___O__, + b____O_, + b___O__, + b__O___, + b_O____, + b______}, + [0x3f] {b__OOO_, + b_O___O, + b_____O, + b____O_, + b___O__, + b______, + b___O__, + b______}, + [0x40] {b__OOO_, + b_O___O, + b_____O, + b__OO_O, + b_O_O_O, + b_O_O_O, + b__OOO_, + b______}, + [0x41] {b__OOO_, + b_O___O, + b_O___O, + b_O___O, + b_OOOOO, + b_O___O, + b_O___O, + b______}, + [0x42] {b_OOOO_, + b_O___O, + b_O___O, + b_OOOO_, + b_O___O, + b_O___O, + b_OOOO_, + b______}, + [0x43] {b__OOO_, + b_O___O, + b_O____, + b_O____, + b_O____, + b_O___O, + b__OOO_, + b______}, + [0x44] {b_OOO__, + b_O__O_, + b_O___O, + b_O___O, + b_O___O, + b_O__O_, + b_OOO__, + b______}, + [0x45] {b_OOOOO, + b_O____, + b_O____, + b_OOOO_, + b_O____, + b_O____, + b_OOOOO, + b______}, + [0x46] {b_OOOOO, + b_O____, + b_O____, + b_OOOO_, + b_O____, + b_O____, + b_O____, + b______}, + [0x47] {b__OOO_, + b_O___O, + b_O____, + b_O_OOO, + b_O___O, + b_O___O, + b__OOOO, + b______}, + [0x48] {b_O___O, + b_O___O, + b_O___O, + b_OOOOO, + b_O___O, + b_O___O, + b_O___O, + b______}, + [0x49] {b__OOO_, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b__OOO_, + b______}, + [0x4a] {b___OOO, + b____O_, + b____O_, + b____O_, + b____O_, + b_O__O_, + b__OO__, + b______}, + [0x4b] {b_O___O, + b_O__O_, + b_O_O__, + b_OO___, + b_O_O__, + b_O__O_, + b_O___O, + b______}, + [0x4c] {b_O____, + b_O____, + b_O____, + b_O____, + b_O____, + b_O____, + b_OOOOO, + b______}, + [0x4d] {b_O___O, + b_OO_OO, + b_O_O_O, + b_O_O_O, + b_O___O, + b_O___O, + b_O___O, + b______}, + [0x4e] {b_O___O, + b_O___O, + b_OO__O, + b_O_O_O, + b_O__OO, + b_O___O, + b_O___O, + b______}, + [0x4f] {b__OOO_, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b__OOO_, + b______}, + [0x50] {b_OOOO_, + b_O___O, + b_O___O, + b_OOOO_, + b_O____, + b_O____, + b_O____, + b______}, + [0x51] {b__OOO_, + b_O___O, + b_O___O, + b_O___O, + b_O_O_O, + b_O__O_, + b__OO_O, + b______}, + [0x52] {b_OOOO_, + b_O___O, + b_O___O, + b_OOOO_, + b_O_O__, + b_O__O_, + b_O___O, + b______}, + [0x53] {b__OOOO, + b_O____, + b_O____, + b__OOO_, + b_____O, + b_____O, + b_OOOO_, + b______}, + [0x54] {b_OOOOO, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b______}, + [0x55] {b_O___O, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b__OOO_, + b______}, + [0x56] {b_O___O, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b__O_O_, + b___O__, + b______}, + [0x57] {b_O___O, + b_O___O, + b_O___O, + b_O_O_O, + b_O_O_O, + b_O_O_O, + b__O_O_, + b______}, + [0x58] {b_O___O, + b_O___O, + b__O_O_, + b___O__, + b__O_O_, + b_O___O, + b_O___O, + b______}, + [0x59] {b_O___O, + b_O___O, + b_O___O, + b__O_O_, + b___O__, + b___O__, + b___O__, + b______}, + [0x5a] {b_OOOOO, + b_____O, + b____O_, + b___O__, + b__O___, + b_O____, + b_OOOOO, + b______}, + [0x5b] {b__OOO_, + b__O___, + b__O___, + b__O___, + b__O___, + b__O___, + b__OOO_, + b______}, + [0x5c] {b_O___O, + b__O_O_, + b_OOOOO, + b___O__, + b_OOOOO, + b___O__, + b___O__, + b______}, + [0x5d] {b__OOO_, + b____O_, + b____O_, + b____O_, + b____O_, + b____O_, + b__OOO_, + b______}, + [0x5e] {b___O__, + b__O_O_, + b_O___O, + b______, + b______, + b______, + b______, + b______}, + [0x5f] {b______, + b______, + b______, + b______, + b______, + b______, + b_OOOOO, + b______}, + [0x60] {b__O___, + b___O__, + b____O_, + b______, + b______, + b______, + b______, + b______}, + [0x61] {b______, + b______, + b__OOO_, + b_____O, + b__OOOO, + b_O___O, + b__OOOO, + b______}, + [0x62] {b_O____, + b_O____, + b_O____, + b_O_OO_, + b_OO__O, + b_O___O, + b_OOOO_, + b______}, + [0x63] {b______, + b______, + b__OOO_, + b_O____, + b_O____, + b_O___O, + b__OOO_, + b______}, + [0x64] {b_____O, + b_____O, + b_____O, + b__OO_O, + b_O__OO, + b_O___O, + b__OOOO, + b______}, + [0x65] {b______, + b______, + b__OOO_, + b_O___O, + b_OOOOO, + b_O____, + b__OOO_, + b______}, + [0x66] {b___OO_, + b__O__O, + b__O___, + b_OOO__, + b__O___, + b__O___, + b__O___, + b______}, + [0x67] {b______, + b__OOOO, + b_O___O, + b_O___O, + b__OOOO, + b_____O, + b__OOO_, + b______}, + [0x68] {b_O____, + b_O____, + b_O_OO_, + b_OO__O, + b_O___O, + b_O___O, + b_O___O, + b______}, + [0x69] {b___O__, + b______, + b__OO__, + b___O__, + b___O__, + b___O__, + b__OOO_, + b______}, + [0x6a] {b____O_, + b______, + b___OO_, + b____O_, + b____O_, + b_O__O_, + b__OO__, + b______}, + [0x6b] {b__O___, + b__O___, + b__O__O, + b__O_O_, + b__OO__, + b__O_O_, + b__O__O, + b______}, + [0x6c] {b__OO__, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b__OOO_, + b______}, + [0x6d] {b______, + b______, + b_OO_O_, + b_O_O_O, + b_O_O_O, + b_O___O, + b_O___O, + b______}, + [0x6e] {b______, + b______, + b_OOOO_, + b_O___O, + b_O___O, + b_O___O, + b_O___O, + b______}, + [0x6f] {b______, + b______, + b__OOO_, + b_O___O, + b_O___O, + b_O___O, + b__OOO_, + b______}, + [0x70] {b______, + b______, + b_OOOO_, + b_O___O, + b_OOOO_, + b_O____, + b_O____, + b______}, + [0x71] {b______, + b______, + b__OO_O, + b_O__OO, + b__OOOO, + b_____O, + b_____O, + b______}, + [0x72] {b______, + b______, + b_O_OO_, + b_OO__O, + b_O____, + b_O____, + b_O____, + b______}, + [0x73] {b______, + b______, + b__OOO_, + b_O____, + b__OOO_, + b_____O, + b_OOOO_, + b______}, + [0x74] {b__O___, + b_OOO__, + b__O___, + b__O___, + b__O___, + b__O__O, + b___OO_, + b______}, + [0x75] {b______, + b______, + b_O___O, + b_O___O, + b_O___O, + b_O__OO, + b__OO_O, + b______}, + [0x76] {b______, + b______, + b_O___O, + b_O___O, + b_O___O, + b__O_O_, + b___O__, + b______}, + [0x77] {b______, + b______, + b_O___O, + b_O___O, + b_O___O, + b_O_O_O, + b__O_O_, + b______}, + [0x78] {b______, + b______, + b_O___O, + b__O_O_, + b___O__, + b__O_O_, + b_O___O, + b______}, + [0x79] {b______, + b______, + b_O___O, + b_O___O, + b__OOOO, + b_____O, + b__OOO_, + b______}, + [0x7a] {b______, + b______, + b_OOOOO, + b____O_, + b___O__, + b__O___, + b_OOOOO, + b______}, + [0x7b] {b____O_, + b___O__, + b___O__, + b__O___, + b___O__, + b___O__, + b____O_, + b______}, + [0x7c] {b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b___O__, + b______}, + [0x7d] {b__O___, + b___O__, + b___O__, + b____O_, + b___O__, + b___O__, + b__O___, + b______}, + [0x7e] {b______, + b___O__, + b____O_, + b_OOOOO, + b____O_, + b___O__, + b______, + b______}, + + [0x7f] {b______, + b___O__, + b__O___, + b_OOOOO, + b__O___, + b___O__, + b______, + b______}, + [0xb0] {b__OOO_, + b__O_O_, + b__OOO_, + b______, + b______, + b______, + b______, + b______}, + [0xff] {bOOOOOO, + bOOOOOO, + bOOOOOO, + bOOOOOO, + bOOOOOO, + bOOOOOO, + bOOOOOO, + bOOOOOO}, +}; + +//FIXME: make big chars use less memory + +static unsigned char *fontbignum[10][24] = { + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++....++++++", + "++++++........++++", + "+++++..........+++", + "+++++....++....+++", + "+++++...++++...+++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++...++++...+++", + "+++++....++....+++", + "+++++..........+++", + "++++++........++++", + "++++++++....++++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "+++++++++++++...++", + "++++++++++++....++", + "+++++++++++.....++", + "++++++++++......++", + "++++++++........++", + "+++++++.........++", + "+++++++....+....++", + "+++++++...++....++", + "+++++++.++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++.....+++++", + "++++++.........+++", + "+++++..........+++", + "+++++....+++....++", + "+++++...++++....++", + "++++++..++++....++", + "++++++++++++....++", + "++++++++++++....++", + "+++++++++++....+++", + "++++++++++....++++", + "+++++++++.....++++", + "++++++++.....+++++", + "+++++++....+++++++", + "++++++....++++++++", + "++++++....++++++++", + "+++++...........++", + "+++++...........++", + "+++++...........++", + "+++++...........++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "+++++++.....++++++", + "+++++.........++++", + "+++++.........++++", + "++++....+++....+++", + "++++....+++....+++", + "+++++++++++....+++", + "++++++++++....++++", + "+++++++++.....++++", + "+++++++++...++++++", + "+++++++++.....++++", + "+++++++++++....+++", + "++++++++++++....++", + "++++++++++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++....++....+++", + "+++++..........+++", + "++++++........++++", + "+++++++.....++++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++....++++", + "++++++++++....++++", + "+++++++++.....++++", + "++++++++......++++", + "++++++++......++++", + "+++++++.......++++", + "++++++........++++", + "++++++...+....++++", + "+++++...++....++++", + "+++++...++....++++", + "++++...+++....++++", + "+++...++++....++++", + "+++.............++", + "+++.............++", + "+++.............++", + "++++++++++....++++", + "++++++++++....++++", + "++++++++++....++++", + "++++++++++....++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++++.........+++", + "++++++.........+++", + "+++++..........+++", + "+++++....+++++++++", + "+++++....+++++++++", + "+++++...++++++++++", + "+++++...+....+++++", + "++++..........++++", + "++++...........+++", + "++++....+++.....++", + "++++++++++++....++", + "++++++++++++....++", + "++++++++++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++....++....+++", + "+++++..........+++", + "++++++........++++", + "+++++++.....++++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++.....+++++", + "+++++++........+++", + "++++++.........+++", + "+++++....++.....++", + "+++++...++++....++", + "++++....++++++++++", + "++++....++++++++++", + "++++....+....+++++", + "++++..........++++", + "++++...........+++", + "++++.....++.....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++...++++....++", + "+++++....++.....++", + "++++++.........+++", + "++++++........++++", + "++++++++.....+++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "++++............++", + "++++............++", + "++++............++", + "++++++++++++....++", + "+++++++++++....+++", + "++++++++++....++++", + "++++++++++....++++", + "+++++++++....+++++", + "+++++++++...++++++", + "++++++++....++++++", + "++++++++....++++++", + "+++++++....+++++++", + "+++++++....+++++++", + "+++++++....+++++++", + "+++++++...++++++++", + "++++++....++++++++", + "++++++....++++++++", + "++++++....++++++++", + "++++++....++++++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "+++++++......+++++", + "+++++..........+++", + "+++++....++....+++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++....++....+++", + "++++++........++++", + "++++++........++++", + "+++++....++....+++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "+++++....++....+++", + "+++++..........+++", + "+++++++......+++++", + "++++++++++++++++++", + "++++++++++++++++++"}, + { + "++++++++++++++++++", + "++++++++++++++++++", + "++++++++++++++++++", + "+++++++.....++++++", + "++++++........++++", + "+++++.........++++", + "++++.....++....+++", + "++++....++++...+++", + "++++....++++....++", + "++++....++++....++", + "++++....++++....++", + "++++.....++.....++", + "+++++...........++", + "++++++..........++", + "+++++++....+....++", + "++++++++++++....++", + "++++++++++++....++", + "++++....++++...+++", + "++++.....++....+++", + "+++++.........++++", + "+++++........+++++", + "+++++++.....++++++", + "++++++++++++++++++", + "++++++++++++++++++"} +}; + +static unsigned char *fontbigdp[] = { + "++++++", + "++++++", + "++++++", + "++++++", + "++++++", + "+....+", + "+....+", + "+....+", + "+....+", + "++++++", + "++++++", + "++++++", + "++++++", + "++++++", + "++++++", + "+....+", + "+....+", + "+....+", + "+....+", + "++++++", + "++++++", + "++++++", + "++++++", + "++++++" +}; diff --git a/server/drivers/stv5730.c b/server/drivers/stv5730.c new file mode 100644 index 0000000..ca3a4e0 --- /dev/null +++ b/server/drivers/stv5730.c @@ -0,0 +1,725 @@ +////////////////////////////////////////////////////////////////////////// +// This is a driver for the STV5730A on-screen display chip in con- // +// junction with a parallel port interface. Check // +// www.adams-online.de/lcd/stv5730.html for where to buy // +// and how to build the hardware. // +// The STV3730 displays 11 rows with 28 characters. The characters are // +// fixed and can not be reprogrammed. Luckily the chraracter set con- // +// tains a heartbeat icon and some characters that can be used as // +// hbars / vbars. // +// // +// (C) 2001 Robin Adams ( robin@adams-online.de ) // +// // +// This driver is released under the GPL. See file COPYING in this // +// package for further details. // +////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "port.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "shared/str.h" +#include "lcd.h" +#include "stv5730.h" + + +#ifndef LPTPORT +#define LPTPORT 0x378 +#endif + +#define STV5730_TEST_O 0x01 +#define STV5730_BAR 0x02 +#define STV5730_CLK 0x04 +#define STV5730_CSN 0x08 +#define STV5730_DATA 0x10 + +#define STV5730_TEST_I 0x40 +#define STV5730_MUTE 0x80 + +// If it doesn't work try increasing this value +#define IODELAY 400 + + +// Change that to NTSC if you are from the US... +#define PAL + + +#define STV5730_HGT 11 +#define STV5730_WID 28 +#define STV5730_ATTRIB 0x800 + +#define STV5730_REG_ZOOM 0xCC +#define STV5730_REG_COLOR 0xCD +#define STV5730_REG_CONTROL 0xCE +#define STV5730_REG_POSITION 0xCF +#define STV5730_REG_MODE 0xD0 + +// Choose Colors: FLINE: First line text color, TEXT: Text color, CBACK: Character Background Color +// CBORD: Character Border Color, SBACK: Screen Background color +// 0:Black, 1: Blue, 2:Green, 3: Cyan, 4: Red, 5: Magenta, 6: Yellow, 7: White +#define STV5730_COL_FLINE 4 +#define STV5730_COL_TEXT 1 +#define STV5730_COL_CBACK 3 +#define STV5730_COL_CBORD 0 +#define STV5730_COL_SBACK 2 + + + +unsigned int stv5730_lptport = LPTPORT; +unsigned int stv5730_charattrib = STV5730_ATTRIB; +unsigned int stv5730_flags = 0; + +// Translation map ascii->stv5730 charset +unsigned char stv5730_to_ascii[256] = + { 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x27, 0x0B, 0x27, 0x28, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x26, 0x26, + 0x62, 0x78, 0x61, 0x70, + 0x6c, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, + 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x0B, + 0x0B, 0x0B, 0x0B, 0x72, + 0x0B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x6E, + 0x6C, 0x71, 0x79, 0x7F, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x77 +}; + + +lcd_logical_driver *stv5730; + +static void stv5730_upause (int delayCalls); + +///////////////////////////////////////////////////////////////// +// This function returns true if a powered and working STV5730 +// hardware is present at stv5730_lptport + +int +stv5730_detect (void) +{ + int i; + + for (i = 0; i < 10; i++) + { + port_out (stv5730_lptport, STV5730_TEST_O); + stv5730_upause (IODELAY); + if ((port_in (stv5730_lptport + 1) & STV5730_TEST_I) == 0) + return -1; + port_out (stv5730_lptport, 0); + stv5730_upause (IODELAY); + if ((port_in (stv5730_lptport + 1) & STV5730_TEST_I) != 0) + return -1; + } + return 0; +} + +///////////////////////////////////////////////////////////////// +// returns 0 if a valid video signal is connected to the video +// input +int +stv5730_is_mute (void) +{ + stv5730_upause (IODELAY); + return ((port_in (stv5730_lptport + 1) & STV5730_MUTE) ? 0 : 1); +} + +///////////////////////////////////////////////////////////////// +// stv5730_write16bit, stv5730_write8bit, stv5730_write0bit +// this family of functions write commands or data to the stv5730 +// 8 bit writes repeat the high byte, 0 byte writes repeat the last +// written word + +void +stv5730_write16bit (unsigned int value) +{ + char i, databit; + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CLK + stv5730_flags); + + for (i = 15; i >= 0; i--) + { + (value & (1 << i)) != 0 ? (databit = STV5730_DATA) : (databit = 0); + port_out (stv5730_lptport, databit + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, databit + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, databit + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + } + + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); + stv5730_upause (IODELAY); +} + +void +stv5730_write8bit (unsigned int value) +{ + char i, databit; + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CLK + stv5730_flags); + + for (i = 7; i >= 0; i--) + { + (value & (1 << i)) != 0 ? (databit = STV5730_DATA) : (databit = 0); + port_out (stv5730_lptport, databit + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, databit + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, databit + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + } + + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); +} + +void +stv5730_write0bit (void) +{ + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CLK + stv5730_flags); + + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + STV5730_CLK + stv5730_flags); + stv5730_upause (IODELAY); + port_out (stv5730_lptport, STV5730_CSN + stv5730_flags); +} + + +///////////////////////////////////////////////////////////////// +// sets the memory pointer inside the stv5730 to the position +// row, col. +void +stv5730_locate (int row, int col) +{ + if (row < 0 || row >= STV5730_HGT || col < 0 || col >= STV5730_WID) + return; + + stv5730_write16bit ((row << 8) + col); +} + +///////////////////////////////////////////////////////////////// +// draws char z from fontmap to the framebuffer at position +// x,y. These are zero-based textmode positions. +// We need a conversion map to translate from ascii to the +// non-standard STV5730 charset. +// +void +stv5730_drawchar2fb (int x, int y, unsigned char z) +{ + + if (x < 0 || x >= STV5730_WID || y < 0 || y >= STV5730_HGT) + return; + lcd.framebuf[(y * STV5730_WID) + x] = stv5730_to_ascii[(unsigned int) z]; + +} + +///////////////////////////////////////////////////////////////// +// This initialises the stuff. We support supplying port as +// a command line argument. +// +int +stv5730_init (struct lcd_logical_driver *driver, char *args) +{ + char *argv[64], *str; + int argc, i; + + stv5730 = driver; + + if (args) + if ((str = (char *) malloc (strlen (args) + 1))) + strcpy (str, args); + else + { + fprintf (stderr, "Error mallocing\n"); + return -1; + } + else + str = NULL; + + argc = get_args (argv, args, 64); + for (i = 0; i < argc; i++) + { + if (0 == strcmp (argv[i], "-p") + || 0 == strcmp (argv[i], "--port\0")) + { + if (i + 1 >= argc) + { + fprintf (stderr, + "stv5730_init: %s requires an argument\n", + argv[i]); + return -1; + } + else + { + int myport; + if (sscanf (argv[i + 1], "%i", &myport) != 1) + { + fprintf (stderr, + "stv5730_init: Couldn't read port address -" + " using default value 0x%x\n", + stv5730_lptport); + return -1; + } + else + { + stv5730_lptport = myport; + ++i; + } + } + } + else if (0 == strcmp (argv[i], "-h") + || 0 == strcmp (argv[i], "--help")) + { + int i; + printf + ("LCDproc stv5730 driver\n\t-p n\t--port n\tSelect the output device to use port n\n"); + printf ("put the options in quotes like this: '-p 0x278'\n"); + printf ("\t-h\t--help\t\tShow this help information\n"); + return -1; + } + } + + 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; + } + } + + // Initialize the Port and the stv5730 + if (port_access (stv5730_lptport) || port_access (stv5730_lptport + 1)) + { + printf + ("Couldn't get IO-permission for 0x%X ! Are we running as root ?\n ", + stv5730_lptport); return -1; + }; + + if (stv5730_detect ()) + { + printf ("No STV5730 hardware found at 0x%X !\n ", stv5730_lptport); + return -1; + }; + + port_out (stv5730_lptport, 0); + + // Reset the STV5730 + stv5730_write16bit (0x3000); + stv5730_write16bit (0x3000); + stv5730_write16bit (0x00db); + stv5730_write16bit (0x1000); + + // Setup Mode + Control Register for video detection + stv5730_write16bit (STV5730_REG_MODE); + stv5730_write16bit (0x1576); + + stv5730_write16bit (STV5730_REG_CONTROL); + stv5730_write16bit (0x1FF4); + + printf ("Detecting Video Signal: "); + usleep (50000); + + if (stv5730_is_mute ()) + { + printf ("No Video Signal found, using full page mode.\n"); + // Setup Mode + Control for full page mode + stv5730_charattrib = STV5730_ATTRIB; + stv5730_write16bit (STV5730_REG_MODE); + stv5730_write16bit (0x15A6); + + stv5730_write16bit (STV5730_REG_CONTROL); +#ifdef PAL + stv5730_write16bit (0x1FD5); +#endif +#ifdef NTSC + stv5730_write16bit (0x1ED4); +#endif + + + } + else + { + printf ("Video Signal found, using mixed mode (B&W).\n"); + // Setup Mode + Control for mixed mode, disable color + stv5730_charattrib = 0; + stv5730_write16bit (STV5730_REG_MODE); + stv5730_write16bit (0x1576); + + stv5730_write16bit (STV5730_REG_CONTROL); +#ifdef PAL + stv5730_write16bit (0x1DD4); +#endif +#ifdef NTSC + stv5730_write16bit (0x1CF4); +#endif + } + + // Position Register + stv5730_write16bit (STV5730_REG_POSITION); + stv5730_write16bit (0x1000 + 64 * 30 + 30); + + // Color Register + stv5730_write16bit (STV5730_REG_COLOR); + stv5730_write16bit (0x1000 + (STV5730_COL_SBACK << 9) + + (STV5730_COL_CBORD << 6) + STV5730_COL_CBACK); + + // Zoom Register: Zoom first line + stv5730_write16bit (STV5730_REG_ZOOM); + stv5730_write16bit (0x1000 + 4); + + // Set the Row Attributes + for (i = 0; i <= 10; i++) + { + stv5730_write16bit (0x00C0 + i); + stv5730_write16bit (0x10C0); + } + + + // The Framebuffer LCDproc allocates by default is too small, + // so we free() it and allocate one of adequate size. + if (!driver->framebuf) + free (driver->framebuf); + + driver->framebuf = malloc (STV5730_WID * STV5730_HGT); + if (!driver->framebuf) + { + stv5730_close (); + return -1; + } + + // clear screen + memset (driver->framebuf, 0, STV5730_WID * STV5730_HGT); + + driver->cellwid = 4; + driver->cellhgt = 6; // FIXME: lcd.cellwid always stays 5 + // regardless what it is set to here. This is + // a bug but not inside this driver. + driver->clear = stv5730_clear; + driver->string = stv5730_string; + driver->chr = stv5730_chr; + driver->vbar = stv5730_vbar; + driver->hbar = stv5730_hbar; + driver->num = stv5730_num; + driver->init = stv5730_init; + driver->close = stv5730_close; + driver->flush = stv5730_flush; + driver->flush_box = stv5730_flush_box; + // We dont't have any programmable chars. + driver->set_char = NULL; + + driver->icon = stv5730_icon; + driver->draw_frame = stv5730_draw_frame; + // We dont't need init for vbar,hbar and friends. + driver->init_hbar = NULL; + driver->init_vbar = NULL; + driver->init_num = NULL; + // Neither contrast nor backlight are controllable. + driver->contrast = NULL; + driver->backlight = NULL; + // There are some unused input lines that may be used for input, + // but nothing is programmed so far. + driver->getkey = NULL; + return 200; // 200 is arbitrary. (must be 1 or more) +} + +///////////////////////////////////////////////////////////////// +// Frees the framebuffer and exits the driver. +// +void +stv5730_close () +{ + if (lcd.framebuf != NULL) + free (lcd.framebuf); + lcd.framebuf = NULL; +} + +///////////////////////////////////////////////////////////////// +// Clears the screen +// +void +stv5730_clear () +{ + memset (lcd.framebuf, 0x0B, STV5730_WID * STV5730_HGT); +} + +///////////////////////////////////////////////////////////////// +// +// Flushes all output to the lcd... +// +void +stv5730_flush () +{ + lcd.draw_frame (lcd.framebuf); +} + +///////////////////////////////////////////////////////////////// +// Prints a string on the screen, at position (x,y). The +// upper-left is (1,1), and the lower right should be (28,11). +// +void +stv5730_string (int x, int y, char string[]) +{ + int i; + x--; // Convert 1-based coords to 0-based... + y--; + + for (i = 0; string[i]; i++) + { + stv5730_drawchar2fb (x + i, y, string[i]); + } +} + +///////////////////////////////////////////////////////////////// +// Writes char c at position x,y into the framebuffer. +// x and y are 1-based textmode coordinates. +// +void +stv5730_chr (int x, int y, char c) +{ + y--; + x--; + stv5730_drawchar2fb (x, y, c); +} + +///////////////////////////////////////////////////////////////// +// This function draws ugly big numbers. We could use the zoom +// feature of the stv5730 if we'd know when big numbers start +// and stop. +void +stv5730_num (int x, int num) +{ + + int i, j; + x--; + + if (x < 0 || x > 19 || num < 0 || num > 10) + return; + if (num != 10 && (x < 0 || x > 17)) + return; + if (num == 10 && (x < 0 || x > 19)) + return; + + for (j = 1; j < 10; j++) + { + if (num != 10) + { + for (i = 0; i < 3; i++) + stv5730_drawchar2fb (x + i, j, '0' + num); + } + else + { + stv5730_drawchar2fb (x, j, ':'); + } + } + +} + +///////////////////////////////////////////////////////////////// +// Draws a vertical bar from the bottom up to the last 7 rows of the +// framebuffer at 1-based position x. len is given in pixels. +// +void +stv5730_vbar (int x, int len) +{ + + int i; + x--; + + if (x < 0 || len < 0 || (len / 6) >= STV5730_WID) + return; + + for (i = 0; i <= len; i += 6) + { + + if (len >= (i + 6)) + { + lcd.framebuf[((10 - (i / 6)) * STV5730_WID) + x] = 0x77; + } + else + { + lcd.framebuf[((10 - (i / 6)) * STV5730_WID) + x] = + 0x72 + (len % 6); + } + } + +} + + +///////////////////////////////////////////////////////////////// +// Draws a horizontal bar from left to right at 1-based position +// x,y into the framebuffer. len is given in pixels. +// It uses the STV5730 'channel-tuning' chars(0x64-0x68) to do +// this. +void +stv5730_hbar (int x, int y, int len) +{ + int i; + x--; + y--; + + if (y < 0 || y >= STV5730_HGT || x < 0 || len < 0 + || (x + (len / 5)) >= STV5730_WID) + return; + + for (i = 0; i <= len; i += 5) + { + + if (len >= (i + 4)) + { + lcd.framebuf[(y * STV5730_WID) + x + (i / 5)] = 0x64; + } + else + { + lcd.framebuf[(y * STV5730_WID) + x + (i / 5)] = + 0x65 + (len % 5); + } + } +} + +///////////////////////////////////////////////////////////////// +// Reprogrammes character dest to contain an icon given by +// which. +// The STV5730 has no programmable chars. The charset is very +// limited, it doesn't even contain a '%' char. But wait... +// It contains a heartbeat char ! :-) +void +stv5730_icon (int which, char dest) +{ + switch (which) + { + case 0: // 0:empty Heart + stv5730_to_ascii[(int) dest] = 0x71; + break; + case 1: // 1:Filled Heart + stv5730_to_ascii[(int) dest] = 0x0B; + break; + case 2: // 2:Ellipsis + stv5730_to_ascii[(int) dest] = 0x5F; + break; + default: + stv5730_to_ascii[(int) dest] = 0x0B; + break; + + } + +} + +///////////////////////////////////////////////////////////////// +// Send a rectangular area from lft,top to rgt,bot to the display +// These coordinates are probably one-based, too. It's so fast to +// flush the whole display that it makes no sense to flush less then +// the whole display. Therefore this function redraws the whole +// display. +// FIXME: Check if this function is worth implementing. +// +void +stv5730_flush_box (int lft, int top, int rgt, int bot) +{ + stv5730_flush (); +} + +///////////////////////////////////////////////////////////////// +// Outputs the whole framebuffer *dat to the display. +// Attributes are set for every row only. +// The first line has special attributes. +void +stv5730_draw_frame (char *dat) +{ + int i, j, atr; + if (!dat) + return; + + stv5730_locate (0, 0); + + for (i = 0; i < STV5730_HGT; i++) + { + if (i == 0) + atr = (STV5730_COL_FLINE << 8); + else + atr = (STV5730_COL_TEXT << 8); + stv5730_write16bit (0x1000 + atr + dat[i * STV5730_WID] + + stv5730_charattrib); + for (j = 1; j < STV5730_WID; j++) + { + if (dat[j + (i * STV5730_WID) - 1] != + dat[j + (i * STV5730_WID)]) + stv5730_write8bit (dat[j + (i * STV5730_WID)]); + else + stv5730_write0bit (); + + }; + } +} + +///////////////////////////////////////////////////////////////// +// 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/stv5730.h b/server/drivers/stv5730.h new file mode 100644 index 0000000..8046d0d --- /dev/null +++ b/server/drivers/stv5730.h @@ -0,0 +1,19 @@ +#ifndef STV5730_H +#define STV5730_H + +extern lcd_logical_driver *stv5730; + +int stv5730_init (struct lcd_logical_driver *driver, char *args); +void stv5730_close (); +void stv5730_clear (); +void stv5730_flush (); +void stv5730_string (int x, int y, char string[]); +void stv5730_chr (int x, int y, char c); +void stv5730_vbar (int x, int len); +void stv5730_hbar (int x, int y, int len); +void stv5730_num (int x, int num); +void stv5730_icon (int which, char dest); +void stv5730_flush_box (int lft, int top, int rgt, int bot); +void stv5730_draw_frame (char *dat); + +#endif diff --git a/server/render.c b/server/render.c index 016e8f8..cabbad6 100644 --- a/server/render.c +++ b/server/render.c @@ -111,7 +111,7 @@ draw_screen (screen * s, int timer) lcd.output (output_state); // Draw a frame... - draw_frame (s->widgets, 'v', 0, 0, lcd.wid, lcd.hgt, s->wid, s->hgt, s->duration / s->hgt, timer); + draw_frame (s->widgets, 'v', 0, 0, lcd.wid, lcd.hgt, s->wid, s->hgt, (((s->duration / s->hgt) < 1) ? 1 : (s->duration / s->hgt)), timer); //debug("draw_screen done\n");