[Lcdproc] Zalman HD135/VlSys MPlay Blast driver

Sean Meiners sean.lcdproc@ssttr.com
Sun Oct 7 22:42:01 2007


--Apple-Mail-2-888749021
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed

In case anyone is interested, I've written a hd44780 driver for the  
display that comes with the Zalman HD135 case (which appears to be a  
VlSystem MPlay Blast without the 'keys'). It's very similar to the  
lis2 driver with 2 important differences. Its preferred port speed is  
38400 and it uses a rather different method for setting up custom  
characters. This display also has two thermal sensors and fan  
controllers which I've also enabled via config directives in  
LCDd.conf. I haven't tried to get LCDd to publish the temperature or  
fan speed data, but you can configure it to do sensible things. The  
patch (against 0.5.2) is attached below as well as a python script I  
used to help debug the protocol.


--Apple-Mail-2-888749021
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name=mplay.patch
Content-Disposition: attachment;
	filename=mplay.patch

diff -urN lcdproc-0.5.2.orig/acinclude.m4 lcdproc-0.5.2/acinclude.m4
--- lcdproc-0.5.2.orig/acinclude.m4	2007-04-14 07:39:28.000000000 -0700
+++ lcdproc-0.5.2/acinclude.m4	2007-10-07 12:25:49.000000000 -0700
@@ -185,7 +185,7 @@
 			actdrivers=["$actdrivers glk"]
 			;;
 		hd44780)
-			HD44780_DRIVERS="hd44780-hd44780-serial.o hd44780-hd44780-lis2.o"
+			HD44780_DRIVERS="hd44780-hd44780-serial.o hd44780-hd44780-lis2.o hd44780-hd44780-mplay.o"
 			if test "$ac_cv_port_have_lpt" = yes ; then
 				HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-4bit.o hd44780-hd44780-ext8bit.o hd44780-lcd_sem.o hd44780-hd44780-winamp.o hd44780-hd44780-serialLpt.o"
 			fi
diff -urN lcdproc-0.5.2.orig/server/drivers/hd44780-drivers.h lcdproc-0.5.2/server/drivers/hd44780-drivers.h
--- lcdproc-0.5.2.orig/server/drivers/hd44780-drivers.h	2007-04-14 07:38:14.000000000 -0700
+++ lcdproc-0.5.2/server/drivers/hd44780-drivers.h	2007-10-07 12:23:44.000000000 -0700
@@ -19,6 +19,7 @@
 #endif
 #include "hd44780-serial.h"
 #include "hd44780-lis2.h"
+#include "hd44780-mplay.h"
 #ifdef HAVE_LIBUSB
 # include "hd44780-bwct-usb.h"
 # include "hd44780-lcd2usb.h"
@@ -49,6 +50,7 @@
 	{ "pertelian",     hd_init_serial,    "\tnone\n" },
 	/* End serial connectiontypes */
 	{ "lis2",          hd_init_lis2,      "\tnone\n" },
+	{ "mplay",         hd_init_mplay,     "\tnone\n" },
 #ifdef HAVE_LIBUSB
 	{ "bwctusb",       hd_init_bwct_usb,  "\tnone\n" },
 	{ "lcd2usb",       hd_init_lcd2usb,   "\tnone\n" },
diff -urN lcdproc-0.5.2.orig/server/drivers/hd44780-low.h lcdproc-0.5.2/server/drivers/hd44780-low.h
--- lcdproc-0.5.2.orig/server/drivers/hd44780-low.h	2007-04-14 07:38:14.000000000 -0700
+++ lcdproc-0.5.2/server/drivers/hd44780-low.h	2007-10-07 14:19:06.000000000 -0700
@@ -29,6 +29,7 @@
 
 /* Constants for userdefchar_mode */
 #define NUM_CCs 8 /* number of custom characters */
+#define NUM_FANs 2
 
 typedef enum {
 	standard,	/* only char 0 is used for heartbeat */
@@ -49,6 +50,13 @@
 	const char *helpMsg;
 } ConnectionMapping;
 
