Convert custom characters to 8 byte bitmap.
Remove comments from the code that are already part of docbook documentation. Pass through indent. Remove unused prototypes.
This commit is contained in:
@@ -27,6 +27,7 @@ v.0.5dev (ongoing development)
|
|||||||
* CFontzPacket: Use cellwidth = 5 on CFA-631 and CFA-635 too
|
* CFontzPacket: Use cellwidth = 5 on CFA-631 and CFA-635 too
|
||||||
* t6963: Convert font to 8 byte bitmap
|
* t6963: Convert font to 8 byte bitmap
|
||||||
* convert i2500vfd and mdm166a driver to use 8 byte bitmap custom character
|
* convert i2500vfd and mdm166a driver to use 8 byte bitmap custom character
|
||||||
|
* ula200: convert custom characters to 8 byte bitmap
|
||||||
|
|
||||||
v0.5.4
|
v0.5.4
|
||||||
* Update driver includes and LDFLAGS (fixed glk and bayrad binding error)
|
* Update driver includes and LDFLAGS (fixed glk and bayrad binding error)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ So in theory, it would be possible to write a connection type for the
|
|||||||
I tried this. It was slow and didn't work with user-specific characters
|
I tried this. It was slow and didn't work with user-specific characters
|
||||||
(the hd44780 frequently changes this characters which seems to confuse the
|
(the hd44780 frequently changes this characters which seems to confuse the
|
||||||
microcontroller, at least I cannot explain why it didn't work, there was
|
microcontroller, at least I cannot explain why it didn't work, there was
|
||||||
garbare).
|
garbage).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ svga_SOURCES = lcd.h svgalib_drv.c svgalib_drv.h report.h
|
|||||||
t6963_SOURCES = lcd.h lcd_lib.h t6963.c t6963.h t6963_font.h report.h
|
t6963_SOURCES = lcd.h lcd_lib.h t6963.c t6963.h t6963_font.h report.h
|
||||||
text_SOURCES = lcd.h text.h text.c report.h
|
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
|
tyan_SOURCES = lcd.h lcd_lib.h tyan_lcdm.h tyan_lcdm.c report.h adv_bignum.h
|
||||||
ula200_SOURCES = lcd.h lcd_lib.h ula200.h ula200.c report.h
|
ula200_SOURCES = lcd.h adv_bignum.h ula200.h ula200.c report.h
|
||||||
xosd_SOURCES = lcd.h xosdlib_drv.c xosdlib_drv.h report.h adv_bignum.h
|
xosd_SOURCES = lcd.h xosdlib_drv.c xosdlib_drv.h report.h adv_bignum.h
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)
|
AM_CPPFLAGS = -I$(top_srcdir)
|
||||||
|
|||||||
+233
-289
@@ -2,96 +2,27 @@
|
|||||||
* LCDd \c ula200 driver for the ULA-200 from ELV (http://www.elv.de).
|
* LCDd \c ula200 driver for the ULA-200 from ELV (http://www.elv.de).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Description:
|
/*-
|
||||||
//
|
* Copyright (C) 2006 Bernhard Walle <bernhard.walle@gmx.de>
|
||||||
// This is a driver for the ULA-200 from ELV (http://www.elv.de). It's a small
|
*
|
||||||
// board which can be connected to the PC via USB interface and that allows to
|
* This program is free software; you can redistribute it and/or modify
|
||||||
// connect a HD44780-compatible display. It also has a connection for up to 6
|
* it under the terms of the GNU General Public License as published by
|
||||||
// input buttons.
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
//
|
* any later version.
|
||||||
// It uses libftdi (which uses libusb) for communication, so no kernel driver
|
|
||||||
// is needed. You have to take care that ftdi_sio module doesn't claim the ELV
|
|
||||||
// device. If you didn't change the ids in the driver (ftdi_sio.c), you don't
|
|
||||||
// have to matter.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Features:
|
|
||||||
//
|
|
||||||
// - text display is supported
|
|
||||||
// - standard symbols (heart, checkbox) are supported
|
|
||||||
// - backlight is supported
|
|
||||||
// - input buttons are supported
|
|
||||||
// - bars are NOT supported
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Configuration options (the values are the default values):
|
|
||||||
//
|
|
||||||
// - Size=20x4
|
|
||||||
// - KeyMap_A=Up
|
|
||||||
// - KeyMap_B=Down
|
|
||||||
// - KeyMap_C=Left
|
|
||||||
// - KeyMap_D=Right
|
|
||||||
// - KeyMap_E=Enter
|
|
||||||
// - KeyMap_F=Escape
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Known problems:
|
|
||||||
//
|
|
||||||
// Sometimes the display hangs (the ACK response is not received) on shutdown.
|
|
||||||
// Reconnect the display in that case. The same if it hangs while starting
|
|
||||||
// up (only happens if it was not the first time lcdproc talked to the
|
|
||||||
// display).
|
|
||||||
//
|
|
||||||
// I tried several hours to fix this, I simply find the reason for this problem.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Implementation note:
|
|
||||||
//
|
|
||||||
// The ULA-200 talks a text protocol which allows to display text using a
|
|
||||||
// high-level language, i.e. STX 's' <len> <char0> <char1> ... ETX. It also
|
|
||||||
// allows low-level register access to the HD44780. So in theory, it would be
|
|
||||||
// possible to write a hd44780 extension and let the hd44780 core do the rest.
|
|
||||||
// I tried this. It was slow and didn't work with user-specific characters
|
|
||||||
// (the hd44780 frequently changes this characters which seems to confuse the
|
|
||||||
// microcontroller, at least I cannot explain why it didn't work, there was
|
|
||||||
// garbare).
|
|
||||||
//
|
|
||||||
// So I wrote a own driver (this here) which uses the high-level language and
|
|
||||||
// should work for displays with all sizes. I only tested 20x4, so maybe for
|
|
||||||
// other sizes the positioning code may be adapted.
|
|
||||||
//
|
|
||||||
// As I mentioned, there were problems with frequently changing the
|
|
||||||
// user-definable characters. I also tried to implement bar code in the ula200
|
|
||||||
// driver with similar effects. I gave it up because I don't need it personally
|
|
||||||
// and it can be done later. However, standard icons are implemented. The
|
|
||||||
// user-definable characters are set in startup and are not changed. This
|
|
||||||
// works like a charm. It is not possible to use character 0 with the
|
|
||||||
// high-level language (or at least it isn't documented how to escape it).
|
|
||||||
// It could be done with hd44780 code, but I replaced the character with
|
|
||||||
// a standard character which looks good.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author
|
|
||||||
//
|
|
||||||
// Bernhard Walle <bernhard.walle@gmx.de>
|
|
||||||
// Feel free to contact me if there are problems with this driver.
|
|
||||||
//
|
|
||||||
|
|
||||||
/* Copyright (C) 2006 Bernhard Walle <bernhard.walle@gmx.de>
|
* 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.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
* You should have received a copy of the GNU General Public License
|
||||||
it under the terms of the GNU General Public License as published by
|
* along with this program; if not, write to the Free Software
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
any later version.
|
*/
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
#ifdef HAVE_CONFIG_H
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# include "config.h"
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
#endif
|
||||||
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 <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -105,15 +36,11 @@
|
|||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "hd44780-charmap.h"
|
#include "hd44780-charmap.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "ula200.h"
|
#include "ula200.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "timing.h"
|
#include "adv_bignum.h"
|
||||||
|
|
||||||
|
|
||||||
/* Vars for the server core */
|
/* Vars for the server core */
|
||||||
@@ -123,9 +50,7 @@ MODULE_EXPORT int supports_multiple = 1;
|
|||||||
MODULE_EXPORT char *symbol_prefix = "ula200_";
|
MODULE_EXPORT char *symbol_prefix = "ula200_";
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/* -------------------------- constants ---------------------------------- */
|
||||||
// constants
|
|
||||||
//
|
|
||||||
#define DISPLAY_VENDOR_ID 0x0403
|
#define DISPLAY_VENDOR_ID 0x0403
|
||||||
#define DISPLAY_PRODUCT_ID 0xf06d
|
#define DISPLAY_PRODUCT_ID 0xf06d
|
||||||
|
|
||||||
@@ -138,7 +63,7 @@ MODULE_EXPORT char *symbol_prefix = "ula200_";
|
|||||||
#define CH_DC3 0x13
|
#define CH_DC3 0x13
|
||||||
|
|
||||||
#define MAX_KEY_MAP 6
|
#define MAX_KEY_MAP 6
|
||||||
static char *default_key_map[MAX_KEY_MAP] = { "Up", "Down", "Left", "Right", "Enter", "Escape" };
|
static char *default_key_map[MAX_KEY_MAP] = {"Up", "Down", "Left", "Right", "Enter", "Escape"};
|
||||||
|
|
||||||
#define CELLWIDTH 5
|
#define CELLWIDTH 5
|
||||||
#define CELLHEIGHT 8
|
#define CELLHEIGHT 8
|
||||||
@@ -146,10 +71,19 @@ static char *default_key_map[MAX_KEY_MAP] = { "Up", "Down", "Left", "Right", "En
|
|||||||
/* repeat conts for responses */
|
/* repeat conts for responses */
|
||||||
#define MAX_REPEATS 20
|
#define MAX_REPEATS 20
|
||||||
|
|
||||||
|
/* commands for senddata */
|
||||||
|
#define RS_DATA 0x00
|
||||||
|
#define RS_INSTR 0x01
|
||||||
|
#define SETCHAR 0x40
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/* boolean data type */
|
||||||
// Key ring implementation from CFontz633io
|
#ifndef bool
|
||||||
//
|
# define bool short
|
||||||
|
# define true 1
|
||||||
|
# define false 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ----------- Key ring implementation from CFontz633io ------------------ */
|
||||||
|
|
||||||
/* KeyRing management */
|
/* KeyRing management */
|
||||||
#define KEYRINGSIZE 16
|
#define KEYRINGSIZE 16
|
||||||
@@ -160,26 +94,24 @@ typedef struct ula200_keyring {
|
|||||||
int tail;
|
int tail;
|
||||||
} KeyRing;
|
} KeyRing;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KeyRing handling functions.
|
* KeyRing handling functions. This separates the producer from the consumer.
|
||||||
* This separates the producer from the consumer.
|
|
||||||
* It is just a small fifo of unsigned char.
|
* It is just a small fifo of unsigned char.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** initialize/empty key ring by resetting its read & write pointers */
|
/** initialize/empty key ring by resetting its read & write pointers */
|
||||||
void EmptyKeyRing(KeyRing *kr)
|
void
|
||||||
|
EmptyKeyRing(KeyRing *kr)
|
||||||
{
|
{
|
||||||
kr->head = kr->tail = 0;
|
kr->head = kr->tail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** add byte to key ring; return success (byte added) / failure (key ring is full) */
|
/** add byte to key ring; return success (byte added) / failure (key ring is full) */
|
||||||
int AddKeyToKeyRing(KeyRing *kr, unsigned char key)
|
int
|
||||||
|
AddKeyToKeyRing(KeyRing *kr, unsigned char key)
|
||||||
{
|
{
|
||||||
if (((kr->head + 1) % KEYRINGSIZE) != (kr->tail % KEYRINGSIZE)) {
|
if (((kr->head + 1) % KEYRINGSIZE) != (kr->tail % KEYRINGSIZE)) {
|
||||||
/* fprintf(stderr, "We add key: %d\n", key); */
|
|
||||||
|
|
||||||
kr->contents[kr->head % KEYRINGSIZE] = key;
|
kr->contents[kr->head % KEYRINGSIZE] = key;
|
||||||
kr->head = (kr->head + 1) % KEYRINGSIZE;
|
kr->head = (kr->head + 1) % KEYRINGSIZE;
|
||||||
@@ -192,7 +124,8 @@ int AddKeyToKeyRing(KeyRing *kr, unsigned char key)
|
|||||||
|
|
||||||
|
|
||||||
/** get byte from key ring (or '\\0' if key ring is empty) */
|
/** get byte from key ring (or '\\0' if key ring is empty) */
|
||||||
unsigned char GetKeyFromKeyRing(KeyRing *kr)
|
unsigned char
|
||||||
|
GetKeyFromKeyRing(KeyRing *kr)
|
||||||
{
|
{
|
||||||
unsigned char retval = '\0';
|
unsigned char retval = '\0';
|
||||||
|
|
||||||
@@ -203,43 +136,31 @@ unsigned char GetKeyFromKeyRing(KeyRing *kr)
|
|||||||
kr->tail = (kr->tail + 1) % KEYRINGSIZE;
|
kr->tail = (kr->tail + 1) % KEYRINGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (retval) fprintf(stderr, "We remove key: %d\n", retval); */
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// for HD 44780 compatibility
|
|
||||||
//
|
|
||||||
|
|
||||||
// commands for senddata
|
|
||||||
#define RS_DATA 0x00
|
|
||||||
#define RS_INSTR 0x01
|
|
||||||
|
|
||||||
#define SETCHAR 0x40 /* Only reachable with EXTREG clear */
|
|
||||||
|
|
||||||
|
/* ---------------------- ULA-200 specific functions --------------------- */
|
||||||
|
|
||||||
/** private data for the \c ula200 driver */
|
/** private data for the \c ula200 driver */
|
||||||
typedef struct ula200_private_data {
|
typedef struct ula200_private_data {
|
||||||
struct ftdi_context ftdic; /**< handle for the USB FTDI library */
|
struct ftdi_context ftdic; /**< handle for the USB FTDI library */
|
||||||
|
int width; /**< display width in characters */
|
||||||
// the width and the height (in number of characters) of the library
|
int height; /**< display height in characters */
|
||||||
int width, height;
|
unsigned char *framebuf; /**< framebuffer LCDd writes to */
|
||||||
|
unsigned char *lcd_contents; /**< content of screen for incr. upd. */
|
||||||
// The framebuffer and the framebuffer for the last contents (incr. update)
|
|
||||||
unsigned char *framebuf, *lcd_contents;
|
|
||||||
|
|
||||||
unsigned char all_dirty; /**< first time => all is dirty */
|
unsigned char all_dirty; /**< first time => all is dirty */
|
||||||
|
|
||||||
int backlight; /**< backlight: -1=unset, 0=off, 1=on */
|
int backlight; /**< backlight: -1=unset, 0=off, 1=on */
|
||||||
|
|
||||||
KeyRing keyring; /**< input key ring */
|
KeyRing keyring; /**< input key ring */
|
||||||
|
|
||||||
char *key_map[MAX_KEY_MAP]; /**< mapping of input keys */
|
char *key_map[MAX_KEY_MAP]; /**< mapping of input keys */
|
||||||
} PrivateData;
|
} PrivateData;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Reads a USB characters
|
* Reads a character from USB.
|
||||||
|
* \param p Pointer to drivers private data
|
||||||
|
* \return Character read from USB.
|
||||||
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
ula200_ftdi_usb_read(PrivateData *p)
|
ula200_ftdi_usb_read(PrivateData *p)
|
||||||
{
|
{
|
||||||
@@ -257,11 +178,12 @@ ula200_ftdi_usb_read(PrivateData *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Reads the response
|
* Reads the response.
|
||||||
//
|
*
|
||||||
// @return true if ACK was responded, false if NACk was responded
|
* \return true if ACK was responded
|
||||||
//
|
* \return false if NAK was responded
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
ula200_ftdi_read_response(Driver *drvthis)
|
ula200_ftdi_read_response(Driver *drvthis)
|
||||||
{
|
{
|
||||||
@@ -271,8 +193,7 @@ ula200_ftdi_read_response(Driver *drvthis)
|
|||||||
int ret;
|
int ret;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
while (!answer_read)
|
while (!answer_read) {
|
||||||
{
|
|
||||||
/* wait until STX */
|
/* wait until STX */
|
||||||
while (((ret = ula200_ftdi_usb_read(p)) != CH_STX) && (ret > 0));
|
while (((ret = ula200_ftdi_usb_read(p)) != CH_STX) && (ret > 0));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -312,16 +233,16 @@ ula200_ftdi_read_response(Driver *drvthis)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Write a command to the display. Adds the STX and ETX header/trailer.
|
* Write a command to the display. Adds the STX and ETX header/trailer.
|
||||||
//
|
*
|
||||||
// @param p the private data
|
* \param p the private data
|
||||||
// @param data the data bytes
|
* \param data the data bytes
|
||||||
// @param length the number of bytes in @p data which are valid
|
* \param length the number of bytes in @p data which are valid
|
||||||
// @param escape if the data should be escaped (see the User's Guide of the
|
* \param escape if the data should be escaped (see the User's Guide of the
|
||||||
// ULA-200)
|
* ULA-200)
|
||||||
// @return 0 on success, negative value on error
|
* \return 0 on success, negative value on error
|
||||||
//
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_write_command(Driver *drvthis, unsigned char *data, int length, bool escape)
|
ula200_ftdi_write_command(Driver *drvthis, unsigned char *data, int length, bool escape)
|
||||||
{
|
{
|
||||||
@@ -369,18 +290,18 @@ ula200_ftdi_write_command(Driver *drvthis, unsigned char *data, int length, bool
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!ula200_ftdi_read_response(drvthis) && (repeat_count++ < MAX_REPEATS));
|
while (!ula200_ftdi_read_response(drvthis)&&(repeat_count++ < MAX_REPEATS));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Clear the display
|
* Clear the display using display command.
|
||||||
//
|
* \return Error code from ula200_ftdi_write_command.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_clear(Driver *drvthis)
|
ula200_ftdi_clear(Driver *drvthis)
|
||||||
{
|
{
|
||||||
//PrivateData *p = (PrivateData *) drvthis->private_data;
|
|
||||||
unsigned char command[1];
|
unsigned char command[1];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -395,9 +316,9 @@ ula200_ftdi_clear(Driver *drvthis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Set the position
|
* Set the position.
|
||||||
//
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_position(Driver *drvthis, int x, int y)
|
ula200_ftdi_position(Driver *drvthis, int x, int y)
|
||||||
{
|
{
|
||||||
@@ -424,13 +345,17 @@ ula200_ftdi_position(Driver *drvthis, int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Send raw data
|
* Send raw data.
|
||||||
//
|
*
|
||||||
|
* \param drvthis Pointer to driver
|
||||||
|
* \param flags Flag indicating byte is command or data
|
||||||
|
* \param ch Data byte to send
|
||||||
|
* \return Error code from ula200_ftdi_write_command.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_rawdata(Driver *drvthis, unsigned char flags, unsigned char ch)
|
ula200_ftdi_rawdata(Driver *drvthis, unsigned char flags, unsigned char ch)
|
||||||
{
|
{
|
||||||
//PrivateData *p = (PrivateData *) drvthis->private_data;
|
|
||||||
unsigned char command[3];
|
unsigned char command[3];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -446,13 +371,18 @@ ula200_ftdi_rawdata(Driver *drvthis, unsigned char flags, unsigned char ch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Displays a string
|
* Writes a string to the display.
|
||||||
//
|
*
|
||||||
|
* \param drvthis Pointer to driver
|
||||||
|
* \param string Pointer to string
|
||||||
|
* \param len Length of the string
|
||||||
|
* \return -EINVAL If the string is to long (max 80 characters)
|
||||||
|
* \return err Error code from ula200_ftdi_write_command
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_string(Driver *drvthis, const unsigned char *string, int len)
|
ula200_ftdi_string(Driver *drvthis, const unsigned char *string, int len)
|
||||||
{
|
{
|
||||||
//PrivateData *p = (PrivateData *) drvthis->private_data;
|
|
||||||
unsigned char buffer[128];
|
unsigned char buffer[128];
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
@@ -464,10 +394,10 @@ ula200_ftdi_string(Driver *drvthis, const unsigned char *string, int len)
|
|||||||
buffer[0] = 's';
|
buffer[0] = 's';
|
||||||
buffer[1] = len;
|
buffer[1] = len;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
buffer[i+2] = HD44780_charmap[(unsigned char)string[i]];
|
buffer[i + 2] = HD44780_charmap[(unsigned char)string[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ula200_ftdi_write_command(drvthis, buffer, len+2, true);
|
err = ula200_ftdi_write_command(drvthis, buffer, len + 2, true);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_WARNING, "%s: ula200_ftdi_string: "
|
report(RPT_WARNING, "%s: ula200_ftdi_string: "
|
||||||
"ula200_ftdi_write_command() failed", drvthis->name);
|
"ula200_ftdi_write_command() failed", drvthis->name);
|
||||||
@@ -477,9 +407,11 @@ ula200_ftdi_string(Driver *drvthis, const unsigned char *string, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Enables the raw register access mode.
|
* Enables the raw register access mode.
|
||||||
//
|
* \param drvthis Pointer to driver
|
||||||
|
* \return Error code from ula200_ftdi_write_command.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_ftdi_enable_raw_mode(Driver *drvthis)
|
ula200_ftdi_enable_raw_mode(Driver *drvthis)
|
||||||
{
|
{
|
||||||
@@ -493,82 +425,99 @@ ula200_ftdi_enable_raw_mode(Driver *drvthis)
|
|||||||
return ula200_ftdi_write_command(drvthis, command, 3, false);
|
return ula200_ftdi_write_command(drvthis, command, 3, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
// Loads custom characters in the display
|
* Loads custom characters in the display.
|
||||||
//
|
*/
|
||||||
static int
|
static int
|
||||||
ula200_load_custom_chars(Driver *drvthis)
|
ula200_load_custom_chars(Driver *drvthis)
|
||||||
{
|
{
|
||||||
int i, col, row;
|
int i, row;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
char custom_chars[8][CELLHEIGHT*CELLHEIGHT] = {
|
unsigned char mask = (1 << CELLWIDTH) - 1;
|
||||||
{ 1, 1, 1, 1, 1,
|
char custom_chars[8][CELLHEIGHT] = {
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1 },
|
|
||||||
{ 1, 1, 1, 1, 1,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0,
|
|
||||||
1, 0, 0, 0, 1,
|
|
||||||
1, 1, 0, 1, 1,
|
|
||||||
1, 1, 1, 1, 1 },
|
|
||||||
{ 1, 1, 1, 1, 1,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
0, 1, 0, 1, 0,
|
|
||||||
0, 1, 1, 1, 0,
|
|
||||||
0, 1, 1, 1, 0,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
1, 1, 0, 1, 1,
|
|
||||||
1, 1, 1, 1, 1 },
|
|
||||||
{ 0, 0, 1, 0, 0,
|
|
||||||
0, 1, 1, 1, 0,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0 },
|
|
||||||
{ 0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
0, 1, 1, 1, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0 },
|
|
||||||
{ 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 0, 0, 0, 1,
|
|
||||||
1, 0, 0, 0, 1,
|
|
||||||
1, 0, 0, 0, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0 },
|
|
||||||
{ 0, 0, 1, 0, 0,
|
|
||||||
0, 0, 1, 0, 0,
|
|
||||||
1, 1, 1, 0, 1,
|
|
||||||
1, 0, 1, 1, 0,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
1, 0, 0, 0, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0 },
|
|
||||||
{ 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
1, 1, 0, 1, 1,
|
|
||||||
1, 0, 1, 0, 1,
|
|
||||||
1, 1, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0 }};
|
|
||||||
|
|
||||||
for (i = 0; i < 8 && err == 0; i++)
|
|
||||||
{
|
{
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX,
|
||||||
|
b__XXXXX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b__XXXXX,
|
||||||
|
b__X_X_X,
|
||||||
|
b_______,
|
||||||
|
b_______,
|
||||||
|
b_______,
|
||||||
|
b__X___X,
|
||||||
|
b__XX_XX,
|
||||||
|
b__XXXXX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b__XXXXX,
|
||||||
|
b__X_X_X,
|
||||||
|
b___X_X_,
|
||||||
|
b___XXX_,
|
||||||
|
b___XXX_,
|
||||||
|
b__X_X_X,
|
||||||
|
b__XX_XX,
|
||||||
|
b__XXXXX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b____X__,
|
||||||
|
b___XXX_,
|
||||||
|
b__X_X_X,
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b_______
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b__X_X_X,
|
||||||
|
b___XXX_,
|
||||||
|
b____X__,
|
||||||
|
b_______
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b_______,
|
||||||
|
b_______,
|
||||||
|
b__XXXXX,
|
||||||
|
b__X___X,
|
||||||
|
b__X___X,
|
||||||
|
b__X___X,
|
||||||
|
b__XXXXX,
|
||||||
|
b_______
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b____X__,
|
||||||
|
b____X__,
|
||||||
|
b__XXX_X,
|
||||||
|
b__X_XX_,
|
||||||
|
b__X_X_X,
|
||||||
|
b__X___X,
|
||||||
|
b__XXXXX,
|
||||||
|
b_______
|
||||||
|
},
|
||||||
|
{
|
||||||
|
b_______,
|
||||||
|
b_______,
|
||||||
|
b__XXXXX,
|
||||||
|
b__X_X_X,
|
||||||
|
b__XX_XX,
|
||||||
|
b__X_X_X,
|
||||||
|
b__XXXXX,
|
||||||
|
b_______
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < 8 && err == 0; i++) {
|
||||||
/* Tell the HD44780 we will redefine char number i */
|
/* Tell the HD44780 we will redefine char number i */
|
||||||
ula200_ftdi_rawdata(drvthis, RS_INSTR, SETCHAR | i * 8);
|
ula200_ftdi_rawdata(drvthis, RS_INSTR, SETCHAR | i * 8);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@@ -578,12 +527,7 @@ ula200_load_custom_chars(Driver *drvthis)
|
|||||||
|
|
||||||
/* Send the subsequent rows */
|
/* Send the subsequent rows */
|
||||||
for (row = 0; row < CELLHEIGHT; row++) {
|
for (row = 0; row < CELLHEIGHT; row++) {
|
||||||
int value = 0;
|
int value = custom_chars[i][row] & mask;
|
||||||
|
|
||||||
for (col = 0; col < CELLWIDTH; col++) {
|
|
||||||
value <<= 1;
|
|
||||||
value |= (custom_chars[i][(row * CELLWIDTH) + col] > 0) ? 1 : 0;
|
|
||||||
}
|
|
||||||
err = ula200_ftdi_rawdata(drvthis, RS_DATA, value);
|
err = ula200_ftdi_rawdata(drvthis, RS_DATA, value);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_WARNING, "%s: ula200_ftdi_rawdata failed", drvthis->name);
|
report(RPT_WARNING, "%s: ula200_ftdi_rawdata failed", drvthis->name);
|
||||||
@@ -595,6 +539,7 @@ ula200_load_custom_chars(Driver *drvthis)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------- API functions ----------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the driver.
|
* Initialize the driver.
|
||||||
@@ -609,12 +554,12 @@ ula200_init(Driver *drvthis)
|
|||||||
int err, i;
|
int err, i;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
// Alocate and store private data
|
/* Allocate and store private data */
|
||||||
p = (PrivateData *) malloc( sizeof( PrivateData) );
|
p = (PrivateData *) malloc(sizeof(PrivateData));
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (drvthis->store_private_ptr(drvthis, p)) {
|
if (drvthis->store_private_ptr(drvthis, p)){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,7 +567,7 @@ ula200_init(Driver *drvthis)
|
|||||||
p->all_dirty = 1;
|
p->all_dirty = 1;
|
||||||
EmptyKeyRing(&p->keyring);
|
EmptyKeyRing(&p->keyring);
|
||||||
|
|
||||||
// Get and parse size
|
/* Get and parse size */
|
||||||
s = drvthis->config_get_string(drvthis->name, "size", 0, "20x4");
|
s = drvthis->config_get_string(drvthis->name, "size", 0, "20x4");
|
||||||
if ((sscanf(s, "%dx%d", &(p->width), &(p->height)) != 2)
|
if ((sscanf(s, "%dx%d", &(p->width), &(p->height)) != 2)
|
||||||
|| (p->width <= 0) || (p->width > LCD_MAX_WIDTH)
|
|| (p->width <= 0) || (p->width > LCD_MAX_WIDTH)
|
||||||
@@ -631,36 +576,36 @@ ula200_init(Driver *drvthis)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the keymap
|
/* read the keymap */
|
||||||
for (i = 0; i < MAX_KEY_MAP; i++) {
|
for (i = 0; i < MAX_KEY_MAP; i++) {
|
||||||
char buf[40];
|
char buf[40];
|
||||||
|
|
||||||
// First fill with default value
|
/* First fill with default value */
|
||||||
p->key_map[i] = default_key_map[i];
|
p->key_map[i] = default_key_map[i];
|
||||||
|
|
||||||
// Read config value
|
/* Read config value */
|
||||||
sprintf(buf, "KeyMap_%c", i+'A');
|
sprintf(buf, "KeyMap_%c", i + 'A');
|
||||||
s = drvthis->config_get_string(drvthis->name, buf, 0, NULL);
|
s = drvthis->config_get_string(drvthis->name, buf, 0, NULL);
|
||||||
|
|
||||||
// Was a key specified in the config file ?
|
/* Was a key specified in the config file ? */
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
p->key_map[i] = strdup(s);
|
p->key_map[i] = strdup(s);
|
||||||
report(RPT_INFO, "%s: Key '%c' mapped to \"%s\"",
|
report(RPT_INFO, "%s: Key '%c' mapped to \"%s\"",
|
||||||
drvthis->name, i+'A', s );
|
drvthis->name, i + 'A', s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of config file parsing */
|
/* End of config file parsing */
|
||||||
|
|
||||||
|
|
||||||
// Allocate framebuffer
|
/* Allocate framebuffer */
|
||||||
p->framebuf = (unsigned char *) malloc(p->width * p->height);
|
p->framebuf = (unsigned char *) malloc(p->width * p->height);
|
||||||
if (p->framebuf == NULL) {
|
if (p->framebuf == NULL) {
|
||||||
report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
|
report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
|
||||||
goto err_begin;
|
goto err_begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate and clear the buffer for incremental updates
|
/* Allocate and clear the buffer for incremental updates */
|
||||||
p->lcd_contents = (unsigned char *) malloc(p->width * p->height);
|
p->lcd_contents = (unsigned char *) malloc(p->width * p->height);
|
||||||
if (p->lcd_contents == NULL) {
|
if (p->lcd_contents == NULL) {
|
||||||
report(RPT_ERR, "%s: unable to allocate framebuffer backing store", drvthis->name);
|
report(RPT_ERR, "%s: unable to allocate framebuffer backing store", drvthis->name);
|
||||||
@@ -668,40 +613,40 @@ ula200_init(Driver *drvthis)
|
|||||||
}
|
}
|
||||||
memset(p->lcd_contents, 0, p->width * p->height);
|
memset(p->lcd_contents, 0, p->width * p->height);
|
||||||
|
|
||||||
// open the FTDI library
|
/* open the FTDI library */
|
||||||
ftdi_init(&p->ftdic);
|
ftdi_init(&p->ftdic);
|
||||||
(&p->ftdic)->usb_write_timeout = 20;
|
(&p->ftdic)->usb_write_timeout = 20;
|
||||||
(&p->ftdic)->usb_read_timeout = 20;
|
(&p->ftdic)->usb_read_timeout = 20;
|
||||||
|
|
||||||
// open the device
|
/* open the device */
|
||||||
err = ftdi_usb_open(&p->ftdic, DISPLAY_VENDOR_ID, DISPLAY_PRODUCT_ID);
|
err = ftdi_usb_open(&p->ftdic, DISPLAY_VENDOR_ID, DISPLAY_PRODUCT_ID);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_ERR, "%s: cannot open USB device", drvthis->name);
|
report(RPT_ERR, "%s: cannot open USB device", drvthis->name);
|
||||||
goto err_lcd;
|
goto err_lcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the baudrate
|
/* set the baudrate */
|
||||||
err = ftdi_set_baudrate(&p->ftdic, 19200);
|
err = ftdi_set_baudrate(&p->ftdic, 19200);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_ERR, "%s: cannot set baudrate", drvthis->name);
|
report(RPT_ERR, "%s: cannot set baudrate", drvthis->name);
|
||||||
goto err_ftdi;
|
goto err_ftdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set communication parameters
|
/* set communication parameters */
|
||||||
err = ftdi_set_line_property(&p->ftdic, BITS_8, STOP_BIT_1, EVEN);
|
err = ftdi_set_line_property(&p->ftdic, BITS_8, STOP_BIT_1, EVEN);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_ERR, "%s: cannot set line properties", drvthis->name);
|
report(RPT_ERR, "%s: cannot set line properties", drvthis->name);
|
||||||
goto err_ftdi;
|
goto err_ftdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// user is able to write commands
|
/* user is able to write commands */
|
||||||
err = ula200_ftdi_enable_raw_mode(drvthis);
|
err = ula200_ftdi_enable_raw_mode(drvthis);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_ERR, "%s: unable to enable the raw mode", drvthis->name);
|
report(RPT_ERR, "%s: unable to enable the raw mode", drvthis->name);
|
||||||
goto err_ftdi;
|
goto err_ftdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the chars
|
/* load the chars */
|
||||||
err = ula200_load_custom_chars(drvthis);
|
err = ula200_load_custom_chars(drvthis);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
report(RPT_ERR, "%s: unable to write the custom characters", drvthis->name);
|
report(RPT_ERR, "%s: unable to write the custom characters", drvthis->name);
|
||||||
@@ -715,12 +660,11 @@ ula200_init(Driver *drvthis)
|
|||||||
err_ftdi:
|
err_ftdi:
|
||||||
ftdi_usb_close(&p->ftdic);
|
ftdi_usb_close(&p->ftdic);
|
||||||
ftdi_deinit(&p->ftdic);
|
ftdi_deinit(&p->ftdic);
|
||||||
err_framebuf:
|
|
||||||
free(p->framebuf);
|
|
||||||
err_lcd:
|
err_lcd:
|
||||||
free(p->lcd_contents);
|
free(p->lcd_contents);
|
||||||
|
err_framebuf:
|
||||||
|
free(p->framebuf);
|
||||||
err_begin:
|
err_begin:
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,7 +701,7 @@ ula200_close(Driver *drvthis)
|
|||||||
* \return Number of characters the display is wide.
|
* \return Number of characters the display is wide.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT int
|
MODULE_EXPORT int
|
||||||
ula200_width (Driver *drvthis)
|
ula200_width(Driver *drvthis)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
return p->width;
|
return p->width;
|
||||||
@@ -770,7 +714,7 @@ ula200_width (Driver *drvthis)
|
|||||||
* \return Number of characters the display is high.
|
* \return Number of characters the display is high.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT int
|
MODULE_EXPORT int
|
||||||
ula200_height (Driver *drvthis)
|
ula200_height(Driver *drvthis)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
return p->height;
|
return p->height;
|
||||||
@@ -782,7 +726,7 @@ ula200_height (Driver *drvthis)
|
|||||||
* \param drvthis Pointer to driver structure.
|
* \param drvthis Pointer to driver structure.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
ula200_clear (Driver *drvthis)
|
ula200_clear(Driver *drvthis)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
memset(p->framebuf, ' ', p->width * p->height);
|
memset(p->framebuf, ' ', p->width * p->height);
|
||||||
@@ -798,14 +742,14 @@ ula200_clear (Driver *drvthis)
|
|||||||
* \param c Character that gets written.
|
* \param c Character that gets written.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
ula200_chr (Driver *drvthis, int x, int y, char c)
|
ula200_chr(Driver *drvthis, int x, int y, char c)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
y--;
|
y--;
|
||||||
x--;
|
x--;
|
||||||
|
|
||||||
if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height))
|
if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height))
|
||||||
p->framebuf[ (y * p->width) + x] = c;
|
p->framebuf[(y * p->width) + x] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -818,16 +762,16 @@ ula200_chr (Driver *drvthis, int x, int y, char c)
|
|||||||
* \param string String that gets written.
|
* \param string String that gets written.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
ula200_string (Driver *drvthis, int x, int y, const char string[])
|
ula200_string(Driver *drvthis, int x, int y, const char string[])
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
x --; // Convert 1-based coords to 0-based
|
x--; /* Convert 1-based coords to 0-based */
|
||||||
y --;
|
y--;
|
||||||
|
|
||||||
for (i = 0; string[i] != '\0'; i++) {
|
for (i = 0; string[i] != '\0'; i++) {
|
||||||
// Check for buffer overflows...
|
/* Check for buffer overflows... */
|
||||||
if ((y * p->width) + x + i > (p->width * p->height))
|
if ((y * p->width) + x + i > (p->width * p->height))
|
||||||
break;
|
break;
|
||||||
p->framebuf[(y * p->width) + x + i] = string[i];
|
p->framebuf[(y * p->width) + x + i] = string[i];
|
||||||
@@ -841,7 +785,7 @@ ula200_string (Driver *drvthis, int x, int y, const char string[])
|
|||||||
* \param on New backlight status.
|
* \param on New backlight status.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
ula200_backlight (Driver *drvthis, int on)
|
ula200_backlight(Driver *drvthis, int on)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
unsigned char command[2];
|
unsigned char command[2];
|
||||||
@@ -884,16 +828,16 @@ ula200_flush(Driver *drvthis)
|
|||||||
p->all_dirty = 0;
|
p->all_dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update LCD incrementally by comparing with last contents
|
/* Update LCD incrementally by comparing with last contents */
|
||||||
count = 0;
|
count = 0;
|
||||||
for (y = 0; y < p->height; y++) {
|
for (y = 0; y < p->height; y++) {
|
||||||
drawing = 0;
|
drawing = 0;
|
||||||
firstdiff = -1;
|
firstdiff = -1;
|
||||||
lastdiff = 0;
|
lastdiff = 0;
|
||||||
for (x = 0 ; x < wid; x++) {
|
for (x = 0; x < wid; x++) {
|
||||||
ch = p->framebuf[(y * wid) + x];
|
ch = p->framebuf[(y * wid) + x];
|
||||||
if (ch != p->lcd_contents[(y*wid)+x]) {
|
if (ch != p->lcd_contents[(y * wid) + x]) {
|
||||||
p->lcd_contents[(y*wid)+x] = ch;
|
p->lcd_contents[(y * wid) + x] = ch;
|
||||||
if (firstdiff == -1) {
|
if (firstdiff == -1) {
|
||||||
firstdiff = x;
|
firstdiff = x;
|
||||||
}
|
}
|
||||||
@@ -903,7 +847,7 @@ ula200_flush(Driver *drvthis)
|
|||||||
|
|
||||||
if (firstdiff >= 0) {
|
if (firstdiff >= 0) {
|
||||||
ula200_ftdi_position(drvthis, firstdiff, y);
|
ula200_ftdi_position(drvthis, firstdiff, y);
|
||||||
ula200_ftdi_string(drvthis, p->framebuf + (y*wid) + firstdiff,
|
ula200_ftdi_string(drvthis, p->framebuf + (y * wid) + firstdiff,
|
||||||
lastdiff - firstdiff + 1);
|
lastdiff - firstdiff + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -920,9 +864,8 @@ ula200_flush(Driver *drvthis)
|
|||||||
* \retval <0 Server core shall define/write the icon.
|
* \retval <0 Server core shall define/write the icon.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT int
|
MODULE_EXPORT int
|
||||||
ula200_icon (Driver *drvthis, int x, int y, int icon)
|
ula200_icon(Driver *drvthis, int x, int y, int icon)
|
||||||
{
|
{
|
||||||
/* Yes I know, this is a VERY BAD implementation */
|
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
case ICON_BLOCK_FILLED:
|
case ICON_BLOCK_FILLED:
|
||||||
ula200_chr(drvthis, x, y, 0xff);
|
ula200_chr(drvthis, x, y, 0xff);
|
||||||
@@ -968,22 +911,24 @@ ula200_icon (Driver *drvthis, int x, int y, int icon)
|
|||||||
* \c NULL for nothing available / unmapped key.
|
* \c NULL for nothing available / unmapped key.
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT const char *
|
MODULE_EXPORT const char *
|
||||||
ula200_get_key (Driver *drvthis)
|
ula200_get_key(Driver *drvthis)
|
||||||
{
|
{
|
||||||
PrivateData *p = drvthis->private_data;
|
PrivateData *p = drvthis->private_data;
|
||||||
unsigned char key;
|
unsigned char key;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// The libftdi has no non-blocking read (`select' system call), so we force
|
/*
|
||||||
// a read that could not block by updating one character on the display.
|
* The libftdi has no non-blocking read (`select' system call), so we
|
||||||
// As long as lcdproc is single-threaded, we can write to the display because
|
* force a read that could not block by updating one character on the
|
||||||
// we're not inside a read here.
|
* display. As long as lcdproc is single-threaded, we can write to
|
||||||
|
* the display because we're not inside a read here.
|
||||||
|
*/
|
||||||
ula200_ftdi_position(drvthis, 0, 0);
|
ula200_ftdi_position(drvthis, 0, 0);
|
||||||
ula200_ftdi_string(drvthis, p->lcd_contents, 1);
|
ula200_ftdi_string(drvthis, p->lcd_contents, 1);
|
||||||
|
|
||||||
key = GetKeyFromKeyRing(&p->keyring);
|
key = GetKeyFromKeyRing(&p->keyring);
|
||||||
|
|
||||||
// search the bit that was set by the hardware
|
/* search the bit that was set by the hardware */
|
||||||
for (i = 0; i < MAX_KEY_MAP; i++) {
|
for (i = 0; i < MAX_KEY_MAP; i++) {
|
||||||
if (key & (1 << i))
|
if (key & (1 << i))
|
||||||
return p->key_map[i];
|
return p->key_map[i];
|
||||||
@@ -994,4 +939,3 @@ ula200_get_key (Driver *drvthis)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-26
@@ -1,33 +1,28 @@
|
|||||||
/* This is the LCDproc driver header for ULA-200 (http://www.elv.de)
|
/** \file server/drivers/ula200.h
|
||||||
|
* This is the LCDproc driver header for ULA-200 (http://www.elv.de).
|
||||||
|
*/
|
||||||
|
|
||||||
Author: bernhard.walle@gmx.de
|
/*-
|
||||||
|
* Copyright (C) 2006 Bernhard Walle <bernhard.walle@gmx.de>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
|
||||||
Copyright (C) 2006, Bernhard Walle
|
* 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.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
* You should have received a copy of the GNU General Public License
|
||||||
it under the terms of the GNU General Public License as published by
|
* along with this program; if not, write to the Free Software
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
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 */
|
|
||||||
#ifndef ULA200_H
|
#ifndef ULA200_H
|
||||||
#define ULA200_H
|
#define ULA200_H
|
||||||
|
|
||||||
#include "lcd.h"
|
|
||||||
|
|
||||||
#ifndef bool
|
|
||||||
# define bool short
|
|
||||||
# define true 1
|
|
||||||
# define false 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODULE_EXPORT int ula200_init(Driver *drvthis);
|
MODULE_EXPORT int ula200_init(Driver *drvthis);
|
||||||
MODULE_EXPORT void ula200_close (Driver *drvthis);
|
MODULE_EXPORT void ula200_close (Driver *drvthis);
|
||||||
MODULE_EXPORT int ula200_width (Driver *drvthis);
|
MODULE_EXPORT int ula200_width (Driver *drvthis);
|
||||||
@@ -37,9 +32,7 @@ MODULE_EXPORT void ula200_string (Driver *drvthis, int x, int y, const char stri
|
|||||||
MODULE_EXPORT void ula200_chr (Driver *drvthis, int x, int y, char c);
|
MODULE_EXPORT void ula200_chr (Driver *drvthis, int x, int y, char c);
|
||||||
MODULE_EXPORT void ula200_backlight (Driver *drvthis, int on);
|
MODULE_EXPORT void ula200_backlight (Driver *drvthis, int on);
|
||||||
MODULE_EXPORT void ula200_flush (Driver *drvthis);
|
MODULE_EXPORT void ula200_flush (Driver *drvthis);
|
||||||
MODULE_EXPORT void ula200_vbar (Driver *drvthis, int x, int y, int len, int promille, int options);
|
|
||||||
MODULE_EXPORT void ula200_hbar (Driver *drvthis, int x, int y, int len, int promille, int options);
|
|
||||||
MODULE_EXPORT void ula200_num (Driver *drvthis, int x, int num);
|
|
||||||
MODULE_EXPORT int ula200_icon(Driver *drvthis, int x, int y, int icon);
|
MODULE_EXPORT int ula200_icon(Driver *drvthis, int x, int y, int icon);
|
||||||
MODULE_EXPORT const char * ula200_get_key (Driver *drvthis);
|
MODULE_EXPORT const char * ula200_get_key (Driver *drvthis);
|
||||||
|
|
||||||
#endif /* ULA200_H */
|
#endif /* ULA200_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user