From joris at robijn.net Sun Feb 1 10:03:38 2009 From: joris at robijn.net (Joris Robijn) Date: Sun, 01 Feb 2009 11:03:38 +0100 Subject: [Lcdproc] Signalling in server/main.c In-Reply-To: <20090201095204.173470@gmx.net> References: <20090131141147.142390@gmx.net>, <49847716.3252.3A1226@joris.robijn.net>, <20090201095204.173470@gmx.net> Message-ID: <4985818A.1923.44AE998@joris.robijn.net> Hi Markus, What I mean is that the gained access to the port is lost at the fork. And after the drop_privs you are no longer root so you cannot get access anymore. That's why the order is like this. All related to the good ol' parallel devices. But I wouldn't rule out the possibility that there's a better way to accomplish the same. Joris On 1 Feb 2009 at 10:52, Markus Dolze wrote: > -------- Original-Nachricht -------- > > Datum: Sat, 31 Jan 2009 16:06:46 +0100 > > Von: "Joris Robijn" > > An: lcdproc at lists.omnipotent.net > > CC: bsdfan at nurfuerspam.de > > Betreff: Re: [Lcdproc] Signalling in server/main.c > > > > The whole thing is only necessary because fork() happens before the > > > drivers are initialized. It was after the initialization before 0.5.0. > > > > > > Does anybody of the former developers remember why fork() was moved > > before > > > the initialization? > > > > The server looses the priviledges on the parallel port after the fork. > > That's why the drop_privs is done after the fork and after the driver > > init. > > > > Hi Joris, > > that's a good point. But I am not concerned about drop_privs, but about > the fork(). > > Currently we do (simplyfied): > > CHAIN(e, parent_pid = daemonize()); > install_signal_handlers() > CHAIN(e, sock_init(bind_addr, bind_port)); > // ... Other inits > CHAIN(e, server_screen_init()); > CHAIN_END() > wave_to_parent(parent_pid); > drop_privs(user); > > > What about: > > CHAIN(e, sock_init(bind_addr, bind_port)); > // ... Other inits > CHAIN(e, server_screen_init()); > CHAIN(e, parent_pid = daemonize()); > install_signal_handlers() > CHAIN_END() > drop_privs(user); > > This way we may avoid the signalling at all. > > Regards, > Markus -- Joris Robijn Mobile: +31 6 288 41 964 From stewartputnam at comcast.net Mon Feb 2 00:25:02 2009 From: stewartputnam at comcast.net (stewartputnam at comcast.net) Date: Mon, 2 Feb 2009 00:25:02 +0000 (UTC) Subject: [Lcdproc] LCDd daemon hangs with USB Crystalfontz 634 LCD In-Reply-To: Message-ID: <1429105799.157921233534302448.JavaMail.root@sz0098a.emeryville.ca.mail.comcast.net> ----- Original Message ----- From: "Jeff Artz" To: "lcdproc" Sent: Wednesday, January 28, 2009 9:21:21 PM GMT -08:00 US/Canada Pacific Subject: Re: [Lcdproc] LCDd daemon hangs with USB Crystalfontz 634 LCD Does anybody have anything to suggest? It's now been a month since I posted my issue, but haven't even gotten a single response... :-( Jeff ----- Original Message ----- From: Jeff Artz To: lcdproc Sent: Sunday, December 28, 2008 11:07 PM Subject: [Lcdproc] LCDd daemon hangs with USB Crystalfontz 634 LCD So, to help troubleshoot, I changed the ReportLevel to 5, and here's what I get to stdout: [mythtv at mythbackend etc]$ sudo /sbin/service LCDd start Starting up LCDd: LCDd version 0.5.2 starting Built on Dec 22 2008, protocol version 0.3, API version 0.5 Using Configuration File: /home/mythtv/lcd/LCDd.conf Set report level to 5, output to stderr Server forking to background Listening for queries on 127.0.0.1:13666 screenlist_init() driver_load(name="CFontz", filename="/home/mythtv/lcd/CFontz.so") CFontz: using Device /dev/lcd Excuse me, this strikes me as too simple to be the answer. It popped out to me only after downloading the latest 634*.pdf form CF... I've used three CrystalFontz proucts, never a 634, and debian. All three use the /drivers/usb/serial/ftdi_sio kernel module (CONFIG_USB_SERIAL_FTDI_SIO=m). The device nodes appear as /dev/ttyUSB{n} This is always kernel, not distribution, dependent? Do any distributions customze that part of the kernel or create symlinks? Does the 634 use the same usb-serial converter as the 631, 633, & 635? usbcore: registered new driver usbserial drivers/usb/serial/usb-serial.c: USB Serial Driver core drivers/usb/serial/usb-serial.c: USB Serial support registered for FTDI USB Serial Device ftdi_sio 2-3:1.0: usb_probe_interface ftdi_sio 2-3:1.0: usb_probe_interface - got id ftdi_sio 2-3:1.0: FTDI USB Serial Device converter detected drivers/usb/serial/ftdi_sio.c: Detected FT8U232AM usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB0 usbcore: registered new driver ftdi_sio drivers/usb/serial/ftdi_sio.c: v1.4.3:USB FTDI Serial Converters Driver I've not used any module that appears as /dev/lcd. Um, er, I speculate that some modules do ? Some must (or used to ?) for that to appear as a default in [driver] sections of LCDd.conf, yes? If this is the cause of Jeff Artz hang: how many others give lcdproc a try but do not go as far as signing up to this list & submitting ReportLev=5 logs & resubmitting a mont later? Should /dev/lcd be replaced in some [driver] sectiens of the default / example / distribution LCDd.conf? -------------- next part -------------- An HTML attachment was scrubbed... URL: From andy at siliconlandmark.com Mon Feb 2 02:17:44 2009 From: andy at siliconlandmark.com (Andre Guibert de Bruet) Date: Sun, 1 Feb 2009 21:17:44 -0500 Subject: [Lcdproc] [PATCH] PicoLCD off-by-one causes last char to get chopped off in picoLCD_string() Message-ID: <75BFC17F-FBBB-4BA0-B610-D6FD12751992@siliconlandmark.com> Hi, I found the cause of the bug that causes the last character to get chopped off on the PicoLCD devices. It turns out it was an off-by-one error in picoLCD_string() in the section that enforces line length on the desired output. Please review and commit the attached patch. Cheers, Andy /* Andre Guibert de Bruet * 436f 6465 2070 6f65 742e 2042 6974 206a */ /* Managing Partner * 6f63 6b65 792e 2053 7973 4164 6d69 6e2e */ /* GSM: +1 734 846 8758 * 2055 4e49 5820 736c 6575 7468 2e00 0000 */ /* WWW: siliconlandmark.com * C/C++, Java, Perl, PHP, SQL, XHTML, XML */ -------------- next part -------------- A non-text attachment was scrubbed... Name: picolcd.offbyone.patch Type: application/octet-stream Size: 634 bytes Desc: not available URL: -------------- next part -------------- From sascha.zielinski at gmx.de Mon Feb 2 19:58:35 2009 From: sascha.zielinski at gmx.de (Sascha) Date: Mon, 2 Feb 2009 20:58:35 +0100 Subject: [Lcdproc] HD44780 40x4 with Backlight and winamp wiring In-Reply-To: <20090201094412.173500@gmx.net> References: <9185341920196262063@unknownmsgid> <200901311935.34256.sascha.zielinski@gmx.de> <20090201094412.173500@gmx.net> Message-ID: <200902022058.35436.sascha.zielinski@gmx.de> > > HI,, your Patch works fine I successfully patched and compiled LCDproc > > from > > CVS. My Display is working now. > > > > Am I right that there's no solution for the swithchable backlight in a > > 40x4 > > LCD at this time? I would love to get that working. Is it possible to > > make the > > BL Pin adressable like in lcdtime? > > > > Sascha Zielinski > > Hi, > > there is currently no configuration setting for this. If you do not have > the extra output latch, you can modify the winamp driver to use its pin for > the backlight. > > In hd44780-winamp.c change line 194 from > p->backlight_bit = (state?0:nSEL); > to > p->backlight_bit = (state?0:LF); > > For now you will have to do this whenever you update lcdproc. > > You need to modify your display connections like this: > 1. Connect the backlight transistor to parallel port pin 14 (LF) > 2. Connect the diplay's pin 10 (RW) to ground. > > Additionally you should put "OutputPort=no" in you LCDd.conf. > > Regards > Markus Hi, today I connected LCD Pin 10 (RW) to GND and The BL Pin to Pin 14. I tried the change you mentioned with and without your previosly Patch(I guess without would be right?). I double checked all wire connections, but my LCD shows only the first controller (2 lines on top) and the Backlight doesn't light up. I also tried the three options in the menu(off, on, controlable by LCDd-Clients?), but nothing has changed. Thx for your Help so far. Sascha Zielinski From bsdfan at nurfuerspam.de Wed Feb 4 07:18:33 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Wed, 04 Feb 2009 08:18:33 +0100 Subject: [Lcdproc] [PATCH] FreeBSD's new USB stack support (configure.in changes, testing needed) In-Reply-To: <90B881CB-06A2-4436-8F65-630309EC5279@siliconlandmark.com> References: <90B881CB-06A2-4436-8F65-630309EC5279@siliconlandmark.com> Message-ID: <49894149.7020502@nurfuerspam.de> Andre Guibert de Bruet wrote: > Hi, > > I have attached a patch that extends LCDproc's USB support, and allows > for its use on the upcoming FreeBSD 8.0 (Presently 8-CURRENT). > > This patch changes configure.in as well as all of LCDproc's USB > drivers and though I have made every effort to not introduce > side-effects, it needs wide-scale testing. For users of non-FreeBSD > systems, this patch should not change anything. I have verified this > statement with OSX, but I have not tested against any flavor of Linux > (I suspect that it should "just work"). > > For pre-8.0-CURRENT FreeBSD users, the absence of the new USB's > stack's headers keeps the present dependance on libusb. > > Let me know if this patch works or breaks anything for you. Hello, the patch does not work for me. I took the change to install FreeBSD 200812 snapshot (with old usb) and installed the lcdproc port. Everything looked fine then. After that I deinstalled lcdproc and libusb and rebuilt the kernel with USB2 support and rebuild lcdproc-current with your patch. While the patch correctly detects the libusb20_compat01 header, the configure script uses pkg-config to detect whether libusb (SF) is installed or not and enables / disables drivers accordingly. As I had no libusb installed (I thought it shall use the new FreeBSD's one) all drivers using USB were still disabled. See this excerpt from configure output (note that the FreeBSD lcdproc port currently does not use libftdi, I just left it in) ... checking if libusb support has been enabled... yes checking for pkg-config... /usr/local/bin/pkg-config checking pkg-config is at least version 0.9.0... yes checking for LIBUSB... no checking for libusb20.h... yes checking for libusb20_compat01.h... yes checking if libftdi support has been enabled... yes checking for LIBFTDI... no configure: checking which drivers to compile... configure: WARNING: The i2500vfd driver needs the ftdi library configure: WARNING: The IOWarrior driver needs the libusb library. configure: WARNING: The lis driver needs the ftdi library configure: WARNING: The picolcd driver needs the libusb library. configure: WARNING: The shuttleVFD driver needs the libusb library. ... As you can see, picolcd, shuttleVFD and IOWarrior are not enabled. Additionally all hd44780- drivers using libusb (bwct, lcd2usb, ...) are not enabled. I would like to discuss if is makes sense to be able to disable and enable USB support on FreeBSD 8 like it is now possible for lcdproc with libusb. Regards Markus From andy at siliconlandmark.com Wed Feb 4 22:05:34 2009 From: andy at siliconlandmark.com (Andre Guibert de Bruet) Date: Wed, 4 Feb 2009 17:05:34 -0500 Subject: [Lcdproc] [PATCH] FreeBSD's new USB stack support (configure.in changes, testing needed) In-Reply-To: <49894149.7020502@nurfuerspam.de> References: <90B881CB-06A2-4436-8F65-630309EC5279@siliconlandmark.com> <49894149.7020502@nurfuerspam.de> Message-ID: <6635478E-2C8C-4EB5-88A4-6F020B991CF8@siliconlandmark.com> On Feb 4, 2009, at 2:18 AM, Markus Dolze wrote: > Andre Guibert de Bruet wrote: >> >> I have attached a patch that extends LCDproc's USB support, and >> allows for its use on the upcoming FreeBSD 8.0 (Presently 8-CURRENT). >> >> This patch changes configure.in as well as all of LCDproc's USB >> drivers and though I have made every effort to not introduce side- >> effects, it needs wide-scale testing. For users of non-FreeBSD >> systems, this patch should not change anything. I have verified >> this statement with OSX, but I have not tested against any flavor >> of Linux (I suspect that it should "just work"). >> >> For pre-8.0-CURRENT FreeBSD users, the absence of the new USB's >> stack's headers keeps the present dependance on libusb. >> >> Let me know if this patch works or breaks anything for you. > > the patch does not work for me. I took the change to install FreeBSD > 200812 snapshot (with old usb) and installed the lcdproc port. > Everything looked fine then. After that I deinstalled lcdproc and > libusb and rebuilt the kernel with USB2 support and rebuild lcdproc- > current with your patch. > > While the patch correctly detects the libusb20_compat01 header, the > configure script uses pkg-config to detect whether libusb (SF) is > installed or not and enables / disables drivers accordingly. Mea culpa. To get everything to work, I had to hack up a /usr/local/ libdata/pkgconfig/libusb.pc file that looked like: # -- 8< -- # Package Information for pkg-config prefix=/usr/ exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: libusb Description: libusb 2.0 Version: 2.0 Libs: -L${libdir} -lusb20 Cflags: -I${includedir} # -- 8< -- LCDproc can't be the only piece of software using pkg-config to detect libusb presence. I realize that their new USB stack isn't the default yet (From the list feedback, that should happen real soon), so libusb from ports is still the way to go... > As I had no libusb installed (I thought it shall use the new > FreeBSD's one) all drivers using USB were still disabled. See this > excerpt from configure output (note that the FreeBSD lcdproc port > currently does not use libftdi, I just left it in) > > ... > checking if libusb support has been enabled... yes > checking for pkg-config... /usr/local/bin/pkg-config > checking pkg-config is at least version 0.9.0... yes > checking for LIBUSB... no > checking for libusb20.h... yes > checking for libusb20_compat01.h... yes > checking if libftdi support has been enabled... yes > checking for LIBFTDI... no > configure: checking which drivers to compile... > configure: WARNING: The i2500vfd driver needs the ftdi library > configure: WARNING: The IOWarrior driver needs the libusb library. > configure: WARNING: The lis driver needs the ftdi library > configure: WARNING: The picolcd driver needs the libusb library. > configure: WARNING: The shuttleVFD driver needs the libusb library. > ... > > As you can see, picolcd, shuttleVFD and IOWarrior are not enabled. > Additionally all hd44780- drivers using libusb (bwct, lcd2usb, ...) > are not enabled. > > I would like to discuss if is makes sense to be able to disable and > enable USB support on FreeBSD 8 like it is now possible for lcdproc > with libusb. I am open for suggestions. I can make configure.in grok a --enable- freebsd8-libusb (Or whatever) option or hack the libusb check to perform some scary voodoo that will support the target. Andy /* Andre Guibert de Bruet * 436f 6465 2070 6f65 742e 2042 6974 206a */ /* Managing Partner * 6f63 6b65 792e 2053 7973 4164 6d69 6e2e */ /* GSM: +1 734 846 8758 * 2055 4e49 5820 736c 6575 7468 2e00 0000 */ /* WWW: siliconlandmark.com * C/C++, Java, Perl, PHP, SQL, XHTML, XML */ From bsdfan at nurfuerspam.de Thu Feb 5 07:10:12 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Thu, 05 Feb 2009 08:10:12 +0100 Subject: [Lcdproc] [PATCH] PicoLCD off-by-one causes last char to get chopped off in picoLCD_string() In-Reply-To: <75BFC17F-FBBB-4BA0-B610-D6FD12751992@siliconlandmark.com> References: <75BFC17F-FBBB-4BA0-B610-D6FD12751992@siliconlandmark.com> Message-ID: <498A90D4.8050805@nurfuerspam.de> Andre Guibert de Bruet wrote: > Hi, > > I found the cause of the bug that causes the last character to get > chopped off on the PicoLCD devices. It turns out it was an off-by-one > error in picoLCD_string() in the section that enforces line length on > the desired output. > > Please review and commit the attached patch. Thank you for spotting this. Although I cannot test your patch, I tested picoLCD_string() separately and created a slightly different patch. Imagine you want to write the text "test" two times at position 5 on a 1x12 display. The result should be "1234testtest". width = 12, x = 5, len = 8; current code: if (len + x > p->width) len = p->width - x; with values: if (8 + 5 > 12) // true len = 12 - 5; // = 7, wrong It is not only the length that is calculated incorrectly, but the condition triggers incorrectly as well. If you apply my patch, the 1-to-0 conversion is done before, resulting in: x--; // 4 if ((8 + 4) > 12) //false, len stays 8 Suppose we want to write the same text twice at position 6, resulting in "12345testtes": width = 12, x = 6, len = 8; x--; // 5 if ((8 + 5) > 12) // true len = 12 - 5; // = 7, correct Please test if the attached patch works for you. Regards Markus -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: picolcd.offbyone-2.diff URL: From listen at sowas.org Thu Feb 5 13:22:21 2009 From: listen at sowas.org (Dirk Mueller) Date: Thu, 5 Feb 2009 14:22:21 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 Message-ID: <200902051422.21195.listen@sowas.org> Hi, I own a usb lcd conector from www.usblcd.de. Lcdproc supported this type of lcd connector since version 0.4.4. Today I tried lcdproc 0.5.2 and I was not able to get it running. Looks like the usblcd code was removed from version 0.5.0. There is no information about this in the release notes. Am I right, is it not longer supported? Regards, Dirk From bsdfan at nurfuerspam.de Thu Feb 5 18:39:22 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Thu, 05 Feb 2009 19:39:22 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <200902051422.21195.listen@sowas.org> References: <200902051422.21195.listen@sowas.org> Message-ID: <498B325A.3050500@nurfuerspam.de> Dirk Mueller wrote: > Hi, > > I own a usb lcd conector from www.usblcd.de. > Lcdproc supported this type of lcd connector since version 0.4.4. > > Today I tried lcdproc 0.5.2 and I was not able to get it running. Looks like > the usblcd code was removed from version 0.5.0. > > There is no information about this in the release notes. Am I right, is it not > longer supported? > > Regards, > > Dirk > Hello Dirk, according to CVS this driver (actually it was a connection type of the hd44780 driver) has been removed 6 years ago and was only available in the 0.4.4 and 0.4.5 releases. Regards Markus From listen at sowas.org Thu Feb 5 19:30:49 2009 From: listen at sowas.org (Dirk Mueller) Date: Thu, 5 Feb 2009 20:30:49 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <498B325A.3050500@nurfuerspam.de> References: <200902051422.21195.listen@sowas.org> <498B325A.3050500@nurfuerspam.de> Message-ID: <200902052030.50105.listen@sowas.org> Hi Markus, > according to CVS this driver (actually it was a connection type of the > hd44780 driver) has been removed 6 years ago and was only available in > the 0.4.4 and 0.4.5 releases. ok, like I assumed. Do you know why it has been removed? Thanks Dirk P.S. I have 0.4.5 running From Mark.Vallevand at UNISYS.com Thu Feb 5 21:27:57 2009 From: Mark.Vallevand at UNISYS.com (Vallevand, Mark K) Date: Thu, 5 Feb 2009 15:27:57 -0600 Subject: [Lcdproc] Big bug in server/main.c In-Reply-To: References: Message-ID: Any comments on this bug? I'd hate to see it get lost. Regards. Mark K Vallevand "I got free checking at Bear Stearns!" THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. ________________________________ From: lcdproc-bounces at lists.omnipotent.net [mailto:lcdproc-bounces at lists.omnipotent.net] On Behalf Of Vallevand, Mark K Sent: Thursday, January 29, 2009 9:06 AM To: lcdproc at lists.omnipotent.net Subject: [Lcdproc] Big bug in server/main.c While testing with my embedded Linux and also on SUSE 11 Linux, I found that if time goes backwards, LCDd will stall until time catches up. Try it. Set the time back 2 minutes. For 2 minutes LCDd does nothing. Here's the fix. server/main.c 813c813 < if ((t_diff + 1) > (LONG_MAX / 1e6)) { --- > if ( ((t_diff + 1) > (LONG_MAX / 1e6)) || (t_diff<0) ) { If someone has the time, this really should be rewritten to use something not based on the time and date of Linux. But, this fix suffices and we are now using it. Regards. Mark K Vallevand "I got free checking at Bear Stearns!" THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsdfan at nurfuerspam.de Fri Feb 6 07:13:59 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Fri, 06 Feb 2009 08:13:59 +0100 Subject: [Lcdproc] Big bug in server/main.c In-Reply-To: References: Message-ID: <20090206071359.97450@gmx.net> -------- Original-Nachricht -------- > Datum: Thu, 5 Feb 2009 15:27:57 -0600 > Von: "Vallevand, Mark K" > An: lcdproc at lists.omnipotent.net > Betreff: Re: [Lcdproc] Big bug in server/main.c > Any comments on this bug? I'd hate to see it get lost. > I tested it already and found no problems. Despite that it's pending. You asked if someone would like to write some time independent code. This will likely not happen as LCDd tries to do its best to create a fixed display refresh rate. This requires timing. Regards Markus From bsdfan at nurfuerspam.de Fri Feb 6 10:50:34 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Fri, 06 Feb 2009 11:50:34 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <200902052030.50105.listen@sowas.org> References: <200902051422.21195.listen@sowas.org> <498B325A.3050500@nurfuerspam.de> <200902052030.50105.listen@sowas.org> Message-ID: <20090206105034.136120@gmx.net> -------- Original-Nachricht -------- > Datum: Thu, 5 Feb 2009 20:30:49 +0100 > Von: Dirk Mueller > An: lcdproc at lists.omnipotent.net > Betreff: Re: [Lcdproc] usblcd with lcdproc >= 0.5 > Hi Markus, > > > according to CVS this driver (actually it was a connection type of the > > hd44780 driver) has been removed 6 years ago and was only available in > > the 0.4.4 and 0.4.5 releases. > > ok, like I assumed. > Do you know why it has been removed? > > Thanks > > Dirk > > P.S. I have 0.4.5 running > Hello Dirk, after reading more change logs I think it might be an accident. The driver was added to the stable-0-4-4 branch. At that time, the 0.5 line already existed, but the driver was never added to it. I tried to look up some information in www.usblcd.de but found that all content has been removed. The internet archive shows this happened mid of 2007. So I guess these devices are not sold anymore. It should not be that hard to resurrect the driver for 0.5. But maybe someone involved with 0.4 can comment on that? BTW: The 'anslcd' driver shares the same fate. Regards Markus From listen at sowas.org Fri Feb 6 11:49:17 2009 From: listen at sowas.org (Dirk Mueller) Date: Fri, 6 Feb 2009 12:49:17 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <20090206105034.136120@gmx.net> References: <200902051422.21195.listen@sowas.org> <200902052030.50105.listen@sowas.org> <20090206105034.136120@gmx.net> Message-ID: <200902061249.17913.listen@sowas.org> Hi Markus, > after reading more change logs I think it might be an accident. The driver > was added to the stable-0-4-4 branch. At that time, the 0.5 line already > existed, but the driver was never added to it. as far as I know this work was done by the developer of the usb port itself. His name is Robin Adams. > I tried to look up some information in www.usblcd.de but found that all > content has been removed. The internet archive shows this happened mid of > 2007. So I guess these devices are not sold anymore. Looks like only a few people bought this connector. > It should not be that hard to resurrect the driver for 0.5. sounds good :-) Thanks for your help Dirk From Mark.Vallevand at UNISYS.com Fri Feb 6 15:07:31 2009 From: Mark.Vallevand at UNISYS.com (Vallevand, Mark K) Date: Fri, 6 Feb 2009 09:07:31 -0600 Subject: [Lcdproc] Big bug in server/main.c In-Reply-To: <20090206071359.97450@gmx.net> References: <20090206071359.97450@gmx.net> Message-ID: Thanks. I've tried it on two different flavors of Linux with completely different hardware. Time goes backwards, LCDd stalls. It probably is different on other OSes. For us, it was really serious. When LCDd stalled it cascaded into a series of errors that took lots of time to figure out. Thanks again. Regards. Mark K Vallevand "I got free checking at Bear Stearns!" THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. -----Original Message----- From: lcdproc-bounces at lists.omnipotent.net [mailto:lcdproc-bounces at lists.omnipotent.net] On Behalf Of Markus Dolze Sent: Friday, February 06, 2009 1:14 AM To: Vallevand, Mark K; lcdproc at lists.omnipotent.net Subject: Re: [Lcdproc] Big bug in server/main.c -------- Original-Nachricht -------- > Datum: Thu, 5 Feb 2009 15:27:57 -0600 > Von: "Vallevand, Mark K" > An: lcdproc at lists.omnipotent.net > Betreff: Re: [Lcdproc] Big bug in server/main.c > Any comments on this bug? I'd hate to see it get lost. > I tested it already and found no problems. Despite that it's pending. You asked if someone would like to write some time independent code. This will likely not happen as LCDd tries to do its best to create a fixed display refresh rate. This requires timing. Regards Markus _______________________________________________ LCDproc mailing list LCDproc at lists.omnipotent.net http://lists.omnipotent.net/mailman/listinfo/lcdproc From andy at siliconlandmark.com Fri Feb 6 16:08:19 2009 From: andy at siliconlandmark.com (Andre Guibert de Bruet) Date: Fri, 6 Feb 2009 11:08:19 -0500 Subject: [Lcdproc] Big bug in server/main.c In-Reply-To: References: <20090206071359.97450@gmx.net> Message-ID: <2932C589-B9B5-494B-89D2-864B5DDE7F6E@siliconlandmark.com> On Feb 6, 2009, at 10:07 AM, Vallevand, Mark K wrote: > I've tried it on two different flavors of Linux with completely > different hardware. Time goes backwards, LCDd stalls. It probably is > different on other OSes. For us, it was really serious. When LCDd > stalled it cascaded into a series of errors that took lots of time to > figure out. Your patch appears to address this particular issue. What is worrisome about the scenario that you have brought forward is that time generally never runs backwards, unless you use something other than ntpd to adjust the hardware clock (ntpd skews the clock). Is the sporadic availability of a "reliable" time source (Such as an NTP server or a user keying in "current time") an inherent integration constraint? Cheers, Andy /* Andre Guibert de Bruet * 436f 6465 2070 6f65 742e 2042 6974 206a */ /* Managing Partner * 6f63 6b65 792e 2053 7973 4164 6d69 6e2e */ /* GSM: +1 734 846 8758 * 2055 4e49 5820 736c 6575 7468 2e00 0000 */ /* WWW: siliconlandmark.com * C/C++, Java, Perl, PHP, SQL, XHTML, XML */ From Mark.Vallevand at UNISYS.com Fri Feb 6 17:10:36 2009 From: Mark.Vallevand at UNISYS.com (Vallevand, Mark K) Date: Fri, 6 Feb 2009 11:10:36 -0600 Subject: [Lcdproc] Big bug in server/main.c In-Reply-To: <2932C589-B9B5-494B-89D2-864B5DDE7F6E@siliconlandmark.com> References: <20090206071359.97450@gmx.net> <2932C589-B9B5-494B-89D2-864B5DDE7F6E@siliconlandmark.com> Message-ID: We are using lcdproc on an embedded Linux system. Lots of 'normal' things just aren't there. Using ntpd or any other software to skew time can't be done. Our time must be sync'd to the time in an external source and our software just sets that time into Linux at a certain point in our processing. We just use the time for logging and certainly don't code to use the current time for any measurements. I was surprised that lcdproc used the time in this way. I expected something like clock(), but perhaps there are reasons for doing it as its done. I'm just glad I found it. The serious issue wasn't LCDd stalling as much as the way sockets was working. In some cases the recvfrom() function generates a signal when a shutdown() is done from the other end. We didn't handle the signal. The default action for that particular signal was to terminate the program. So, one of our programs terminated when LCDd woke up and shutdown() the socket. And, while time was 'catching up' the LCD screens and menu system didn't respond. Since our LCD isn't regularly used, no one cared much about that. But, when one of our programs crashed, we stopped doing our function and that got lots of attention. Regards. Mark K Vallevand "I got free checking at Bear Stearns!" THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. -----Original Message----- From: Andre Guibert de Bruet [mailto:andy at siliconlandmark.com] Sent: Friday, February 06, 2009 10:08 AM To: Vallevand, Mark K Cc: lcdproc at lists.omnipotent.net Subject: Re: [Lcdproc] Big bug in server/main.c On Feb 6, 2009, at 10:07 AM, Vallevand, Mark K wrote: > I've tried it on two different flavors of Linux with completely > different hardware. Time goes backwards, LCDd stalls. It probably is > different on other OSes. For us, it was really serious. When LCDd > stalled it cascaded into a series of errors that took lots of time to > figure out. Your patch appears to address this particular issue. What is worrisome about the scenario that you have brought forward is that time generally never runs backwards, unless you use something other than ntpd to adjust the hardware clock (ntpd skews the clock). Is the sporadic availability of a "reliable" time source (Such as an NTP server or a user keying in "current time") an inherent integration constraint? Cheers, Andy /* Andre Guibert de Bruet * 436f 6465 2070 6f65 742e 2042 6974 206a */ /* Managing Partner * 6f63 6b65 792e 2053 7973 4164 6d69 6e2e */ /* GSM: +1 734 846 8758 * 2055 4e49 5820 736c 6575 7468 2e00 0000 */ /* WWW: siliconlandmark.com * C/C++, Java, Perl, PHP, SQL, XHTML, XML */ From listen at sowas.org Sat Feb 7 15:47:24 2009 From: listen at sowas.org (Dirk Mueller) Date: Sat, 7 Feb 2009 16:47:24 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <20090207104033.190730@gmx.net> References: <200902051422.21195.listen@sowas.org> <200902061249.17913.listen@sowas.org> <20090207104033.190730@gmx.net> Message-ID: <200902071647.24181.listen@sowas.org> Hi Markus, > attached you will find the usblcd driver modified for the cvs version of > lcdproc. > > The patch compiles, but I cannot test with a real display. Therefore I > appreciate your help. Please report back if the driver works for you. thanks a lot for the patch. I just tested it and I have now a working version of LCDproc 0.5dev with usblcd. Do need more information before applying this patch to the current version? Best regards Dirk From bsdfan at nurfuerspam.de Sat Feb 7 21:54:41 2009 From: bsdfan at nurfuerspam.de (Markus Dolze) Date: Sat, 07 Feb 2009 22:54:41 +0100 Subject: [Lcdproc] usblcd with lcdproc >= 0.5 In-Reply-To: <200902071647.24181.listen@sowas.org> References: <200902051422.21195.listen@sowas.org> <200902061249.17913.listen@sowas.org> <20090207104033.190730@gmx.net> <200902071647.24181.listen@sowas.org> Message-ID: <20090207215441.114770@gmx.net> -------- Original-Nachricht -------- > Datum: Sat, 7 Feb 2009 16:47:24 +0100 > Von: Dirk Mueller > An: lcdproc at lists.omnipotent.net > Betreff: Re: [Lcdproc] usblcd with lcdproc >= 0.5 > Hi Markus, > > > attached you will find the usblcd driver modified for the cvs version of > > lcdproc. > > > > The patch compiles, but I cannot test with a real display. Therefore I > > appreciate your help. Please report back if the driver works for you. > > thanks a lot for the patch. I just tested it and I have now a working > version > of LCDproc 0.5dev with usblcd. This is good news. > > Do need more information before applying this patch to the current > version? > I will submit it for review to the mailing list within the next days. But I have to update the documentation before. Regards, Markus From ethan.dicks at gmail.com Sat Feb 7 23:27:05 2009 From: ethan.dicks at gmail.com (Ethan Dicks) Date: Sat, 7 Feb 2009 18:27:05 -0500 Subject: [Lcdproc] New drivers for Hyundai HG12603 / JW-002 24x8 Message-ID: All, I have my new JW-002 driver code cleaned up to the point where I want to submit a first cut. For those that don't happen to have one of these, it appears to be originally from an AT&T/Lucent telephone product, but gained fame about 5-6 years ago as an inexpensive large-format textual display sold as a bare surplus item, or as an attachment to homemade MP3 player, the PJRC. The attached driver handles the basic 24x8 display formatting, the built-in LED as an "output", hbars, vbars, the optional 12-key keypad, and bignums. The display itself is implemented with a lot of local RAM and a graphic (KS107) controller, so it can, in effect, have as many user-definable characters as desired. I've implemented the driver with 28 defined user-definable characters to work with, for an as-yet-unposted patch to the bignum library to give this display a much smoother bignum implementation than is possible with 7-8 user definable characters (such as any HD44780-based display). Down the road, I'd like to add code to this driver to allow it to be used as 8x24 _and_ 24x8 (portrait mode and landscape mode), but if I don't get something out now, who knows when I'll get things "done" enough to post. Here's a few links for the curious: I doubt anyone else will be able to test this, but if you _do_ have a JW-002 display, give it a whirl. If a display this size is appealing, I have one or two spares I could sell, or you could buy a complete display with keypad and replacement firmware from the PJRC links above. I am attaching patches against a recent CVS HEAD fetch. It's been a while since I've submitted code for an entire driver, so please let me know if I've forgotten anything, and I can submit what is required. -ethan -------------- next part -------------- /* This is the LCDproc driver for Hyundai HG12603A equipped with PJRC firmware (http://www.pjrc.com/tech/mp3/pushbutton_info.html) The HG12603(A) is a 2"x4" LCD panel with a Samsung KS107B controller, driven by an on-board 8051-family microcontroller. Normally, the KS107B would make this a graphical LCD, but the actual pixels on the glass are diced up into 8 lines of 24 5x7 character areas. This LCD module seems to have originally been used in some sort of AT&T telephone product, but has been available for a number of years in the surplus channel, typically selling for between $20 and $50, depending on quantity and if it was being sold as a bare module or with the necessary circuitry to interface to a host machine. The most visible use of this LCD module has been the PJRC MP3 player (http://www.pjrc.com/tech/mp3/index.html). The original AT&T firmware was severely limited as to what it could do. Paul Stoffregen of PJRC has made replacement firmware available in the public domain. Owners of "stock" HG12603A modules (also sold as "JW-002" modules) can either download Paul's firmware from his site and burn their own chips, or more simply, purchase a chip ready to drop into a stock display. The PJRC firmware takes care of the command set, but the module itself needs a few external components added to it for easy PC use. The HG12603A requires a Vee of about -7V for LCD contrast. In addition, the serial interface to the 8051 microcontroller is at TTL levels (0 and +5VDC), not RS-232 levels (+/- 3-12VDC). Fortunately, it's easy to tap off the charge pump caps of an ordinary MAX232A chip for Vee, making the interface a single chip and a few caps. As a bonus. the PJRC software uses the 8051 I/O lines present on the 17-pin connector to scan a 3x4 keypad matrix. Paul has also made the schematics to a level shifter/Vee supply/keypad available on his website - http://www.pjrc.com/tech/mp3/pushbutton_info.html If you have your own HG12603A/JW-002 module, you can roll your own, or, as of this writing, it's still possible to buy a ready-to-plug-in LCD module *with* a "pushbutton adaptor board" and cables directly from PJRC - http://www.pjrc.com/store/mp3_display.html While the PJRC display was really designed to work hand-in-hand with the PJRC MP3 player, an intelligent, serially interfaced, 8x24 character display with 12 buttons is a luxury compared to the standard LCDproc 4x20 display with 0-5 buttons. Applicable external links: - http://www.pjrc.com/tech/mp3/index.html - http://www.pjrc.com/store/mp3_display.html - http://www.pjrc.com/tech/mp3/firmware.html - http://www.pjrc.com/tech/mp3/lcd_protocol.html Copyright (C) 2008, 2009, Ethan Dicks This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "lcd.h" #include "lcd_lib.h" #include "jw002.h" #include "adv_bignum.h" #include "report.h" /* PJRC firmware supports an optional 3x4 keypad matrix */ #define MAX_KEY_MAP 12 // Don't forget to define key mappings in LCDd.conf: KeyMap_A=Enter, ... // otherwise you will not get your keypad working. /* * The JW-002 driver depends on the four standard firmware fonts * to implement vbar, hbar, and bignum. None of the standard fonts * happen to have the standard LCDproc heartbeat chars, so we define * those ourselves. * * For the same reason, we don't use the hardware clear but rather * empty the internal frame buffer. The frame buffer holds all * the requested changes until the server asks us to flush the * changes to the display. This also permits us to do an * incremental update and reduce the number of characters to be * sent to the display across the serial link. * * In order to display graphic widgets, we define and use our own * custom characters. To avoid multiple definitions of the same * custom characters, we use a caching mechanism that remembers * what is currently defined. In order to avoid always redefining * the same custom character at the beginning of the table, we * rotate the beginning of the table. This is supposed to reduce * the number of character redefinitions and make the caching more * effective. The overall goal is to reduce the number of * characters sent to the display. * * (TODO: a totally custom RAM-resident font that gets loaded once) */ /* Constants for userdefchar_mode */ #define NUM_CCs 28 // max. number of custom characters #define CC_OFFSET 192 // first custom char typedef enum { standard, /* only char 0 is used for heartbeat */ vbar, /* vertical bars */ hbar, /* horizontal bars */ custom, /* custom settings */ bignum, /* big numbers */ bigchar /* big characters */ } CGmode; typedef struct { int fd; /* The LCD file descriptor */ /* dimensions */ int width, height; int cellwidth, cellheight; int xoff, yoff; /* framebuffer and buffer for old LCD contents */ unsigned char *framebuf; unsigned char *backingstore; /* defineable characters */ CGmode ccmode; int font; /* font number */ int output_state; /* static data from jw002_output */ int contrast; /* static data from set/get_contrast */ int brightness; int offbrightness; /* the keymap */ char *keymap[MAX_KEY_MAP]; int keys; int keypad_test_mode; char info[255]; /* static data from jw002_get_info */ } PrivateData; /* Vars for the server core */ MODULE_EXPORT char *api_version = API_VERSION; MODULE_EXPORT int stay_in_foreground = 0; MODULE_EXPORT int supports_multiple = 1; MODULE_EXPORT char *symbol_prefix = "jw002_"; static void jw002_hardware_clear(Driver *drvthis); static void jw002_linewrap(Driver *drvthis, int on); static void jw002_autoscroll(Driver *drvthis, int on); //static void jw002_cursorblink(Driver *drvthis, int on); static void jw002_cursor_goto(Driver *drvthis, int x, int y); /* Parse one key from the configfile */ static char jw002_parse_keypad_setting (Driver *drvthis, char *keyname, char default_value) { char return_val = 0; const char *s; char buf[255]; s = drvthis->config_get_string(drvthis->name, keyname, 0, NULL); if (s != NULL) { strncpy(buf, s, sizeof(buf)); buf[sizeof(buf)-1] = '\0'; return_val = buf[0]; } else { return_val = default_value; } return return_val; } /** * Initialize the driver. * \param drvthis Pointer to driver structure. * \retval 0 Success. * \retval <0 Error. */ MODULE_EXPORT int jw002_init (Driver *drvthis) { struct termios portset; char device[256] = DEFAULT_DEVICE; int speed = DEFAULT_SPEED; char size[256] = DEFAULT_SIZE; int tmp, w, h, xoff, yoff; PrivateData *p; /* Alocate and store private data */ p = (PrivateData *) malloc(sizeof(PrivateData)); if (p == NULL) return -1; if (drvthis->store_private_ptr(drvthis, p)) return -1; /* Initialise the PrivateData structure */ p->fd = -1; p->width = JW002_DEFAULT_WIDTH; p->height = JW002_DEFAULT_HEIGHT; p->cellwidth = JW002_DEFAULT_CELLWIDTH; p->cellheight = JW002_DEFAULT_CELLHEIGHT; p->framebuf = NULL; p->backingstore = NULL; p->output_state = -1; /* static data from jw002_output */ p->keypad_test_mode = 0; debug(RPT_INFO, "jw002: init(%p)", drvthis); /* 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, "%s: using Device %s", drvthis->name, device); /* Get display size */ strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); size[sizeof(size)-1] = '\0'; if ((sscanf(size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", drvthis->name, size, DEFAULT_SIZE); sscanf(DEFAULT_SIZE , "%dx%d", &w, &h); } p->width = w; p->height = h; /* Get font number (0-3 are ROM fonts, 4-31 are RAM fonts) */ tmp = drvthis->config_get_int(drvthis->name, "Font", 0, JW002_DEFAULT_FONT); if (tmp < 0 || tmp >= JW002_MAX_FONT) { report(RPT_WARNING, "%s: Font numbers range from 0-31. Font number %d is invalid; using font 0", drvthis->name, tmp); tmp = 0; } p->font = tmp; // jw-002 interface speed is compiled into the firmware - default is 19200 /* Get speed */ tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); switch (tmp) { case 1200: speed = B1200; break; case 2400: speed = B2400; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; default: speed = B19200; report(RPT_WARNING, "%s: Speed must be 1200, 2400, 9600 or 19200; using default %d", drvthis->name, tmp); } /* Get keypad settings */ /* Get offsets */ xoff = drvthis->config_get_int(drvthis->name, "X_offset", 0, DEFAULT_XOFFSET); yoff = drvthis->config_get_int(drvthis->name, "Y_offset", 0, DEFAULT_YOFFSET); if (xoff < 0 || xoff + p->width > LCD_MAX_WIDTH) { report(RPT_WARNING, "%s: X offset of %d invalid. Ignoring X offset request", drvthis->name, xoff); xoff = 0; } if (yoff < 0 || yoff + p->height > LCD_MAX_HEIGHT) { report(RPT_WARNING, "%s: Y offset of %d invalid. Ignoring Y offset request", drvthis->name, xoff); yoff = 0; } p->xoff = xoff; p->yoff = yoff; /* keypad test mode? */ if (drvthis->config_get_bool(drvthis->name, "keypad_test_mode", 0, 0)) { fprintf(stdout, "jw-002: Entering keypad test mode...\n"); p->keypad_test_mode = 1; stay_in_foreground = 1; } if (!p->keypad_test_mode) { /* We don't send any chars to the server in keypad test mode. * So there's no need to get them from the configfile in keypad * test mode. */ int i; /* assume no mapped keys */ p->keys = 0; /* read the keymap */ for (i = 0; i < MAX_KEY_MAP; i++) { char buf[40]; const char *s; /* First fill with NULL; */ p->keymap[i] = NULL; /* Read config value */ sprintf(buf, "KeyMap_%c", i+'A'); s = drvthis->config_get_string(drvthis->name, buf, 0, NULL); /* Was a key specified in the config file ? */ if (s != NULL) { p->keys++; p->keymap[i] = strdup(s); report(RPT_INFO, "%s: Key '%c' mapped to \"%s\"", drvthis->name, i+'A', s ); } } } /* End of config file parsing */ /* Set up io port correctly, and open it... */ // p->fd = open(device, O_RDWR | O_NOCTTY); p->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); if (p->fd == -1) { report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno)); if (errno == EACCES) report(RPT_ERR, "%s: %s device could not be opened...", drvthis->name, device); return -1; } report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); tcgetattr(p->fd, &portset); // THIS ALL COMMENTED OUT BECAUSE WE NEED TO SET TIMEOUTS /* We use RAW mode */ #ifdef HAVE_CFMAKERAW_NOT /* The easy way */ cfmakeraw(&portset); #else /* The hard way */ 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; #endif /* Set port speed */ cfsetospeed(&portset, speed); cfsetispeed(&portset, B0); /* Do it... */ tcsetattr(p->fd, TCSANOW, &portset); /* Make sure the frame buffer is there... */ p->framebuf = (unsigned char *) calloc(p->width * p->height, 1); if (p->framebuf == NULL) { report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name); return -1; } memset(p->framebuf, ' ', p->width * p->height); /* make sure the framebuffer backing store is there... */ p->backingstore = (unsigned char *) malloc(p->width * p->height); if (p->backingstore == NULL) { report(RPT_ERR, "%s: unable to create framebuffer backing store", drvthis->name); return -1; } memset(p->backingstore, ' ', p->width * p->height); /* set initial LCD configuration */ jw002_init_keys(drvthis); jw002_hardware_clear(drvthis); // clear screen and set font from p->font jw002_linewrap(drvthis, 0); // turn off linewrap _and_ autoscroll report(RPT_DEBUG, "%s: init() done", drvthis->name); return 1; } /** * Close the driver (do necessary clean-up). * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void jw002_close (Driver *drvthis) { PrivateData *p = drvthis->private_data; if (p != NULL) { if (p->fd >= 0) close(p->fd); if (p->framebuf) free(p->framebuf); p->framebuf = NULL; if (p->backingstore) free(p->backingstore); p->backingstore = NULL; free(p); } drvthis->store_private_ptr(drvthis, NULL); debug(RPT_DEBUG, "jw002: closed"); } /** * Return the display width in characters. * \param drvthis Pointer to driver structure. * \return Number of characters the display is wide. */ MODULE_EXPORT int jw002_width (Driver *drvthis) { PrivateData *p = drvthis->private_data; return p->width; } /** * Return the display height in characters. * \param drvthis Pointer to driver structure. * \return Number of characters the display is high. */ MODULE_EXPORT int jw002_height (Driver *drvthis) { PrivateData *p = drvthis->private_data; return p->height; } /** * Return the width of a character in pixels. * \param drvthis Pointer to driver structure. * \return Number of pixel columns a character cell is wide. */ MODULE_EXPORT int jw002_cellwidth (Driver *drvthis) { PrivateData *p = drvthis->private_data; return p->cellwidth; } /** * Return the height of a character in pixels. * \param drvthis Pointer to driver structure. * \return Number of pixel lines a character cell is high. */ MODULE_EXPORT int jw002_cellheight (Driver *drvthis) { PrivateData *p = drvthis->private_data; return p->cellheight; } /** * Print a string on the screen at position (x,y). * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height). * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column). * \param y Vertical character position (row). * \param string String that gets written. */ MODULE_EXPORT void jw002_string (Driver *drvthis, int x, int y, const char string[]) { PrivateData *p = drvthis->private_data; int i; /* Convert 1-based coords to 0-based... */ x--; y--; if ((y < 0) || (y >= p->height)) return; for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) { /* Check for buffer overflows... */ if (x >= 0) p->framebuf[(y * p->width) + x] = string[i]; } debug(RPT_DEBUG, "jw002: printed string at (%d,%d)", x, y); } /** * Clear the screen. * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void jw002_clear (Driver *drvthis) { PrivateData *p = drvthis->private_data; /* set hbar/vbar/bignum mode back to normal character display */ p->ccmode = standard; /* replace all chars in framebuf with spaces */ memset(p->framebuf, ' ', (p->width * p->height)); /* make backing store differ from framebuf so it all gets cleared by jw002_flush */ //memset(p->backingstore, 0xFE, (p->width * p->height)); debug(RPT_DEBUG, "jw002: cleared screen"); } /** * Flush data on screen to the LCD. * \param drvthis Pointer to driver structure. * * The one possible trick is that we want to display chars 0-5 here (for * hbars), which could be interpreted as control chars. The technique * for printing out low chars is... * * Display Byte 0 to 31 * Some control characters (ascii 0 to 31) have special functions, and if * a PC terminal emulation program is also receiving the communication, it * may respond to control characters. To cause the board to display * characters 0 to 31, send a 0x5C followed by the control character plus 32. */ MODULE_EXPORT void jw002_flush (Driver *drvthis) { PrivateData *p = drvthis->private_data; int modified = 0; int i, j; for (i = 0; i < p->height; i++) { // set pointers to start of the line in frame buffer & backing store unsigned char *sp = p->framebuf + (i * p->width); unsigned char *sq = p->backingstore + (i * p->width); // set pointers to end of the line in frame buffer & backing store unsigned char *ep = sp + (p->width - 1); unsigned char *eq = sq + (p->width - 1); int length = 0; debug(RPT_DEBUG, "Framebuf: '%.*s'", p->width, sp); debug(RPT_DEBUG, "Backingstore: '%.*s'", p->width, sq); /* Strategy: * - not more than one update command per line * - leave out leading and trailing parts that are identical */ // skip over leading identical portions of the line for (j = 0; (sp <= ep) && (*sp == *sq); sp++, sq++, j++) ; // skip over trailing identical portions of the line for (length = p->width - j; (length > 0) && (*ep == *eq); ep--, eq--, length--) ; /* there are differences, ... */ if (length > 0) { unsigned char out[length+2]; unsigned char safeout[length+2 * 2]; // room to include escape char for out-of-band chars unsigned char rawchar; memcpy(out, sp, length); unsigned char *rawp, *safep; // point to each of our two line buffers rawp = out; safep = safeout; while (rawp < out + length) { // grab a char and check to see if it's "printable" or not rawchar = *rawp++; // look for 0x5C, 0x00-0x1F, 0x80-0x9F if (rawchar == 0x5C || rawchar < 0x20 || (rawchar > 0x7F && rawchar < 0xA0) ) { *safep++ = 0x5C; // throw in escape char if (rawchar < 0x20) { rawchar += 0x20; // scoot low chars up to printable range } if (rawchar > 0x7F) { rawchar -= 0x20; // scoot down high chars down to printable range } } *safep++ = rawchar; // copy char to output buffer } debug(RPT_DEBUG, "%s: l=%d c=%d count=%d string='%.*s'", __FUNCTION__, i, j, length, length, sp); jw002_cursor_goto(drvthis, j+1, i+1); length = safep - safeout; // new length is however many chars we wrote to our OOB buffer write(p->fd, safeout, length); modified++; } } // i < p->height if (modified) memcpy(p->backingstore, p->framebuf, p->width * p->height); debug(RPT_DEBUG, "jw002: frame buffer flushed"); } /** * Print a character on the screen at position (x,y). * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height). * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column). * \param y Vertical character position (row). * \param c Character that gets written. */ MODULE_EXPORT void jw002_chr (Driver *drvthis, int x, int y, char c) { PrivateData *p = drvthis->private_data; /* Convert 1-based coords to 0-based... */ x--; y--; if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height)) p->framebuf[(y * p->width) + x] = c; debug(RPT_DEBUG, "writing character %02X to position (%d,%d)", c, x, y); } /** * Set output port(s). * * External input/output control (protocol version 1 and later only) * Control extra I/O on CPU. All signals are active low, electrical * ground is active '1', electrical 5V is inactive '0'. (refer to * Tom's LCD Modification page for more information. * * http://www.wiresncode.com/projects/pjrcmp3/display-mods/ * * Transmit: * 0x5C 0x4A * command = '0' control LED on front panel * command = '1' control pin 7 on CPU (use with care, may crash non-modified hardware) * command = '2' control pin 8 on CPU (use with care, may crash non-modified hardware) * command = '4' read LED on front panel (will turn led off and always read '0') * command = '5' read pin 7 on CPU (will always read '0' on non-modified hardware) * command = '6' read pin 8 on CPU (will always read '0' on non-modified hardware) * state = '0' for inactive (electrical 5V) * state = '1' for active (electrical ground) * (state is ignored for read, but must be supplied) * * \param drvthis Pointer to driver structure. * \param state Integer with bits representing port states. */ MODULE_EXPORT void jw002_output (Driver *drvthis, int state) { PrivateData *p = drvthis->private_data; unsigned char out[5] = { '\\', 'J', '0', '0' }; // pre-load with LED "off" msg /* only deal with main LED (bit 1) */ if (state < 2) { // remember the state p->output_state = state; // set up the output command out[3] = (state & 1) ? '1' : '0'; // send command to jw002 and log that we did it debug(RPT_DEBUG, "jw002: setting LED to %d", state & 1); // //write(p->fd, out, 4); } else { /* throw a debug msg if they are trying to manipulate control pins 7 or 8 */ debug(RPT_DEBUG, "jw002: output control requires a modified LCD module"); } } /** * Clear the LCD using its hardware command * \param drvthis Pointer to driver structure. */ static void jw002_hardware_clear (Driver *drvthis) { PrivateData *p = drvthis->private_data; unsigned char out[4] = { '\\', '@', ' ', '0' }; out[2] = p->font + 32; // font numbers must be shifted to printable chars write(p->fd, out, 4); // clear and select font 0 debug(RPT_DEBUG, "jw002: cleared LCD and switched to font %d", p->font); } /** * Turn the LCD's built-in linewrapping feature on or off. * \param drvthis Pointer to driver structure. * \param on New state. */ static void jw002_linewrap (Driver *drvthis, int on) { PrivateData *p = drvthis->private_data; unsigned char out[4] = { '\\', 'A', 0, 0 }; out[2] = (on) ? '3' : '0'; // wrap _and_ scroll on or off write(p->fd, out, 3); debug(RPT_DEBUG, "jw002: linewrap turned %s", (on) ? "on" : "off"); } /** * Turn the LCD's built-in automatic scrolling feature on or off. * \param drvthis Pointer to driver structure. * \param on New state. */ static void jw002_autoscroll (Driver *drvthis, int on) { PrivateData *p = drvthis->private_data; unsigned char out[4] = { '\\', 'A', 0, 0 }; out[2] = (on) ? '3' : '0'; // wrap _and_ scroll on or off write(p->fd, out, 3); debug(RPT_DEBUG, "jw002: autoscroll turned %s", (on) ? "on" : "off"); } /** * Move cursor to position (x,y). * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column). * \param y Vertical character position (row). */ static void jw002_cursor_goto(Driver *drvthis, int x, int y) { PrivateData *p = drvthis->private_data; unsigned char out[5] = { '\\', 'B', 0, 0 }; x--; // turn 1-based coords back into 0-based coords y--; /* set cursor position */ if ((x >= 0) && (x < p->width)) out[2] = (unsigned char) x + p->xoff + 0x20; // shift values above cntrl chars if ((y >= 0) && (y < p->height)) out[3] = (unsigned char) y + p->yoff + 0x20; // shift values above cntrl chars write(p->fd, out, 4); } /** * Provide general information about the LCD/VFD display. * \param drvthis Pointer to driver structure. * \return Constant string with information. */ MODULE_EXPORT const char * jw002_get_info (Driver *drvthis) { PrivateData *p = drvthis->private_data; debug(RPT_DEBUG, "jw002: get_info"); memset(p->info, '\0', sizeof(p->info)); strcpy(p->info, "JW-002 Driver "); return p->info; } /** * Draw a vertical bar bottom-up. * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column) of the starting point. * \param y Vertical character position (row) of the starting point. * \param len Number of characters that the bar is high at 100% * \param promille Current height level of the bar in promille. * \param options Options (currently unused). */ MODULE_EXPORT void jw002_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) { #define ROMBARS #ifndef ROMBARS PrivateData *p = drvthis->private_data; if (p->ccmode != vbar) { unsigned char vBar[p->cellheight]; int i; if (p->ccmode != standard) { /* Not supported(yet) */ report(RPT_WARNING, "%s: vbar: cannot combine two modes using user-defined characters", drvthis->name); return; } p->ccmode = vbar; memset(vBar, 0x00, sizeof(vBar)); for (i = 1; i <= p->cellheight; i++) { // add pixel line per pixel line ... vBar[p->cellheight - i] = 0xFF; jw002_set_char(drvthis, i+CC_OFFSET, vBar); } } lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, CC_OFFSET); #else PrivateData *p = drvthis->private_data; int cellheight = p->cellheight; // quick hack to get hbars working int total_pixels = ((long) 2 * len * cellheight + 1 ) * promille / 2000; int pos; for (pos = 0; pos < len; pos++ ) { int pixels = total_pixels - cellheight * pos; if ( pixels >= cellheight ) { /* write a "full" block to the screen... */ drvthis->icon (drvthis, x, y - pos, ICON_BLOCK_FILLED); } else if ( pixels > 0 ) { /* write a partial block... */ drvthis->chr (drvthis, x, y - pos, (cellheight - pixels) + 136); break; } else { ; /* write nothing (not even a space) */ } } #endif } /** * Draw a horizontal bar to the right. * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column) of the starting point. * \param y Vertical character position (row) of the starting point. * \param len Number of characters that the bar is long at 100% * \param promille Current length level of the bar in promille. * \param options Options (currently unused). * * For the JW-002, the first 6 chars of Font 0 happen to contain vertical * lines of 0, 1, 2, 3, 4, and 5 pixels wide. No custom-defined chars * required. * */ MODULE_EXPORT void jw002_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) { #define ROMBARS #ifndef ROMBARS PrivateData *p = drvthis->private_data; if (p->ccmode != hbar) { unsigned char hBar[p->cellheight]; int i; if (p->ccmode != standard) { /* Not supported(yet) */ report(RPT_WARNING, "%s: hbar: cannot combine two modes using user-defined characters", drvthis->name); return; } p->ccmode = hbar; memset(hBar, 0x00, sizeof(hBar)); for (i = 1; i <= p->cellwidth; i++) { // fill pixel columns from left to right. memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar)); jw002_set_char(drvthis, i+CC_OFFSET, hBar); } } lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, CC_OFFSET); #else PrivateData *p = drvthis->private_data; int cellwidth = p->cellwidth; // quick hack to get hbars working int total_pixels = ((long) 2 * len * cellwidth + 1 ) * promille / 2000; int pos; for (pos = 0; pos < len; pos++ ) { int pixels = total_pixels - cellwidth * pos; if ( pixels >= cellwidth ) { /* write a "full" block to the screen... */ drvthis->icon (drvthis, x+pos, y, ICON_BLOCK_FILLED); } else if ( pixels > 0 ) { /* write a partial block... */ drvthis->chr (drvthis, x+pos, y, pixels); break; } else { ; /* write nothing (not even a space) */ } } #endif } /** * Write a big number to the screen. * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column). * \param num Character to write (0 - 10 with 10 representing ':') */ MODULE_EXPORT void jw002_num (Driver *drvthis, int x, int num) { PrivateData *p = drvthis->private_data; int do_init = 0; if ((num < 0) || (num > 10)) return; debug(RPT_DEBUG, "BG jw002_num: ccmode = %d (bignum = %d)", p->ccmode, bignum); if (p->ccmode != bignum) { if (p->ccmode != standard) { /* Not supported (yet) */ report(RPT_WARNING, "%s: num: cannot combine two modes using user-defined characters", drvthis->name); return; } p->ccmode = bignum; do_init = 1; } debug(RPT_DEBUG, "BG do_init = %d", do_init); // Lib_adv_bignum does everything needed to show the bignumbers. lib_adv_bignum(drvthis, x, num, CC_OFFSET, do_init); } /** * Get total number of custom characters available. * \param drvthis Pointer to driver structure. * \return Number of custom characters (always NUM_CCs). */ MODULE_EXPORT int jw002_get_free_chars (Driver *drvthis) { //PrivateData *p = drvthis->private_data; return NUM_CCs; } /** * Define a custom character and write it to the LCD. * \param drvthis Pointer to driver structure. * \param n Custom character to define [0 - (NUM_CCs-1)]. * \param dat Array of 8(=cellheight) bytes, each representing a pixel row * starting from the top to bottom. * The bits in each byte represent the pixels where the LSB * (least significant bit) is the rightmost pixel in each pixel row. * * From http://www.pjrc.com/mp3/lcd_protocol.html * * Define Custom Character * Download a custom character to RAM. The character number is sent as * two byte ascii hex, followed by a font number (offset by 32), and * an 8-byte bitmap. You may write to any font. User defined fonts * should be placed in 8 through 31. Low numbered fonts may also be * written, but this should generally only be done if the appearance * of particular characters needs to be changed. See the LCD Fonts * page for images of the fonts included in the display board's * firmware. All downloaded font bitmaps are stored in volatile * memory and are lost when the board is rebooted. * * Transmit: * 0x5C 0x44 * * Example: Changing the appearance of capital "R" (R is ascii 0x52) * in font #0: * 0x5C 0x44 0x35 0x32 0x20 0x3E 0x39 0x39 0x39 0x3E 0x3A 0x39 0x39 */ //#define HEX2ASC(x) ((((x) & 0xF) + (((x) & 0xF) > 9) ? 48 : 55 )) //#define HEX2ASC(x) ((x) & 15) + ((((x) & 15) > 9) ? 55 : 48) #define HEX2ASC(x) ((x) + (((x) > 9) ? 55 : 48)) MODULE_EXPORT void jw002_set_char (Driver *drvthis, int n, unsigned char *dat) { PrivateData *p = drvthis->private_data; unsigned char out[13] = { '\\', 'D', 0,0, ' ', 0,0,0,0,0,0,0,0 }; unsigned char mask = (1 << p->cellwidth) - 1; int row; if ((n < CC_OFFSET) || (n >= NUM_CCs+CC_OFFSET)) return; if (!dat) return; out[2] = HEX2ASC(n >> 4); /* Custom char to define. xxx */ out[3] = HEX2ASC(n & 0x0F); /* Custom char to define. xxx */ for (row = 0; row <= p->cellheight; row++) { out[row+5] = (dat[row] & mask) | 0x20; // data portion range 0x20 - 0x3F } #ifdef DEBUG_CHARS debug(RPT_DEBUG, "Chardef: '%.*s'", 13, out); #endif write(p->fd, out, 13); } /** * Place an icon on the screen. * \param drvthis Pointer to driver structure. * \param x Horizontal character position (column). * \param y Vertical character position (row). * \param icon synbolic value representing the icon. * \return Information whether the icon is handled here or needs to be handled by the server core. */ MODULE_EXPORT int jw002_icon (Driver *drvthis, int x, int y, int icon) { // PrivateData *p = drvthis->private_data; static unsigned char heart_open[] = { b__XXXXX, b__X_X_X, b_______, b_______, b_______, b__X___X, b__XX_XX, b__XXXXX }; static unsigned char heart_filled[] = { b__XXXXX, b__X_X_X, b___X_X_, b___XXX_, b___XXX_, b__X_X_X, b__XX_XX, b__XXXXX }; static unsigned char arrow_up[] = { b____X__, b___XXX_, b__X_X_X, b____X__, b____X__, b____X__, b____X__, b_______ }; static unsigned char arrow_down[] = { b____X__, b____X__, b____X__, b____X__, b__X_X_X, b___XXX_, b____X__, b_______ }; /* static unsigned char arrow_left[] = { b_______, b____X__, b___X___, b__XXXXX, b___X___, b____X__, b_______, b_______ }; static unsigned char arrow_right[] = { b_______, b____X__, b_____X_, b__XXXXX, b_____X_, b____X__, b_______, b_______ }; */ static unsigned char checkbox_off[] = { b_______, b_______, b__XXXXX, b__X___X, b__X___X, b__X___X, b__XXXXX, b_______ }; static unsigned char checkbox_on[] = { b____X__, b____X__, b__XXX_X, b__X_XX_, b__X_X_X, b__X___X, b__XXXXX, b_______ }; static unsigned char checkbox_gray[] = { b_______, b_______, b__XXXXX, b__X_X_X, b__XX_XX, b__X_X_X, b__XXXXX, b_______ }; /* static unsigned char selector_left[] = { b___X___, b___XX__, b___XXX_, b___XXXX, b___XXX_, b___XX__, b___X___, b_______ }; static unsigned char selector_right[] = { b_____X_, b____XX_, b___XXX_, b__XXXX_, b___XXX_, b____XX_, b_____X_, b_______ }; static unsigned char ellipsis[] = { b_______, b_______, b_______, b_______, b_______, b_______, b__X_X_X, b_______ }; static unsigned char block_filled[] = { b__XXXXX, b__XXXXX, b__XXXXX, b__XXXXX, b__XXXXX, b__XXXXX, b__XXXXX, b__XXXXX }; */ /* Yes we know, this is a VERY BAD implementation :-) */ switch (icon) { case ICON_BLOCK_FILLED: jw002_chr(drvthis, x, y, 136); // Font 0 fill chr break; case ICON_HEART_FILLED: jw002_set_char(drvthis, CC_OFFSET, heart_filled); jw002_chr(drvthis, x, y, CC_OFFSET); break; case ICON_HEART_OPEN: jw002_set_char(drvthis, CC_OFFSET+1, heart_open); jw002_chr(drvthis, x, y, CC_OFFSET+1); break; case ICON_ARROW_UP: jw002_set_char(drvthis, CC_OFFSET+2, arrow_up); jw002_chr(drvthis, x, y, CC_OFFSET+2); case ICON_ARROW_DOWN: jw002_set_char(drvthis, CC_OFFSET+3, arrow_down); jw002_chr(drvthis, x, y, CC_OFFSET+3); break; case ICON_ARROW_LEFT: jw002_chr(drvthis, x, y, 0x7F); break; case ICON_ARROW_RIGHT: jw002_chr(drvthis, x, y, 0x7E); break; case ICON_CHECKBOX_OFF: jw002_set_char(drvthis, CC_OFFSET+4, checkbox_off); jw002_chr(drvthis, x, y, CC_OFFSET+4); break; case ICON_CHECKBOX_ON: jw002_set_char(drvthis, CC_OFFSET+5, checkbox_on); jw002_chr(drvthis, x, y, CC_OFFSET+5); break; case ICON_CHECKBOX_GRAY: jw002_set_char(drvthis, CC_OFFSET+6, checkbox_gray); jw002_chr(drvthis, x, y, CC_OFFSET+6); break; default: return -1; /* Let the core do other icons */ } return 0; } /** * Set cursor position and state. * \param drvthis Pointer to driver structure. * \param x Horizontal cursor position (column). * \param y Vertical cursor position (row). * \param state New cursor state. */ MODULE_EXPORT void jw002_cursor (Driver *drvthis, int x, int y, int state) { // jw-002 doesn't support visible (hardware-driven) cursors /* set cursor position */ jw002_cursor_goto(drvthis, x, y); } /** * Initialize keypad strings * * The standard PJRC firmware for the JW-002 sends back strings at * keydown, keyup, and repeat. We don't really care about keyup, * and to us, repeat might as well be another keydown event. Fortunately, * the firmware allows us to set arbitrary strings for all keys and * all events. * * To simplify things, we will set the keydown and repeat strings to 'A'-'L', * and the keyup strings to nothing (12 spaces). * * From http://www.pjrc.com/mp3/lcd_protocol.html * * Configure Pushbutton Message String * * Transmit: * 0x5C 0x48