diff -Naur graphlcd-base-0.1.5.dm140/graphlcd.conf graphlcd-base-0.1.5/graphlcd.conf --- graphlcd-base-0.1.5.dm140/graphlcd.conf 2007-02-25 20:41:31.000000000 +0300 +++ graphlcd-base-0.1.5/graphlcd.conf 2008-04-27 19:07:17.441096730 +0400 @@ -526,3 +526,23 @@ Invert=no Brightness=10 RefreshDisplay=1 + +######################################################################## + +[dm140gink] +# dm140gink driver +# This is an driver module for Futaba DM140-GINK VFD displays. +# The VFD is built-in in some HTPC cases and connected to a +# USB port. +# Default size: 112 x 16 +Driver=dm140gink +#Width=112 +#Height=16 +#UpsideDown=no + +# Invertion is not supported +#Invert=no + +# USB VendorID and ProductID +#Vendor=0x040b +#Product=0x7001 diff -Naur graphlcd-base-0.1.5.dm140/glcddrivers/dm140gink.c graphlcd-base-0.1.5/glcddrivers/dm140gink.c --- graphlcd-base-0.1.5.dm140/glcddrivers/dm140gink.c 1970-01-01 03:00:00.000000000 +0300 +++ graphlcd-base-0.1.5/glcddrivers/dm140gink.c 2008-04-27 19:23:12.061092848 +0400 @@ -0,0 +1,309 @@ +/* + * GraphLCD driver library + * + * framebuffer.h - framebuffer device + * Output goes to a framebuffer device + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Stephan Skrodzki + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "common.h" +#include "config.h" +#include "dm140gink.h" + + +namespace GLCD +{ + +cDriverDM140GINK::cDriverDM140GINK(cDriverConfig * config) +: config(config), + fd(-1), + framebuff(0) +{ + oldConfig = new cDriverConfig(*config); +} + +cDriverDM140GINK::~cDriverDM140GINK() +{ + delete oldConfig; +} + +/* hack - fix improper signed char handling - it's seeing 0x80 as a negative value*/ +#define VALUE_FILTER(_value) (_value>0x7F)?(__s32)(0xFFFFFF00 | _value):(_value) + +//************************************************************** +// FUNCTION: SendReport +// +// INPUT: +// int fd - file descriptor to the opened HID device +// const char *buf - Message to write +// size_t size - size of buf. +// +// OUTPUT: +// int err - result of the ioctl call (On success 0, On error -1) +// +// DESCRIPTION: This function will write the 'buf' to the opened +// HID device. Specifically, it updates the device's usage +// reference with the data and then sends a report to the HID. +//************************************************************** +int cDriverDM140GINK::SendReport(const char *cbuf, size_t size) +{ + const unsigned char *buf=reinterpret_cast(cbuf); + struct hiddev_report_info rinfo; + struct hiddev_usage_ref uref; + int err; + + //****************************************************** + // Initialize the usage Reference and mark it for OUTPUT + //****************************************************** + memset(&uref, 0, sizeof(uref)); + uref.report_type = HID_REPORT_TYPE_OUTPUT; + uref.report_id = 0; + uref.field_index = 0; + + //************************************************************** + // Fill in the information that we wish to set + //************************************************************** + uref.usage_code = 0xffa10005; //unused? + for(size_t i=0;iname.c_str(), i, (int)buf[i],size); + return err; + } + uref.usage_code = 0xffa10006; //unused? + } + + //************************************************************** + // HIDIOCSREPORT - struct hiddev_report_info (write) + // Instructs the kernel to SEND a report to the device. This + // report can be filled in by the user through HIDIOCSUSAGE calls + // (below) to fill in individual usage values in the report before + // sending the report in full to the device. + //************************************************************** + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.report_type = HID_REPORT_TYPE_OUTPUT; + rinfo.report_id = 0; + rinfo.num_fields = 0; + if((err = ioctl(fd, HIDIOCSREPORT, &rinfo)) < 0) + { + syslog(LOG_INFO, "%s: Error with sending the REPORT ioctl %d\n", config->name.c_str(), err); + } + + //****************************************************** + // All done, let's return what we did. + //****************************************************** + return err; +} + +int cDriverDM140GINK::Init() +{ + // default values + width = config->width; + if (width <= 0) + width = 112; + height = config->height; + if (height <= 0) + height = 16; + + vendor = 0x040b; + product = 0x7001; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Vendor") + vendor=config->GetInt(config->options[i].value); + if (config->options[i].name == "Product") + product=config->GetInt(config->options[i].value); + } + + //****************************************************** + // Loop through all the 16 HID ports/devices looking for + // one that matches our device. + //****************************************************** + const char *hiddev_prefix = "/dev/usb/hiddev"; /* in devfs */ + for(int i=0;i<16;i++) + { + char port[32]; + sprintf(port, "%s%d", hiddev_prefix, i); + if((fd = open(port,O_WRONLY))>=0) + { + struct hiddev_devinfo device_info; + ioctl(fd, HIDIOCGDEVINFO, &device_info); + + + // If we've found our device, no need to look further, time to stop searching + if(vendor==device_info.vendor && product==device_info.product) + { + //char name[256]; + //ioctl(fd, HIDIOCGNAME(sizeof(name)), name); + //name[sizeof(name)-1]='\0'; + //syslog(LOG_INFO, "%s: The device %s was opened successfully.\n", config->name.c_str(), name); + + break; // stop the for loop + } + close(fd); // Added by HL + fd=-1; + } + } + + if (-1 == fd) + { + syslog(LOG_ERR, "%s: Cannot open device 0x%x:0x%x.\n", config->name.c_str(), vendor, product); + return -1; + } + + //****************************************************** + // Initialize the internal report structures + //****************************************************** + if(ioctl(fd, HIDIOCINITREPORT,0)<0) + { + syslog(LOG_ERR, "%s: cannot init device.\n", config->name.c_str()); + return -1; + } + + //****************************************************** + // Set up the display to show graphics + //****************************************************** + const char panelCmd[] = {0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + const char iconCmd[] = {0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //icon command + const char iconoff[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //icon data + + SendReport(panelCmd, sizeof(panelCmd)); + SendReport(iconCmd, sizeof(iconCmd)); + SendReport(iconoff, sizeof(iconoff)); + + const char setup[] = {0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + SendReport(setup, sizeof(setup)); + + screensize = width * height / 8; + + // reserve another memory to draw into + framebuff = new char[screensize]; + if (!framebuff) + { + syslog(LOG_ERR, "%s: failed to alloc memory for device.\n", config->name.c_str()); + return -1; + } + + *oldConfig = *config; + + // clear display + Clear(); + Refresh(true); + + syslog(LOG_INFO, "%s: display initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverDM140GINK::DeInit() +{ + if (framebuff) + delete[] framebuff; + framebuff=NULL; + if (-1 != fd) + close(fd); + fd=-1; + return 0; +} + +int cDriverDM140GINK::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverDM140GINK::SetPixel(int x, int y) +{ + if (x >= width || y >= height) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + int offset = (y/8) * width + x; + char mask = (1 << (7 - (y%8))); + framebuff[offset] |= mask; +} + +void cDriverDM140GINK::Clear() +{ + memset(framebuff, 0, screensize); +} + +void cDriverDM140GINK::Set8Pixels(int x, int y, unsigned char data) +{ + x &= 0xFFF8; + + for (int n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverDM140GINK::Refresh(bool refreshAll) +{ + char packet[] = {0x1D, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + + SendReport(packet, sizeof(packet)); + + // Send the actual graphics + for(int i=0; i< screensize;i+=8) + { + // make sure we only send 8 bytes at a time + int size = (screensize - i); + size = (size > 8) ? 8 : size; + SendReport(framebuff+i, size); + } + + const char show[] = {0x01, 0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00}; + + SendReport(show, sizeof(show)); +} + +} // end of namespace diff -Naur graphlcd-base-0.1.5.dm140/glcddrivers/dm140gink.h graphlcd-base-0.1.5/glcddrivers/dm140gink.h --- graphlcd-base-0.1.5.dm140/glcddrivers/dm140gink.h 1970-01-01 03:00:00.000000000 +0300 +++ graphlcd-base-0.1.5/glcddrivers/dm140gink.h 2008-04-15 22:35:05.492092784 +0400 @@ -0,0 +1,57 @@ +/* + * GraphLCD driver library + * + * framebuffer.h - framebuffer device + * Output goes to a framebuffer device + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Stephan Skrodzki + */ + +#ifndef _GLCDDRIVERS_DM140GINK_H_ +#define _GLCDDRIVERS_DM140GINK_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverDM140GINK : public cDriver +{ +private: + cDriverConfig * config; + cDriverConfig * oldConfig; + + int fd; + + int vendor; + int product; + + char *framebuff; + + long int screensize; + + int SendReport(const char *buf, size_t size); + int CheckSetup(); + void SetPixel(int x, int y); + +public: + cDriverDM140GINK(cDriverConfig * config); + virtual ~cDriverDM140GINK(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -Naur graphlcd-base-0.1.5.dm140/glcddrivers/drivers.c graphlcd-base-0.1.5/glcddrivers/drivers.c --- graphlcd-base-0.1.5.dm140/glcddrivers/drivers.c 2007-02-25 20:41:31.000000000 +0300 +++ graphlcd-base-0.1.5/glcddrivers/drivers.c 2008-04-14 22:33:31.120130239 +0400 @@ -27,6 +27,7 @@ #include "avrctl.h" #include "network.h" #include "gu126x64D-K610A4.h" +#include "dm140gink.h" #include "serdisp.h" #include "g15daemon.h" @@ -50,6 +51,7 @@ {"avrctl", kDriverAvrCtl}, {"network", kDriverNetwork}, {"gu126x64D-K610A4", kDriverGU126X64D_K610A4}, + {"dm140gink", kDriverDM140GINK}, {"serdisp", kDriverSerDisp}, {"g15daemon", kDriverG15daemon}, {"", kDriverUnknown} @@ -104,6 +106,8 @@ return new cDriverNetwork(config); case kDriverGU126X64D_K610A4: return new cDriverGU126X64D_K610A4(config); + case kDriverDM140GINK: + return new cDriverDM140GINK(config); case kDriverSerDisp: return new cDriverSerDisp(config); case kDriverG15daemon: diff -Naur graphlcd-base-0.1.5.dm140/glcddrivers/drivers.h graphlcd-base-0.1.5/glcddrivers/drivers.h --- graphlcd-base-0.1.5.dm140/glcddrivers/drivers.h 2007-02-25 20:41:31.000000000 +0300 +++ graphlcd-base-0.1.5/glcddrivers/drivers.h 2008-04-14 22:31:20.548791356 +0400 @@ -39,6 +39,7 @@ kDriverAvrCtl = 13, kDriverNetwork = 14, kDriverGU126X64D_K610A4 = 15, + kDriverDM140GINK = 16, kDriverSerDisp = 100, kDriverG15daemon = 200 }; diff -Naur graphlcd-base-0.1.5.dm140/glcddrivers/Makefile graphlcd-base-0.1.5/glcddrivers/Makefile --- graphlcd-base-0.1.5.dm140/glcddrivers/Makefile 2007-02-25 20:41:31.000000000 +0300 +++ graphlcd-base-0.1.5/glcddrivers/Makefile 2008-04-14 22:16:08.572907767 +0400 @@ -14,7 +14,7 @@ LIBNAME = $(BASENAME).$(VERMAJOR).$(VERMINOR).$(VERMICRO) -OBJS = common.o config.o driver.o drivers.o port.o simlcd.o framebuffer.o gu140x32f.o gu256x64-372.o gu256x64-3900.o hd61830.o ks0108.o image.o sed1330.o sed1520.o t6963c.o noritake800.o serdisp.o avrctl.o g15daemon.o network.o gu126x64D-K610A4.o +OBJS = common.o config.o driver.o drivers.o port.o simlcd.o framebuffer.o gu140x32f.o gu256x64-372.o gu256x64-3900.o hd61830.o ks0108.o image.o sed1330.o sed1520.o t6963c.o noritake800.o serdisp.o avrctl.o g15daemon.o network.o gu126x64D-K610A4.o dm140gink.o HEADERS = config.h driver.h drivers.h