diff --git a/ChangeLog b/ChangeLog index 8910f62..50f72c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,8 @@ v.0.5dev (ongoing development) * avoid sending duplicate "success" messages in response to menu_add_item + lcdexec: parameter support using widgets * server core: display values in menu for all input MenuEntry types + * hd44780 driver: reorganize ConnectionType recognition + + hd44780 driver: new ConnectionType mplay v.0.5.2 * fix switching on/off the Load screen in lcdproc client using the menu diff --git a/docs/LCDd.8.in b/docs/LCDd.8.in index 3855fe6..9329db6 100644 --- a/docs/LCDd.8.in +++ b/docs/LCDd.8.in @@ -152,6 +152,9 @@ Pertelian X2040 module (http://pertelian.com/) .B lis2 LIS2 from VLSystem (http://www.vlsys.co.kr), connected to USB .TP +.B mplay +MPlay Blast from VLSystem (http://www.vlsys.co.kr), connected to USB +.TP .B bwctusb USB-to-HD44780 converter by BWCT (http://www.bwct.de) .TP diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook index 7a479af..c82a3e3 100644 --- a/docs/lcdproc-user/drivers/hd44780.docbook +++ b/docs/lcdproc-user/drivers/hd44780.docbook @@ -1553,10 +1553,25 @@ that. The BL output below should be connected to the BL input in the LIS2 USB device "lis2" -LIS2 from VLSystem () is a full featured USB VFD module -with four channel fan controls. This device can be accessed as a serial device with the -help of the kernel modules ftdi_sio.ko that map the USB port to a serial port -(/dev/ttyUSBx). +LIS2 from VLSystem () +is a full featured USB VFD module with four channel fan controls. +This device can be accessed as a serial device with the help of the kernel +module ftdi_sio.ko that maps the USB port to a serial port +(e.g. /dev/ttyUSBx). + + + + + +MPlay Blast USB device "mplay" + + +MPlay Blast from VLSystem () +is a full featured USB VFD module with two channel fan controls and +two channel temperature sensors. +This device can be accessed as a serial device with the help of the kernel +module ftdi_sio.ko that maps the USB port to a serial port +(e.g. /dev/ttyUSBx). @@ -2104,6 +2119,7 @@ This can be done by specifying or by inclu bwctusb lcd2usb lis2 + mplay i2c @@ -2173,6 +2189,10 @@ This can be done by specifying or by inclu lis2 LIS2 from VLSystem () + + mplay + MPlay Blast from VLSystem () + i2c LCD driven by PCF8574(A)/PCA9554(A) connected via I2C diff --git a/server/drivers/hd44780-drivers.h b/server/drivers/hd44780-drivers.h index b55039d..53f5151 100644 --- a/server/drivers/hd44780-drivers.h +++ b/server/drivers/hd44780-drivers.h @@ -36,26 +36,27 @@ // - initialisation function static const ConnectionMapping connectionMapping[] = { #ifdef HAVE_PCSTYLE_LPT_CONTROL - { "4bit", HD44780_CT_4BIT, IF_TYPE_PARPORT, hd_init_4bit }, - { "8bit", HD44780_CT_8BIT, IF_TYPE_PARPORT, hd_init_ext8bit }, - { "serialLpt", HD44780_CT_SERIALLPT, IF_TYPE_PARPORT, hd_init_serialLpt }, - { "winamp", HD44780_CT_WINAMP, IF_TYPE_PARPORT, hd_init_winamp }, + { "4bit", HD44780_CT_4BIT, IF_TYPE_PARPORT, hd_init_4bit }, + { "8bit", HD44780_CT_8BIT, IF_TYPE_PARPORT, hd_init_ext8bit }, + { "serialLpt", HD44780_CT_SERIALLPT, IF_TYPE_PARPORT, hd_init_serialLpt }, + { "winamp", HD44780_CT_WINAMP, IF_TYPE_PARPORT, hd_init_winamp }, #endif /* Serial connectiontypes */ - { "picanlcd", HD44780_CT_PICANLCD, IF_TYPE_SERIAL, hd_init_serial }, - { "lcdserializer", HD44780_CT_LCDSERIALIZER, IF_TYPE_SERIAL, hd_init_serial }, - { "los-panel", HD44780_CT_LOS_PANEL, IF_TYPE_SERIAL, hd_init_serial }, - { "vdr-lcd", HD44780_CT_VDR_LCD, IF_TYPE_SERIAL, hd_init_serial }, - { "vdr-wakeup", HD44780_CT_VDR_WAKEUP, IF_TYPE_SERIAL, hd_init_serial }, - { "pertelian", HD44780_CT_PERTELIAN, IF_TYPE_SERIAL, hd_init_serial }, + { "picanlcd", HD44780_CT_PICANLCD, IF_TYPE_SERIAL, hd_init_serial }, + { "lcdserializer", HD44780_CT_LCDSERIALIZER, IF_TYPE_SERIAL, hd_init_serial }, + { "los-panel", HD44780_CT_LOS_PANEL, IF_TYPE_SERIAL, hd_init_serial }, + { "vdr-lcd", HD44780_CT_VDR_LCD, IF_TYPE_SERIAL, hd_init_serial }, + { "vdr-wakeup", HD44780_CT_VDR_WAKEUP, IF_TYPE_SERIAL, hd_init_serial }, + { "pertelian", HD44780_CT_PERTELIAN, IF_TYPE_SERIAL, hd_init_serial }, /* End serial connectiontypes */ - { "lis2", HD44780_CT_LIS2, IF_TYPE_SERIAL, hd_init_lis2 }, + { "lis2", HD44780_CT_LIS2, IF_TYPE_USB, hd_init_lis2 }, + { "mplay", HD44780_CT_MPLAY, IF_TYPE_USB, hd_init_lis2 }, #ifdef HAVE_LIBUSB - { "bwctusb", HD44780_CT_BWCTUSB, IF_TYPE_USB, hd_init_bwct_usb }, - { "lcd2usb", HD44780_CT_I2C, IF_TYPE_USB, hd_init_lcd2usb }, + { "bwctusb", HD44780_CT_BWCTUSB, IF_TYPE_USB, hd_init_bwct_usb }, + { "lcd2usb", HD44780_CT_I2C, IF_TYPE_USB, hd_init_lcd2usb }, #endif #ifdef HAVE_I2C - { "i2c", HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c }, + { "i2c", HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c }, #endif // add new connection types and their string specifier here // default, end of structure element (do not delete) diff --git a/server/drivers/hd44780-lis2.c b/server/drivers/hd44780-lis2.c index 7d2d648..a0fe41c 100644 --- a/server/drivers/hd44780-lis2.c +++ b/server/drivers/hd44780-lis2.c @@ -1,10 +1,9 @@ /** \file hd44780-lis2.c - * \c lis2 connection type of \c hd44780 driver for Hitachi HD44780 based LCD displays. + * \c lis2 and \c mplay connection types of \c hd44780 driver for Hitachi HD44780 based LCD displays. */ /* - * VLSystems LIS2 driver - * Modification of the code of the LCDSerializer driver + * Driver for VLsystems LIS2 and MPlay displays. * * Copyright (c) 1997, Matthias Prinke * 1998, Richard Rognlie @@ -15,6 +14,7 @@ * 2005, Pillon Matteo * 2005, Laurent ARNAL * 2007, Peter Marschall + * 2007, Sean Meiners * * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. @@ -40,17 +40,25 @@ # include "config.h" #endif -#define DEFAULT_DEVICE "/dev/ttyUSB0" +#define DEFAULT_DEVICE "/dev/ttyUSB0" +/* bitrate conversion */ +extern unsigned int **bitrate_conversion; +extern int convert_bitrate(unsigned int conf_bitrate, size_t *bitrate); + void lis2_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); void lis2_HD44780_backlight(PrivateData *p, unsigned char state); unsigned char lis2_HD44780_scankeypad(PrivateData *p); -static void setLIS2CustomCharRow(int fd, unsigned char custom, unsigned char row, unsigned char data); -static void setLIS2Fan(int fd, int fan1, int fan2, int fan3, int fan4); +static void clearScreen(int fd); static void gotoXY(int fd, unsigned char x, unsigned char y); - +static void setMPlayCustomChars(int fd, CGram *chars); +static void setLIS2CustomCharRow(int fd, unsigned char custom, unsigned char row, unsigned char data); +static char readMPlayTemps(int fd, int *temps, int num); +static void initMPlayFans(int fd); +static void setMPlayFans(int fd, unsigned char *fans, int num); +static void setLIS2Fans(int fd, int fan1, int fan2, int fan3, int fan4); static void writeChar(int fd, unsigned char code); @@ -89,9 +97,26 @@ int hd_init_lis2(Driver *drvthis) portset.c_cc[VMIN] = 1; portset.c_cc[VTIME] = 3; - /* Set port speed to 19200 baud */ - cfsetospeed(&portset, B19200); - cfsetispeed(&portset, B0); + if (p->connectiontype == HD44780_CT_LIS2) { + /* Set port speed to 19200 baud */ + cfsetospeed(&portset, B19200); + cfsetispeed(&portset, B0); + } + else { // p->connectiontype == HD44780_CT_MPLAY + /* Get bitrate */ + unsigned int conf_bitrate; + size_t bitrate; + + conf_bitrate = drvthis->config_get_int(drvthis->name, "Speed", 0, 38400); + if (convert_bitrate(conf_bitrate, &bitrate)) { + report(RPT_ERR, "HD44780: lis2: invalid configured bitrate speed"); + return -1; + } + report(RPT_INFO, "HD44780: lis2: using speed: %d", conf_bitrate); + + cfsetospeed(&portset, bitrate); + cfsetispeed(&portset, bitrate); + } /* Set TCSANOW mode of serial device */ tcsetattr(p->fd, TCSANOW, &portset); @@ -106,74 +131,6 @@ int hd_init_lis2(Driver *drvthis) } -/** - * Set one pixel row of a custom character, valid on LIS2 devices only. - * \param fd File handle to write to. - * \param custom Custom character to set (from 0 to 7). - * \param row Index of pixel row to set (from (0 [=top] to 7 [=bottom]). - * \param data Pixel data: 5 bit coding from 0 to 31 from right to left (16/8/4/2/1). - */ -static void setLIS2CustomCharRow(int fd, unsigned char custom, unsigned char row, unsigned char data) -{ - writeChar(fd, 0); - writeChar(fd, 171); - writeChar(fd, custom); - writeChar(fd, row); - writeChar(fd, data); -} - - -/** - * ??? Set fans, valid on LIS2 devices only. ??? - * \param fd File handle to write to. - * \param fan1 Data for 1st fan. - * \param fan2 Data for 2nd fan. - * \param fan3 Data for 3rd fan. - * \param fan4 Data for 4th fan. - */ -static void setLIS2Fan(int fd, int fan1, int fan2, int fan3, int fan4) -{ - writeChar(fd, 0); - writeChar(fd, 174); - writeChar(fd, 0); - writeChar(fd, 0); - writeChar(fd, fan1); - writeChar(fd, 0); - writeChar(fd, fan2); - writeChar(fd, 0); - writeChar(fd, fan3); - writeChar(fd, 0); - writeChar(fd, fan4); - writeChar(fd, 0); - writeChar(fd, 0); -} - - -/** Move cursor to given character coordinates. - * \param fd File handle to write to. - * \param x Character column to set cursor to. - * \param y Character row to set cursor to. - */ -static void gotoXY(int fd, unsigned char x, unsigned char y) -{ - writeChar(fd, 0); - writeChar(fd, 161 + y); - writeChar(fd, x); - writeChar(fd, 167); -} - - -/** - * Write a character. - * \param fd File handle to write to. - * \param ch Character to write. - */ -static void writeChar(int fd, unsigned char code) -{ - write(fd, &code, 1); -} - - void lis2_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { static int mode = 0; @@ -182,22 +139,45 @@ static unsigned char rowNum = 0; if (flags == RS_DATA) { // RS_DATA: we have data if (mode == SETCHAR) { - // define row for custom char (reset mode to normal if illegal row) - if (rowNum < p->cellheight) - setLIS2CustomCharRow(p->fd, charNum, rowNum, ch); - else - mode = 0; + if (p->connectiontype == HD44780_CT_LIS2) { + if (rowNum < p->cellheight) + // define row for custom char + setLIS2CustomCharRow(p->fd, charNum, rowNum, ch); + else + mode = 0; // reset mode + } // increase row counter rowNum++; + + if (p->connectiontype == HD44780_CT_MPLAY) { + if (rowNum == p->cellheight) { + // set all custom chars + setMPlayCustomChars(p->fd, p->cc); + // give enough time for the commands to exec + p->hd44780_functions->uPause(p, 40); + + mode = 0; // reset mode + } + } } else { - // offset given char by one to avoid collisions with command prefix - // TODO: check if this is correct - if (ch < 7) - ch++; + if (p->connectiontype == HD44780_CT_LIS2) { + // offset given char by one to avoid collisions with command prefix + // TODO: check if this is correct + if (ch < 7) + ch++; + } + else { // p->connectiontype == HD44780_CT_MPLAY + // 0x00 is the command prefix so we can't use it. + // Luckily, there are 16 custom char positions & the + // second 8 are identical to the first 8 so we can + // just offset it + if (ch < NUM_CCs) + ch += NUM_CCs; + } - // simply write character byte + // simply write data/character byte write(p->fd, &ch, 1); } } @@ -214,23 +194,27 @@ static unsigned char rowNum = 0; else if ((ch & SETCHAR) != 0) { mode = SETCHAR; - // extract character to set from given info - charNum = (ch & ~SETCHAR) / 8; - - // offset it by one to avoid collisions with command prefix - // TODO: check if this is correct - charNum++; + if (p->connectiontype == HD44780_CT_LIS2) { + // extract character to set from given info + charNum = (ch & ~SETCHAR) / 8; - // restrict it to range [1, 7] - // TODO: check if this is correct - if (charNum == 8) - charNum = 7; + // offset it by one to avoid collisions with command prefix + // TODO: check if this is correct + charNum++; + + // restrict it to range [1, 7] + // TODO: check if this is correct + if (charNum == 8) + charNum = 7; + } + // MPlay devices don't need the char num; + // they always set all custom characters // reset row number rowNum = 0; } else - // simply write through instruction byte + // simply write instruction byte write(p->fd, &ch, 1); } } @@ -248,3 +232,165 @@ unsigned char lis2_HD44780_scankeypad(PrivateData *p) } +// hardware specific functions common to all device types + +/** + * Clear device screen. + * \param fd File handle to write to. + */ +static void clearScreen(int fd) +{ + writeChar(fd, 0); + writeChar(fd, 0xA0); +} + + +/** Move cursor to given character coordinates. + * \param fd File handle to write to. + * \param x Character column to set cursor to. + * \param y Character row to set cursor to. + */ +static void gotoXY(int fd, unsigned char x, unsigned char y) +{ + writeChar(fd, 0); + writeChar(fd, 0xA1 + y); + writeChar(fd, x); + writeChar(fd, 0xA7); +} + + +// hardware specific functions specific for a special device type + +/** + * Set a custom character, valid on MPlay devices only. + * \param fd File handle to write to. + * \param chars Pixel definition of all custom chars. + */ +static void setMPlayCustomChars(int fd, CGram *chars) +{ + // chars *must* be 8x8 + int i, row; + + writeChar(fd, 0); + writeChar(fd, 0xAD); + + for (i = 0; i < NUM_CCs; i++) { + for (row = 0; row < 8; row++) { // 8 == p->cellheight + writeChar(fd, chars[i].cache[row]); + } + } +} + + +/** + * Set one pixel row of a custom character, valid on LIS2 devices only. + * \param fd File handle to write to. + * \param custom Custom character to set (from 0 to 7). + * \param row Index of pixel row to set (from (0 [=top] to 7 [=bottom]). + * \param data Pixel data: 5 bit coding from 0 to 31 from right to left (16/8/4/2/1). + */ +static void setLIS2CustomCharRow(int fd, unsigned char custom, unsigned char row, unsigned char data) +{ + writeChar(fd, 0); + writeChar(fd, 0xAB); + writeChar(fd, custom); + writeChar(fd, row); + writeChar(fd, data); +} + + +/** + * Read temperatures, valid only on MPlay devices. + * \param fd File handle to read from. + * \param temps Pointer to pre-allocated array to store the temperatures. + * \param num Length of temperature array. + * \retval 0 Error. + * \retval 1 Temperatures read successfully. + */ +static char readMPlayTemps(int fd, int *temps, int num) +{ + unsigned char raw[num]; + int i; + + writeChar(fd, 0); + writeChar(fd, 0xAF); + + if (read(fd, raw, num) == num) { + for (i = 0; i < num; i++) + temps[i] = (int) raw[i] - 150; + return 1; + } + + return 0; +} + + +/** + * initialize fans, valid only on MPlay devices. + * \param fd File handle to write to. + */ +static void initMPlayFans(int fd) +{ + writeChar(fd, 0); + writeChar(fd, 0xA4); + writeChar(fd, 0x7D); +} + + +/** + * Set fans, valid on MPlay devices only. + * \param fd File handle to write to. + * \param fans Array holding fan information + * \param num Length of fan array. + */ +static void setMPlayFans(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]); +} + + +/** + * Set fans, valid on LIS2 devices only. ??? + * \param fd File handle to write to. + * \param fan1 Data for 1st fan. + * \param fan2 Data for 2nd fan. + * \param fan3 Data for 3rd fan. + * \param fan4 Data for 4th fan. + */ +static void setLIS2Fans(int fd, int fan1, int fan2, int fan3, int fan4) +{ + writeChar(fd, 0); + writeChar(fd, 0xAE); + writeChar(fd, 0); + writeChar(fd, 0); + writeChar(fd, fan1); + writeChar(fd, 0); + writeChar(fd, fan2); + writeChar(fd, 0); + writeChar(fd, fan3); + writeChar(fd, 0); + writeChar(fd, fan4); + writeChar(fd, 0); + writeChar(fd, 0); +} + + +// basic functions + +/** + * Write a character. + * \param fd File handle to write to. + * \param ch Character to write. + */ +static void writeChar(int fd, unsigned char code) +{ + write(fd, &code, 1); +} + +/* EOF */ diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h index 9026f03..382f96c 100644 --- a/server/drivers/hd44780-low.h +++ b/server/drivers/hd44780-low.h @@ -35,9 +35,10 @@ #define HD44780_CT_VDR_WAKEUP 9 #define HD44780_CT_PERTELIAN 10 #define HD44780_CT_LIS2 11 -#define HD44780_CT_BWCTUSB 12 -#define HD44780_CT_LCDUSB 13 -#define HD44780_CT_I2C 14 +#define HD44780_CT_MPLAY 12 +#define HD44780_CT_BWCTUSB 13 +#define HD44780_CT_LCDUSB 14 +#define HD44780_CT_I2C 15 // symbolic names for interface types #define IF_TYPE_UNKNOWN 0