+typedef struct Fan {
+        int ontemp;
+        int offtemp;
+        int lowspeed;
+        int currentspeed;
+} Fan;
+
 typedef struct driver_private_data {
 
 	unsigned int port;
@@ -117,6 +127,12 @@
 
 	int backlight_bit;
 
+        // Fan control
+        char have_fans;
+        char fan_temp_scale;
+        int fan_update_interval;
+        Fan fans[NUM_FANs];
+
 	// force full refresh of display
 	time_t nextrefresh;
 	int refreshdisplay;     // When >0 make a full display update every <refreshdisplay> seconds
diff -urN lcdproc-0.5.2.orig/server/drivers/hd44780-mplay.c lcdproc-0.5.2/server/drivers/hd44780-mplay.c
--- lcdproc-0.5.2.orig/server/drivers/hd44780-mplay.c	1969-12-31 16:00:00.000000000 -0800
+++ lcdproc-0.5.2/server/drivers/hd44780-mplay.c	2007-10-07 14:26:06.000000000 -0700
@@ -0,0 +1,331 @@
+/*
+ * MPLAY Serializer driver
+ * Modification of the code of the LCDSerializer driver
+ *
+ * Copyright (c)  1997, Matthias Prinke <m.prinke@trashcan.mcnet.de>
+ *		  1998, Richard Rognlie <rrognlie@gamerz.net>
+ * 		  1999, Ethan Dicks
+ *		  1999-2000, Benjamin Tse <blt@Comports.com>
+ *		  2001, Rene Wagner
+ *		  2001-2002, Joris Robijn <joris@robijn.net>
+ *                2005, Pillon Matteo <matteo.pillon@email.it>
+ *		  2005, Laurent ARNAL <laurent@clae.net>
+ *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ *
+ * 
+ * 
+ *
+ */
+
+#include "hd44780-mplay.h"
+#include "hd44780-low.h"
+
+#include "report.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <errno.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#define DEFAULT_DEVICE		"/dev/ttyUSB0"
+
+/* bitrate conversion */
+extern unsigned int **bitrate_conversion;
+extern int convert_bitrate(unsigned int conf_bitrate, size_t *bitrate);
+
+void mplay_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch);
+void mplay_HD44780_backlight(PrivateData *p, unsigned char state);
+unsigned char mplay_HD44780_scankeypad(PrivateData *p);
+
+static void ClearScreen(int fd);
+static void InitFans(int fd);
+static void SetFans(int fd, unsigned char *fans, int num);
+static void SetChars(int fd, CGram *chars);
+static char readTemps(int fd, int *temps, int num);
+static void gotoXY(int fd, int x, int y);
+
+static void writeChar(int fd, int code);
+
+
+// initialise the driver
+int hd_init_mplay(Driver *drvthis)
+{
+	PrivateData *p = (PrivateData*) drvthis->private_data;
+
+	struct termios portset;
+	char device[256] = DEFAULT_DEVICE;
+
+	/* READ CONFIG FILE */
+
+	/* Get serial device to use */
+	strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device));
+	device[sizeof(device)-1] = '\0';
+	report(RPT_INFO, "HD44780: LCD Serializer: Using device: %s", device);
+
+	// Set up io port correctly, and open it...
+	p->fd = open(device, O_RDWR | O_NOCTTY);
+	if (p->fd == -1) {
+		report(RPT_ERR, "HD44780: LCD Serializer: could not open device %s (%s)",
+				device, strerror(errno));
+		return -1;
+	}
+
+	/* Get serial device parameters */
+	tcgetattr(p->fd, &portset);
+
+	portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
+	                      | INLCR | IGNCR | ICRNL | IXON );
+	portset.c_oflag &= ~OPOST;
+	portset.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
+	portset.c_cflag &= ~( CSIZE | PARENB | CRTSCTS );
+	portset.c_cflag |= CS8 | CREAD | CLOCAL ;
+	portset.c_cc[VMIN] = 1;
+	portset.c_cc[VTIME] = 3;
+
+	/* Get bitrate */
+	unsigned int conf_bitrate;
+	size_t bitrate;
+
+	conf_bitrate = drvthis->config_get_int(drvthis->name, "Speed", 0, 38400);
+        if (conf_bitrate==0)
+                conf_bitrate = 38400;
+	if (convert_bitrate(conf_bitrate, &bitrate)) {
+		report(RPT_ERR, "HD44780: mplay: invalid configured bitrate speed");
+		return -1;
+	}
+	report(RPT_INFO, "HD44780: mplay: using speed: %d", conf_bitrate);
+
+	cfsetospeed(&portset, bitrate);
+	cfsetispeed(&portset, bitrate);
+
+	/* Set TCSANOW mode of serial device */
+	tcsetattr(p->fd, TCSANOW, &portset);
+
+	p->hd44780_functions->senddata = mplay_HD44780_senddata;
+	p->hd44780_functions->backlight = mplay_HD44780_backlight;
+	p->hd44780_functions->scankeypad = mplay_HD44780_scankeypad;
+
+	common_init(p, IF_8BIT);
+
+	p->have_fans = drvthis->config_get_bool(drvthis->name, "HaveFans", 0, 0);
+	p->fan_update_interval = drvthis->config_get_bool(drvthis->name, "FansUpdateSecs", 0, 10);
+	report(RPT_INFO, "HD44780: mplay: fans enabled: %s, updating every %d secs",
+	       p->have_fans ? "yes" : "no", p->fan_update_interval);
+	if( p->have_fans )
+	{
+	        const char* scale = drvthis->config_get_string(drvthis->name, "TempScale", 0, "C");
+		if( scale && (scale[0] == 'f' || scale[0] == 'F') )
+		        p->fan_temp_scale = 'f';
+		else
+		        p->fan_temp_scale = 'c';
+
+		report(RPT_INFO, "HD44780: mplay: temperature scale: %s", p->fan_temp_scale == 'f' ? "Farenheit" : "Celcius");
+
+		int i;
+		for( i = 0; i < NUM_FANs; ++i )
+		{
+		        p->fans[i].ontemp   = drvthis->config_get_int(drvthis->name, "FanOn", i,
+								      p->fan_temp_scale == 'f' ? 120 : 50);
+			p->fans[i].offtemp  = drvthis->config_get_int(drvthis->name, "FanOff", i,
+								      p->fan_temp_scale =='f' ? 110 : 45);
+			p->fans[i].lowspeed = drvthis->config_get_int(drvthis->name, "FanMinSpeed", i, 140);
+			p->fans[i].currentspeed = p->fans[i].lowspeed;
+
+			report(RPT_INFO, "HD44780: mplay: fan %d config: On at: %d, Off at: %d, Min Speed: %d",
+			       i, p->fans[i].ontemp, p->fans[i].offtemp, p->fans[i].lowspeed);
+		}
+
+		if( p->keepalivedisplay < p->fan_update_interval )
+		        p->keepalivedisplay = p->fan_update_interval;
+
+		InitFans(p->fd);
+		p->hd44780_functions->uPause(p, 40);  // Minimum exec time for all commands
+	}
+
+	return 0;
+}
+
+static void ClearScreen(int fd)
+{
+        writeChar(fd, 0);
+	writeChar(fd, 0xA0);
+}
+
+static void InitFans(int fd)
+{
+	writeChar(fd, 0);
+	writeChar(fd, 0xA4);
+	writeChar(fd, 0x7D);
+}
+
+static void SetFans(int fd, unsigned char *fans, int num)
+{
+        int i;
+	writeChar(fd, 0);
+	writeChar(fd, 0xAC);
+	for( i = 0; i < num; ++i )
+	        writeChar(fd, fans[i]);
+}
+
+static void SetChars(int fd, CGram *chars)
+{
+        // chars *must* be 8x8
+        int i, row;
+        writeChar(fd, 0);
+	writeChar(fd, 0xAD);
+	for( i = 0; i < 8; ++i )
+	{
+	        for( row = 0; row < 8; ++row )
+		{
+		        writeChar(fd, chars[i].cache[row]);
+		}
+	}
+}
+
+static char readTemps(int fd, int *temps, int num)
+{
+        writeChar(fd, 0);
+	writeChar(fd, 0xAF);
+
+	unsigned char raw[num];
+	int i;
+	if( read(fd, raw, num) == num )
+	{
+	        for( i = 0; i < num; ++i )
+		        temps[i] = (int)raw[i] - 150;
+		return 1;
+	}
+
+	return 0;
+}
+
+static void gotoXY(int fd, int x, int y)
+{
+	writeChar(fd, 0);
+	writeChar(fd, 0xA1+y);
+	writeChar(fd, x);
+	writeChar(fd, 167);
+}
+
+static void writeChar(int fd, int code)
+{
+	char buf = code;
+
+	write(fd, &buf, 1);
+}
+
+
+static int mode = 0;
+static int charNum = 0;
+static int rowNum = 0;
+static time_t nextfanupdate = 0;
+
+void mplay_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
+{
+	if (p->have_fans && time(NULL) > nextfanupdate)
+	{
+		nextfanupdate = time(NULL) + p->fan_update_interval;
+
+		int temps[NUM_FANs];
+		if( readTemps(p->fd, temps, NUM_FANs) )
+		{
+		        int i;
+		        if( p->fan_temp_scale == 'f' )
+			{
+			        for( i = 0; i < NUM_FANs; ++i )
+				        temps[i] = temps[i] * 9 / 5 + 32;
+			}
+			
+			for( i = 0; i < NUM_FANs; ++i )
+			{
+			        if( p->fans[i].currentspeed > 0 && temps[i] < p->fans[i].offtemp )
+				        p->fans[i].currentspeed = 0;
+
+				else if( temps[i] >= p->fans[i].ontemp )
+				        p->fans[i].currentspeed = 
+					  (temps[i] - p->fans[i].ontemp) * 
+					  (255 - p->fans[i].lowspeed) /
+					  100 + p->fans[i].lowspeed;
+			}
+
+			unsigned char fanspeeds[NUM_FANs];
+			for( i = 0; i < NUM_FANs; ++i )
+			        fanspeeds[i] = p->fans[i].currentspeed;
+			SetFans(p->fd, fanspeeds, NUM_FANs);
+			p->hd44780_functions->uPause(p, 40);  // Minimum exec time for all commands
+		}
+	}
+
+	if (flags == RS_DATA) {
+		if (mode == SETCHAR) {
+			rowNum++;
+			if (rowNum == p->cellheight) {
+			        mode = 0;
+				rowNum = 0;
+			        SetChars(p->fd, p->cc);
+				//report(RPT_INFO, "HD44780: mplay: read temps (in C): %d, %d", temps[0], temps[1]);
+				p->hd44780_functions->uPause(p, 40);  // Minimum exec time for all commands
+			}
+		}
+		else {
+		        // 0x00 is the command prefix so we can't use it.
+		        // luckly, there are 16 custom char positions & the
+		        // second 8 are identical to the first 8 so we can
+		        // just offset it
+			if (ch < 8) ch+=8;
+			write(p->fd, &ch, 1);
+		}
+	}
+	else {
+		if ((ch & POSITION) != 0) {
+			int x = 0;
+			int y = 0;
+			int pos = 0;
+
+			pos = (ch & ~POSITION);
+
+			if (p->ext_mode) {				
+				y = pos / 0x20;
+				x = pos - (y * 0x20);
+			}
+			else {
+				y = pos / 0x40;
+				x = pos - (y * 0x40);
+			}
+
+			gotoXY(p->fd, x, y);
+		}
+		else if ((ch & SETCHAR) != 0) {
+			mode = SETCHAR;
+			charNum = ch & ~SETCHAR;
+			if (charNum == 8) charNum = 7;
+			rowNum = 0;
+		}
+	 	else write(p->fd, &ch, 1);
+	}
+
+}
+
+void mplay_HD44780_backlight(PrivateData *p, unsigned char state)
+{
+	/* No backlight control */
+}
+
+unsigned char mplay_HD44780_scankeypad(PrivateData *p)
+{
+	return 0;
+}
+
+
diff -urN lcdproc-0.5.2.orig/server/drivers/hd44780-mplay.h lcdproc-0.5.2/server/drivers/hd44780-mplay.h
--- lcdproc-0.5.2.orig/server/drivers/hd44780-mplay.h	1969-12-31 16:00:00.000000000 -0800
+++ lcdproc-0.5.2/server/drivers/hd44780-mplay.h	2007-10-07 10:47:03.000000000 -0700
@@ -0,0 +1,9 @@
+#ifndef HD_MPLAY_H
+#define HD_MPLAY_H
+
+#include "lcd.h"					  /* for Driver */
+
+// initialise this particular driver
+int hd_init_mplay(Driver *drvthis);
+
+#endif
diff -urN lcdproc-0.5.2.orig/server/drivers/Makefile.am lcdproc-0.5.2/server/drivers/Makefile.am
--- lcdproc-0.5.2.orig/server/drivers/Makefile.am	2007-04-14 07:39:53.000000000 -0700
+++ lcdproc-0.5.2/server/drivers/Makefile.am	2007-10-07 12:40:54.000000000 -0700
@@ -71,7 +71,7 @@
 glcdlib_SOURCES =    lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h
 glk_SOURCES =        lcd.h glk.c glk.h glkproto.c glkproto.h report.h
 hd44780_SOURCES =    lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h
-EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h
+EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h hd44780-mplay.c hd44780-mplay.h
 
 icp_a106_SOURCES =   lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
 imon_SOURCES =       lcd.h lcd_lib.h imon.h imon.c report.h
diff -urN lcdproc-0.5.2.orig/server/drivers/Makefile.in lcdproc-0.5.2/server/drivers/Makefile.in
--- lcdproc-0.5.2.orig/server/drivers/Makefile.in	2007-04-27 03:40:28.000000000 -0700
+++ lcdproc-0.5.2/server/drivers/Makefile.in	2007-10-07 12:43:13.000000000 -0700
@@ -396,7 +396,7 @@
 glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h
 glk_SOURCES = lcd.h glk.c glk.h glkproto.c glkproto.h report.h
 hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h
-EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h
+EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h hd44780-mplay.c hd44780-mplay.h
 icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
 imon_SOURCES = lcd.h lcd_lib.h imon.h imon.c report.h
 IOWarrior_SOURCES = lcd.h lcd_lib.h hd44780-charmap.h IOWarrior.c IOWarrior.h report.h adv_bignum.h
@@ -645,6 +645,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-i2c.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-lcd2usb.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-lis2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-mplay.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-serial.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-serialLpt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd44780-hd44780-winamp.Po@am__quote@
@@ -888,6 +889,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hd44780-i2c.c' object='hd44780-hd44780-i2c.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hd44780_CFLAGS) $(CFLAGS) -c -o hd44780-hd44780-i2c.obj `if test -f 'hd44780-i2c.c'; then $(CYGPATH_W) 'hd44780-i2c.c'; else $(CYGPATH_W) '$(srcdir)/hd44780-i2c.c'; fi`
+
+hd44780-hd44780-mplay.o: hd44780-mplay.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hd44780_CFLAGS) $(CFLAGS) -MT hd44780-hd44780-mplay.o -MD -MP -MF "$(DEPDIR)/hd44780-hd44780-mplay.Tpo" -c -o hd44780-hd44780-mplay.o `test -f 'hd44780-mplay.c' || echo '$(srcdir)/'`hd44780-mplay.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/hd44780-hd44780-mplay.Tpo" "$(DEPDIR)/hd44780-hd44780-mplay.Po"; else rm -f "$(DEPDIR)/hd44780-hd44780-mplay.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hd44780-mplay.c' object='hd44780-hd44780-mplay.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hd44780_CFLAGS) $(CFLAGS) -c -o hd44780-hd44780-mplay.o `test -f 'hd44780-mplay.c' || echo '$(srcdir)/'`hd44780-mplay.c
+
+hd44780-hd44780-mplay.obj: hd44780-mplay.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hd44780_CFLAGS) $(CFLAGS) -MT hd44780-hd44780-mplay.obj -MD -MP -MF "$(DEPDIR)/hd44780-hd44780-mplay.Tpo" -c -o hd44780-hd44780-mplay.obj `if test -f 'hd44780-mplay.c'; then $(CYGPATH_W) 'hd44780-mplay.c'; else $(CYGPATH_W) '$(srcdir)/hd44780-mplay.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/hd44780-hd44780-mplay.Tpo" "$(DEPDIR)/hd44780-hd44780-mplay.Po"; else rm -f "$(DEPDIR)/hd44780-hd44780-mplay.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hd44780-mplay.c' object='hd44780-hd44780-mplay.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hd44780_CFLAGS) $(CFLAGS) -c -o hd44780-hd44780-mplay.obj `if test -f 'hd44780-mplay.c'; then $(CYGPATH_W) 'hd44780-mplay.c'; else $(CYGPATH_W) '$(srcdir)/hd44780-mplay.c'; fi`
 uninstall-info-am:
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
diff -urN lcdproc-0.5.2.orig/LCDd.conf lcdproc-0.5.2/LCDd.conf
--- lcdproc-0.5.2.orig/LCDd.conf	2007-04-25 12:56:43.000000000 -0700
+++ lcdproc-0.5.2/LCDd.conf	2007-10-07 15:26:31.000000000 -0700
@@ -484,6 +484,37 @@
 KeyMatrix_4_3=Down
 KeyMatrix_4_4=Escape
 
+# Does the display have a fan controller?
+HaveFans=n
+
+# 'f' for Farenheit or 'c' for Celcius
+TemperatureScale=f
+
+# You can change the parameters for the fan controller below
+# The first set of parameters will use the first temperature sensor
+# and the first fan, the second set will use the second temperature
+# sensor and second fan, etc.
+# Note: only 2 fans & 2 sensors are currently supported in the mplay driver
+
+# Fan 1 & Sensor 1
+# The minimum temperature before the fan will turn on.
+# [default: 120f/50c]
+FanOn=120
+# The temperature the sensor must read before turning the fan off.
+# It is recommended that this be lower than FanOn to prevent the
+# fan from constantly cycling between on and off.
+# [default: 110f/45c]
+FanOff=110
+# The minimum allowable speed for the fan (range: 0-255).
+# Many fans will not spin at all if this value is too low.
+# [default: 140, this seems to work with most fans]
+FanMinSpeed=140
+
+# Fan 2 & Sensor 2
+# See above for explinations
+FanOn=120
+FanOff=110
+FanMinSpeed=140
 
 
 ## ICP A106 driver ##

--Apple-Mail-2-888749021
Content-Transfer-Encoding: 7bit
Content-Type: text/x-python-script;
	x-unix-mode=0755;
	name=hd135.py
Content-Disposition: attachment;
	filename=hd135.py

#!/usr/bin/python

#  60436450
# nec d16314agj-011
#     0609xx018

# top = temp2
# bottom = temp1


# 21 - 171
# 25 - 175
# 33 - 183

# left = fan2
# right = fan1

import os
import sys
import termios
import tty
import time
from select import select

keymap = {
    0x41: 'PwrOff',
    0x55: 'PwrOn',
    0x40: 'Movies',
    0x46: 'Television',
    0x45: 'Photos',
    0x56: 'Music',
    0x4d: '1',
    0x4e: '2',
    0x4f: '3',
    0x50: '4',
    0x51: '5',
    0x52: '6',
    0x53: '7',
    0x03: '8',
    0x07: '9',
    0x4c: '0',
    0x0a: 'Vol+',
    0x0e: 'Vol-',
    0x12: 'Ch+/Lang',
    0x16: 'Ch-/Page',
    0x0f: 'Guide',
    0x0b: 'Back',
    0x13: 'TV',
    0x42: 'OK',
    0x19: 'Up',
    0x54: 'Left',
    0x43: 'Right',
    0x1d: 'Down',
    0x1f: 'Exit/Click',
    0x17: 'Task/Quick',
    0x1b: 'Run/D.Click',
    0x0d: 'Rew',
    0x09: 'Play',
    0x15: 'FFwd',
    0x1a: 'Prev',
    0x01: 'Stop',
    0x1e: 'Next',
    0x05: 'Pause',
    0x4a: 'Mute',
    0x47: 'Warp/Mouse',
    0x11: 'Rec',
    0x14: 'DVD/Zoom',
    0x4b: 'Detail',
    0x7e: '<repeat>',
}

b_______ = 0x00
b______X = 0x01
b_____X_ = 0x02
b_____XX = 0x03
b____X__ = 0x04
b____X_X = 0x05
b____XX_ = 0x06
b____XXX = 0x07
b___X___ = 0x08
b___X__X = 0x09
b___X_X_ = 0x0A
b___X_XX = 0x0B
b___XX__ = 0x0C
b___XX_X = 0x0D
b___XXX_ = 0x0E
b___XXXX = 0x0F
b__X____ = 0x10
b__X___X = 0x11
b__X__X_ = 0x12
b__X__XX = 0x13
b__X_X__ = 0x14
b__X_X_X = 0x15
b__X_XX_ = 0x16
b__X_XXX = 0x17
b__XX___ = 0x18
b__XX__X = 0x19
b__XX_X_ = 0x1A
b__XX_XX = 0x1B
b__XXX__ = 0x1C
b__XXX_X = 0x1D
b__XXXX_ = 0x1E
b__XXXXX = 0x1F
b_XXX___ = 0x38
b_XXXXXX = 0x3F

block1 = [ b_______,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]
block2 = [ b__XXXXX,
	   b_______,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]
block3 = [ b__XXXXX,
	   b__XXXXX,
	   b_______,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]
block4 = [ b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]
block5 = [ b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]
block6 = [ b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______,
	   b__XXXXX,
	   b_______ ]
block7 = [ b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______,
	   b_______ ]
block8 = [ b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b__XXXXX,
	   b_______ ]

fd = os.open("/dev/ttyUSB0", os.O_RDWR)

#tty.setraw(fd)
attrs = [0, 1, 2, 3, 4, 5, [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ] ]
attrs = termios.tcgetattr(fd)

#c_iflag = 0
#c_oflag = 1
#c_cflag = 2
#c_lflag = 3
#ispeed  = 4
#ospeed  = 5
#cc      = 6

# iflag
attrs[0] = attrs[0] & ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK |
			termios.ISTRIP | termios.INLCR | termios.IGNCR |
			termios.ICRNL | termios.IXON)
# oflag
attrs[1] = attrs[1] & ~termios.OPOST
# lflag
attrs[3] = attrs[3] & ~(termios.ECHO | termios.ECHONL | termios.ICANON |
			termios.ISIG | termios.IEXTEN)
# cflag
attrs[2] = attrs[2] & ~(termios.CSIZE | termios.PARENB | termios.CRTSCTS)
attrs[2] = attrs[2] | termios.CS8 | termios.CREAD | termios.CLOCAL
# control chars
attrs[6][termios.VMIN] = 1
attrs[6][termios.VTIME] = 3
# ispeed
attrs[4] = termios.B38400
# ospeed
attrs[5] = termios.B38400

termios.tcsetattr(fd, termios.TCSANOW, attrs)

def write(fd, v):
    os.write(fd, chr(v))

def writeChr(fd, c):
    os.write(fd, c)

def writeLn(fd, ln):
    for i in range(0, min(len(ln), 20)):
	writeChr(fd, ln[i])
    time.sleep(0.000040)

def clear(fd):
    write(fd, 0xA0)
    time.sleep(0.000040)

def gotoXY(fd, x, y):
    write(fd, 0)
    write(fd, 0xA1+y)
    write(fd, x)
    write(fd, 0xA7)
    time.sleep(0.000040)

def initFans(fd):
    write(fd, 0)
    write(fd, 0xA4)
    write(fd, 0x7D)

def setFans(fd, fan1, fan2):
    write(fd, 0)
    write(fd, 0xAC)
    write(fd, fan1)
    write(fd, fan2)
    time.sleep(0.000040)

def setChars(fd, chars):
    write(fd, 0)
    write(fd, 0xAD)
    for char in chars:
	for row in char:
	    write(fd, row)
    time.sleep(0.000040)

def readTemp(fd):
    # request the current temp
    write(fd, 0)
    write(fd, 0xAF)
    time.sleep(0.000040)

    res = select([fd], [], [])
    if len(res[0]):
	temp1 = -1
	temp2 = -1
	while temp2 == -1:
	    str = os.read(fd, 2)
	    if len(str) == 1:
		if temp1 == -1:
		    temp1 = ord(str[0])
		else:
		    temp2 = ord(str[0])

	    elif len(str) == 2:
		temp1 = ord(str[0])
		temp2 = ord(str[1])

	    else:
		sys.stdout.write("Unexpected data during remp read: ")
		for c in str:
		    sys.stdout.write( "0x%02x " % ord(c) )
		sys.stdout.write("\n")
		break

	if temp2 != -1:
	    if 1: # farenheit
		temp1 = (temp1 - 150) * 9 / 5 + 32
		temp2 = (temp2 - 150) * 9 / 5 + 32
	    else: # celcius
		temp1 = temp1 - 150
		temp2 = temp2 - 150

	    return (temp1, temp2)

    return None

# initialize the fan controller
initFans(fd)

# setup our custom chars
chars = [ block1, block2, block3, block4,
	  block5, block6, block7, block8 ]
setChars(fd, chars)

# clear the screen
clear(fd)

# display some test data
gotoXY(fd, 0, 0)
for i in range(8, 16):
    write(fd, i)
writeLn(fd, "012345678901")
gotoXY(fd, 0, 1)
#            01234567890123456789
writeLn(fd, "ABCDEFGHIJKLMNOPQRST")

sys.exit(0)

lastTime = 0.0

FAN_ON  = [120, 120]
FAN_OFF = [110, 110]
FAN_LOW = [140, 140]
fans = [FAN_LOW[0], FAN_LOW[1]]
fanTempMap = [1, 0]
fanNames =  ['Case  ', 'CPU   ']

tempNames = ['CPU   ', 'Video ']

while 1:
    res = select([fd], [], [], 0.1)
    if len(res[0]):
	str = os.read(fd, 20)
	if len(str) == 1:
	    val = ord(str[0])
	    if val in keymap:
		print "%s (0x%02x)" % (keymap[val], val)
	    else:
		print "<unknown> (0x%02x)" % (val)
	else:
	    sys.stdout.write("Read: ")
	    for c in str:
		sys.stdout.write( "0x%02x " % ord(c) )
	    sys.stdout.write("\n")

    if lastTime + 1 < time.time():
	lastTime = time.time()

	# temp0 = cpu
	# fan1 = case
	# temp1 = video
	# fan2 = top/cpu

	temps = readTemp(fd)
	if temps:
	    gotoXY(fd, 0, 0)
	    writeLn(fd, "%s%3d  %s%3d" % ( tempNames[0], temps[0], tempNames[1], temps[1] ) )

	    for i in range(0, 2):
		if fans[i] > 0 and temps[fanTempMap[i]] < FAN_OFF[i]:
		    fans[i] = 0
		elif temps[fanTempMap[i]] >= FAN_ON[i]:
		    fans[i] = (temps[fanTempMap[i]] - FAN_ON[i]) * (255 - FAN_LOW[i]) / 100 + FAN_LOW[i]

	gotoXY(fd, 0, 1)
	writeLn(fd, "%s%3d  %s%3d" % (fanNames[fanTempMap[0]],
				      fans[fanTempMap[0]],
				      fanNames[fanTempMap[1]],
				      fans[fanTempMap[1]]) )
	setFans(fd, fans[0], fans[1])

    time.sleep(0.010)

fd.close()

--Apple-Mail-2-888749021
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed


I hope this helps someone out,
--Sean Meiners.


The person who said it can't be done is always interrupted by the one  
who just did it.


--Apple-Mail-2-888749021--