New driver: vlsys_m428 driver for Moneual MonCaso 320 (W. Hauck).

This commit is contained in:
mmdolze
2011-10-23 12:08:55 +00:00
parent b8646d2db3
commit 57c0645621
11 changed files with 542 additions and 6 deletions
+1
View File
@@ -10,6 +10,7 @@ v0.5dev (ongoing development)
+ new driver: glcd unified graphic display driver (M. Dolze)
* curses: Fix missed keystrokes (from Debian)
* curses: Correct the name of the info function.
+ new driver: vlsys_m428 driver for Moneual MonCaso 320 (W. Hauck)
v0.5.5
+ sed1330 driver: Add support for HG25504 (L. Lagendijk)
+9 -1
View File
@@ -49,7 +49,7 @@ DriverPath=server/drivers/
# IOWarrior, irman, joy, lb216, lcdm001, lcterm, lirc, lis, MD8800,
# mdm166a, ms6931, mtc_s16209x, MtxOrb, mx5000, NoritakeVFD, picolcd,
# pyramid, sed1330, sed1520, serialPOS, serialVFD, shuttleVFD, sli,
# stv5730, svga, t6963, text, tyan, ula200, xosd
# stv5730, svga, t6963, text, tyan, ula200, vlsys_m428, xosd
Driver=curses
# Tells the driver to bind to the given interface
@@ -1160,6 +1160,14 @@ Speed=19200
## vlsys_m428 for VFD/IR combination in Moneual MonCaso 320 ##
[vlsys_m428]
# Select the output device to use [default: /dev/ttyUSB0]
#Device=/dev/ttyUSB0
## OnScreen Display using libxosd ##
[xosd]
+6 -2
View File
@@ -15,14 +15,14 @@ AC_ARG_ENABLE(drivers,
[ ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,]
[ picolcd,pyramid,sed1330,sed1520,serialPOS,]
[ serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,]
[ t6963,text,tyan,ula200,xosd]
[ t6963,text,tyan,ula200,vlsys_m428,xosd]
[ ]
[ 'all' compiles all drivers;]
[ 'all,!xxx,!yyy' de-selects previously selected drivers],
drivers="$enableval",
drivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text])
allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,xosd]
allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,vlsys_m428,xosd]
if test "$debug" = yes; then
allDrivers=["${allDrivers},debug"]
fi
@@ -469,6 +469,10 @@ dnl else
AC_MSG_WARN([The ula200 driver needs the ftdi library])
fi
;;
vlsys_m428)
DRIVERS="$DRIVERS vlsys_m428${SO}"
actdrivers=["$actdrivers vlsys_m428"]
;;
xosd)
AC_PATH_PROG([LIBXOSD_CONFIG], [xosd-config], [no])
if test "$LIBXOSD_CONFIG" = "no"; then
+3
View File
@@ -283,6 +283,9 @@ LCD module in Tyan Barebone GS series
.B ula200
ULA-200 device from ELV (http://www.elv.de)
.TP
.B vlsys_m428
VFD/IR combination in case MonCaso 320 from Moneual
.TP
.B xosd
On Screen Display on X11
.PP
+1
View File
@@ -53,6 +53,7 @@ well as the configuration of LCDd.
&text;
&tyan;
&ula200;
&vlsys_m428;
&xosd;
&ppttrouble;
+3 -2
View File
@@ -12,6 +12,7 @@ EXTRA_DIST = bayrad.docbook \
glcdlib.docbook \
glk.docbook \
hd44780.docbook \
i2500vfd.docbook \
icp_a106.docbook \
imon.docbook \
imonlcd.docbook \
@@ -47,7 +48,7 @@ EXTRA_DIST = bayrad.docbook \
text.docbook \
tyan.docbook \
ula200.docbook \
xosd.docbook \
i2500vfd.docbook
vlsys_m428.docbook \
xosd.docbook
## EOF
@@ -0,0 +1,38 @@
<sect1 id="vlsys_m428-howto">
<title>The vlsys_m428 driver</title>
<sect2 id="vlsys_m428-general">
<title>General</title>
<para>
The vlsys_m428 driver handles the VFD/IR combination from VLSystem built into
the case MonCaso 320 from the manufacturer Moneual. The driver functionality
is rudimentary as it is derived from a reverse engineering from the Windows
driver behaviour.
</para>
<para>
This driver writes only to the serial port, and it triggers no transmission
activity of the combination. Thus, it cooperates with drivers reading only
from the port. Other drivers are allowed to initialize the combination for
IR operation.
</para>
<para>
The vlsys_m428 driver assumes the character encoding ISO 8859-1.
Note: The mapping from the character encoding to the display encoding is not complete;
furthermore some characters are approximated by similar ones.
</para>
</sect2>
<sect2 id="vlsys_m428-configuration">
<title>Configuration</title>
<para>
The only configuration parameter is <property>Device</property>, the path name
of the serial device (a mapper between USB and serial line emulation). By
default it is <filename class="devicefile">/dev/ttyUSB0</filename>.
</para>
</sect2>
</sect1>
+1
View File
@@ -59,6 +59,7 @@
<!ENTITY t6963 SYSTEM "drivers/t6963.docbook">
<!ENTITY text SYSTEM "drivers/text.docbook">
<!ENTITY tyan SYSTEM "drivers/tyan.docbook">
<!ENTITY vlsys_m428 SYSTEM "drivers/vlsys_m428.docbook">
<!ENTITY ula200 SYSTEM "drivers/ula200.docbook">
<!ENTITY xosd SYSTEM "drivers/xosd.docbook">
+2 -1
View File
@@ -22,7 +22,7 @@ AM_LDFLAGS = @LDSHARED@
## Keep the lists sorted!
pkglib_PROGRAMS = @DRIVERS@
EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g15 glcd glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 xosd i2500vfd irtrans
EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g15 glcd glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 vlsys_m428 xosd i2500vfd irtrans
noinst_LIBRARIES = libLCD.a libbignum.a
g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
@@ -128,6 +128,7 @@ t6963_SOURCES = lcd.h lcd_lib.h t6963.c t6963.h glcd_font5x8.h report.h t69
text_SOURCES = lcd.h text.h text.c report.h
tyan_SOURCES = lcd.h lcd_lib.h tyan_lcdm.h tyan_lcdm.c report.h adv_bignum.h
ula200_SOURCES = lcd.h adv_bignum.h ula200.h ula200.c report.h
vlsys_m428_SOURCES = lcd.h report.h vlsys_m428.c vlsys_m428.h
xosd_SOURCES = lcd.h xosdlib_drv.c xosdlib_drv.h report.h adv_bignum.h
AM_CPPFLAGS = -I$(top_srcdir)
+450
View File
@@ -0,0 +1,450 @@
/** \file server/drivers/vlsys_m428.c
* LCDd \c vlsys_m428 driver for the VLSystem VFD/IR combination in the
* computer case "Moneual MonCaso 320". The precise name of the VFD is
* unknown, but it reports itself as "M428".
*
* The command set and its parameters have been discovered by
* monitoring the serial port communication of the Windows driver.
*/
/*-
* Copyright (c) 2011 Wolfgang Hauck <wolfgang.hauck@gmx.de>.
* Derived from imon-module.
*
* This source code is being released under the GPL.
* Please see the file COPYING in this package for details.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include "lcd.h"
#include "report.h"
#include "vlsys_m428.h"
/** Default device path. */
#define DEFAULT_DEVICE "/dev/ttyUSB0"
/** Default serial baud rate. */
#define DEFAULT_BAUD_RATE B57600
/** Display width in characters. */
#define DEFAULT_WIDTH 14
/** Display height in characters. */
#define DEFAULT_HEIGHT 1
/** Frame buffer size. */
#define DEFAULT_SIZE (DEFAULT_WIDTH * DEFAULT_HEIGHT)
/** Maximal size of device path. */
#define PATH_SIZE 256
/* Command set and parameters */
/** Initialise display for IR receive. Unused by this driver. */
#define CMD_INIT 0x96
/** Enable icon on top of display. */
#define CMD_ICON 0x97
/** Print a character sequence starting from a specified display position */
#define CMD_PRINT 0x93
/** Complete print action */
#define CMD_COMPLETE 0x09
/** Switch power LED. */
#define CMD_LED 0x9B
/** Disable icon; parameter to command CMD_ICON. */
#define PAR_ICON_DISABLE 0x01
/** Enable icon; parameter to command CMD_ICON. */
#define PAR_ICON_ENABLE 0x02
/** Switch LED off; parameter to command CMD_LED. */
#define PAR_LED_OFF 0x02
/** Switch LED on; parameter to command CMD_LED. */
#define PAR_LED_ON 0x01
/* Vars for the server core */
MODULE_EXPORT char *api_version = API_VERSION;
MODULE_EXPORT int stay_in_foreground = 0;
MODULE_EXPORT int supports_multiple = 0;
MODULE_EXPORT char *symbol_prefix = "vlsys_m428_";
/** Private data for the \c vlsystem_m428 driver */
typedef struct vlsystem_m428_private_data {
int fd; /**< File descriptor of serial port */
char framebuf[DEFAULT_SIZE]; /**< Frame buffer */
} PrivateData;
/* Internal functions */
static int dev_print_chr(PrivateData *p, char x, const char *s, unsigned int n);
static int dev_send_bytes(PrivateData *p, const char *s, unsigned int n);
static int initialise_display(PrivateData *p);
static int initialise_port(int fd);
static char map(char c);
/**
* Sends an array of bytes to the display.
* \param p Pointer to private data.
* \param s Pointer to array of bytes.
* \param n Number of bytes to be sent.
* \retval 0 Success.
* \retval <0 Error (errno is set).
*/
static int
dev_send_bytes(PrivateData *p, const char *s, unsigned int n)
{
int l;
while (n > 0) {
l = write(p->fd, s, n);
if (l < 0) {
return (-1);
}
s += l;
n -= l;
}
return 0;
}
/**
* Prints an array of characters on the display.
* \param p Pointer to private data.
* \param x Column position (1, 2, 3, ..., DEFAULT_WIDTH).
* \param s Pointer to array of characters.
* \param n Number of characters to be printed.
* \retval 0 Success.
* \retval <0 Error (errno is set).
*/
static int
dev_print_chr(PrivateData *p, char x, const char *s, unsigned int n)
{
char c;
c = CMD_PRINT;
if (dev_send_bytes(p, &c, 1) < 0) {
return (-1);
}
if (dev_send_bytes(p, &x, 1) < 0) {
return (-1);
}
if (dev_send_bytes(p, s, n) < 0) {
return (-1);
}
c = CMD_COMPLETE;
if (dev_send_bytes(p, &c, 1) < 0) {
return (-1);
}
return 0;
}
/**
* Maps a character encoded in ISO 8859-1 to display encoding.
* Note: Encoding is not complete; some characters
* are approximated by similar ones.
* - Approximates for 0xA6, 0xAD, 0xB4, 0xB7, 0xCD, 0xFA.
* - No character for 0xA8, 0xA9, 0xAC, 0xAE, 0xAF, 0xB8.
* \param c Character (ISO 8859-1).
* \return Character (display encoding or an approximation),
* zero if map value is unknown.
*/
static char
map(char c)
{
static const char display[] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x20, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0x7C, 0xF5, 0x00, 0x00, 0xA6, 0xAE, 0x00, 0x2D, 0x00, 0x00, /* 0xA? */
0xF8, 0xF1, 0xFD, 0xFC, 0x27, 0x16, 0xF4, 0x2E, 0x00, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* 0xB? */
0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, 0xD4, 0x90, 0xD2, 0xD3, 0xD6, 0x49, 0xD7, 0xD8, /* 0xC? */
0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, 0xBF, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE7, 0xE1, /* 0xD? */
0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, /* 0xE? */
0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, 0xCB, 0x97, 0x75, 0x96, 0x81, 0xEC, 0xE8, 0x98 /* 0xF? */
};
unsigned char d = c;
if (d >= 0x20 && d <= 0x7F) {
return d; /* standard ASCII */
}
else if (d >= 0xA0) {
return display[d - 0xA0]; /* ISO 8859-1 extension */
}
else {
return 0;
}
}
/**
* Initialises the serial port.
* \param fd File descriptor of serial port.
* \retval 0 Success.
* \retval <0 Error.
*/
static int
initialise_port(int fd)
{
struct termios options;
if (tcgetattr(fd, &options) < 0) {
return -1;
}
#ifdef HAVE_CFMAKERAW
cfmakeraw(&options);
#else
options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
options.c_oflag &= ~OPOST;
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options.c_cflag &= ~(CSIZE | PARENB | CRTSCTS);
options.c_cflag |= CS8 | CREAD | CLOCAL;
#endif
cfsetispeed(&options, DEFAULT_BAUD_RATE);
cfsetospeed(&options, DEFAULT_BAUD_RATE);
if (tcsetattr(fd, TCSAFLUSH, &options) < 0) {
return -1;
}
return 0;
}
/**
* Initialises the display.
* Switches red LED on and off such that a short flash is visible;
* useful for LED test and debugging purposes.
* Note: All commands sent do not trigger a response on the serial line,
* therefore other read-only drivers are not disturbed.
* \param p Pointer to private data.
* \retval 0 Success.
* \retval <0 Error.
*/
static int
initialise_display(PrivateData *p)
{
const char on[] = {CMD_LED, PAR_LED_ON};
const char off[] = {CMD_LED, PAR_LED_OFF};
int i; /* icon index */
/* Switch red LED on */
if (dev_send_bytes(p, on, sizeof(on))) {
return -1;
}
/* Send output initialisation sequence (non-intrusive, no response) */
for (i = 1; i < DEFAULT_SIZE; i++) {
char icon[] = {CMD_ICON, 0, PAR_ICON_DISABLE};
icon[1] = i;
if (dev_send_bytes(p, icon, sizeof(icon))) {
return -1;
}
}
/* Switch red LED off */
if (dev_send_bytes(p, off, sizeof(off))) {
return -1;
}
return 0;
}
/**
* Initialises the driver.
* \param drvthis Pointer to driver structure.
* \retval 0 Success.
* \retval <0 Error.
*/
MODULE_EXPORT int
vlsys_m428_init(Driver *drvthis)
{
PrivateData *p = NULL;
char path[PATH_SIZE]; /* device path (serial port) */
/* Allocate and initialise private data */
p = (PrivateData *) calloc(1, sizeof(PrivateData));
if (p == NULL) {
report(RPT_ERR, "%s: failed to allocate private data", drvthis->name);
return -1;
}
p->fd = -1; /* fail safe value */
memset(p->framebuf, ' ', sizeof(p->framebuf));
/* Store pointer to private data */
if (drvthis->store_private_ptr(drvthis, p)) {
report(RPT_ERR, "%s: failed to store private data pointer", drvthis->name);
vlsys_m428_close(drvthis);
return -1;
}
/* Get device path from configuration file */
strncpy(path,
drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE),
sizeof(path));
path[sizeof(path) - 1] = '\0';
report(RPT_INFO, "%s: using device %s", drvthis->name, path);
/* Open device for writing (reading would interfere with LIRC) */
if ((p->fd = open(path, O_WRONLY)) < 0) {
report(RPT_ERR,
"%s: could not open %s (%s)",
drvthis->name, path, strerror(errno));
vlsys_m428_close(drvthis);
return -1;
}
/* Serial port configuration */
else if (initialise_port(p->fd) < 0) {
report(RPT_ERR, "%s: could not configure %s (%s)",
drvthis->name, path, strerror(errno));
vlsys_m428_close(drvthis);
return -1;
}
/* Initialise display for output */
else if (initialise_display(p) < 0) {
report(RPT_ERR, "%s: could not initialise display", drvthis->name);
vlsys_m428_close(drvthis);
return -1;
}
/* Erase display */
else if (dev_print_chr(p, 1, p->framebuf, DEFAULT_SIZE) < 0) {
report(RPT_ERR, "%s: could not erase display", drvthis->name);
vlsys_m428_close(drvthis);
return -1;
}
report(RPT_DEBUG, "%s: init() done", drvthis->name);
return 0;
}
/**
* Closes the driver (do necessary clean-up).
* \param drvthis Pointer to driver structure.
*/
MODULE_EXPORT void
vlsys_m428_close(Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
/* Clean up resources */
if (p != NULL) {
/* Close serial port */
if (p->fd >= 0) {
close(p->fd);
}
free(p);
}
/* Invalidate local driver structure */
drvthis->store_private_ptr(drvthis, NULL);
report(RPT_DEBUG, "%s: close() done", drvthis->name);
}
/**
* Provides some information about this driver.
* \param drvthis Pointer to driver structure.
* \return Constant string with information.
*/
MODULE_EXPORT const char *
vlsys_m428_get_info(Driver *drvthis)
{
const char *info_string = "Driver for VLSystem VFD/IR combination in Moneual MonCaso 320";
return info_string;
}
/**
* Clears the screen.
* \param drvthis Pointer to driver structure.
*/
MODULE_EXPORT void
vlsys_m428_clear(Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
memset(p->framebuf, ' ', DEFAULT_SIZE);
}
/**
* Flushes data on screen to the display.
* \param drvthis Pointer to driver structure.
*/
MODULE_EXPORT void
vlsys_m428_flush(Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
dev_print_chr(p, 1, p->framebuf, DEFAULT_SIZE);
}
/**
* Prints a string on the screen at position (x,y).
* The upper-left corner is (1,1),
* the lower-right corner is (DEFAULT_WIDTH, DEFAULT_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
vlsys_m428_string(Driver *drvthis, int x, int y, const char string[])
{
int i;
for (i = 0; string[i] != '\0'; i++)
vlsys_m428_chr(drvthis, x + i, y, string[i]);
}
/**
* Puts a character on the screen at position (x,y).
* The upper-left corner is (1,1),
* the lower-right corner is (DEFAULT_WIDTH, DEFAULT_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
vlsys_m428_chr(Driver *drvthis, int x, int y, char c)
{
PrivateData *p = drvthis->private_data;
if ((x >= 1) && (y >= 1) && (x <= DEFAULT_WIDTH) && (y <= DEFAULT_HEIGHT)) {
p->framebuf[x - 1] = map(c);
}
}
/**
* Returns the display width in characters.
* \param drvthis Pointer to driver structure.
* \return Number of characters the display is wide.
*/
MODULE_EXPORT int
vlsys_m428_width(Driver *drvthis)
{
return DEFAULT_WIDTH;
}
/**
* Returns the display height in characters.
* \param drvthis Pointer to driver structure.
* \return Number of characters the display is high.
*/
MODULE_EXPORT int
vlsys_m428_height(Driver *drvthis)
{
return DEFAULT_HEIGHT;
}
+28
View File
@@ -0,0 +1,28 @@
/**
* Driver for VL System VFD and IR receiver M428 in Moneual Moncaso 320.
*/
/*-
* Copyright (c) 2011 Wolfgang Hauck <wolfgang.hauck@gmx.de>.
* Derived from imon-module.
*
* This source code is being released under the GPL.
* Please see the file COPYING in this package for details.
*/
#ifndef VLSYS_M428_H
#define VLSYS_M428_H
MODULE_EXPORT int vlsys_m428_init(Driver *drvthis);
MODULE_EXPORT void vlsys_m428_close(Driver *drvthis);
MODULE_EXPORT int vlsys_m428_width(Driver *drvthis);
MODULE_EXPORT int vlsys_m428_height(Driver *drvthis);
MODULE_EXPORT void vlsys_m428_clear(Driver *drvthis);
MODULE_EXPORT void vlsys_m428_flush(Driver *drvthis);
MODULE_EXPORT void vlsys_m428_string(Driver *drvthis, int x, int y, const char string[]);
MODULE_EXPORT void vlsys_m428_chr(Driver *drvthis, int x, int y, char c);
MODULE_EXPORT const char * vlsys_get_info(Driver *drvthis);
#endif