diff --git a/ChangeLog b/ChangeLog
index 7cb3fe7..fb479e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,7 @@ v.0.5dev (ongoing development)
* All drivers: sync functions with prototypes
* Port remaining drivers to 0.5 API (glk, lcdm001, stv5730)
* Pyramid: Only send LED state changes, doxygen-ize
+ * sed1520: Make it work with 68-family style interface, convert to 0.5 API
v0.5.4
* Update driver includes and LDFLAGS (fixed glk and bayrad binding error)
diff --git a/docs/lcdproc-user/drivers/sed1520.docbook b/docs/lcdproc-user/drivers/sed1520.docbook
index 1d3ca34..4c0d479 100644
--- a/docs/lcdproc-user/drivers/sed1520.docbook
+++ b/docs/lcdproc-user/drivers/sed1520.docbook
@@ -3,14 +3,229 @@
This section talks about using LCDproc with LCD displays that use the
-sed1520 chipset.
+SED1520 chipset.
Currently the driver supports 122x32 pixel graphic displays based on
-the SED1520 Controller connected to the parallel port.
+the SED1520 controller connected to the parallel port.
+
+Those SED1520 displays are the most troublesome I have ever used. You
+should probably avoid using them and get a 20x4 text display instead.
+
+
+
+Connections
+
+Displays using SED1520 come in a wide variety of configurations. It is
+possible to cause harm to your display (e.g. connecting negative voltage
+incorrectly. Be sure to check your datasheet! Do not try to use a display
+without having a datasheet to check against!
+Here here some of the options I encountered:
+
+ Negative voltage: The chip requires negative voltage for
+ driving the display. Some display modules have a negative voltage converter
+ on-board. On those that don't you have to supply about -7 V (will not
+ show how to do this).
+ Reset circuit: Some display modules have an R/C-combination
+ on-board selecting an MCU interface if the pin is not connected.
+ Frequency generator: The SED1520 is manufactured in several
+ versions. Some contain an on-chip frequency generator, others require an external
+ clock of 2 kHz (won't show this here). Note that display modules with an
+ on-chip generator do not have a /CS (chip select) line.
+ Incorrect datasheets: I have seen display datasheets
+ incorrectly naming pins, missing some of the commands, missing pages from the
+ chip description and other odds. Be warned!
+ No pin numbers are given in the tables below. You have to
+ figure out those yourself from the datasheet for your display!
+
+
+
+That said here some wirings:
+
+
+80-style connection style
+
+This mode of operation is selected if the RESET line is wired to ground.
+The wiring used by this driver in 80-style mode requires the use of an external
+74HC04 inverter and assumes you have /CS1 and /CS2 lines available (thus you
+must have an external clock generator) and toggles the /RW line. This is the
+original wiring by Robin Adams.
+
+
+SED1520 80-style wiring schematic
+
+
+
+
+
+
+
+
+ Parallel port
+ <->
+ LCD
+
+
+ name
+ pin
+ name
+ pin
+
+
+
+
+ D0-D7
+ 2-9
+
+ DB0-DB7
+ *
+
+
+ nSTRB
+ 1
+
+ /WR
+ *
+
+
+ nLF
+ 14
+
+ /CS1
+ *
+
+
+ INIT
+ 16
+
+ /CS2
+ *
+
+
+ nSEL
+ 17
+
+ A0
+ *
+
+
+
+
+ VDD
+ /RD
+ *
+
+
+
+
+ GND
+ RESET/IF
+ *
+
+
+
+
+ 2 kHz clock
+ CL
+ *
+
+
+
+
+
+
+
+68-style connection style
+
+This mode of operation is selected if the RESET line is wired to VDD.
+For this wiring the display is required to have an on-board frequency generator
+(something you really want to have) and the display module has an E1 and E2
+line. Writing is controlled by toggling the E1 and E2 line while /RW is low.
+
+
+
+SED1520 68-style wiring schematic
+
+
+
+
+
+
+
+
+ Parallel port
+ <->
+ LCD
+
+
+ name
+ pin
+ name
+ pin
+
+
+
+
+ D0-D7
+ 2-9
+
+ DB0-DB7
+ *
+
+
+ nSTRB
+ 1
+
+ R/-W
+ *
+
+
+ nLF
+ 14
+
+ E1
+ *
+
+
+ INIT
+ 16
+
+ E2
+ *
+
+
+ nSEL
+ 17
+
+ A0
+ *
+
+
+
+
+ VDD
+ RESET/IF
+ *
+
+
+
+
+
+
+This is the only wiring I was able to test. My display (Crystalfontz
+CFAG12232J-TFH-TA) has E1 and E2 lines. Trying to use it with 80-style wiring
+was not successful. I suspect that (as the E# line is used as /RD line in
+80-style mode) the wiring resulted in reading from one chip while writing to
+the other at the same time and the data bus got fuzzed.
+
+
+
+
+
+
Configuration in LCDd.conf
@@ -31,6 +246,36 @@ the SED1520 Controller connected to the parallel port.
The default value is 0x378.
+
+
+
+ InterfaceType =
+ INTERFACE
+
+
+ The SED1520 chip can be driven with one of two interface types selected by
+ the level of the RESET line: 68-style MCU interface (high level) or
+ 80-style MCU interface (low level).
+
+ Use value 68 if your display is connected 68-style
+ style. In this mode the E1 and E2 lines are cycled to write the data. If
+ you use 80 (the default), 80-style style is selected
+ and the /WR line is cycled and /CS1 and /CS2 lines are required.
+
+
+
+
+
+ DelayMult =
+ DELAY
+
+
+ This value adds an additional delay to each write, in microseconds. For
+ the 80-style connection type actual two delays are added each. The
+ default value of 1 already slows down communication a
+ lot, larger value should likely be avoided.
+
+
diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c
index 42def86..565c6d2 100644
--- a/server/drivers/sed1520.c
+++ b/server/drivers/sed1520.c
@@ -2,19 +2,14 @@
* LCDd \c sed1520 driver for graphic displays based on the SED1520.
*
* This is a driver for 122x32 pixel graphic displays based on the SED1520
- * controller connected to the parallel port. Check http://www.usblcd.de/lcdproc/
- * for where to buy and how to build the hardware. This Controller has no
+ * controller connected to the parallel port. This Controller has no
* built in character generator. Therefore all fonts and pixels are generated
* by this driver.
- *
- * \todo Convert to 0.5 style hbar / vbar API.
*/
/*-
- * (C) 2001 Robin Adams ( robin@adams-online.de )
- *
- * The HD44780 font in sed1520fm.c was shamelessly stolen from
- * Michael Reinelt / lcd4linux and is (C) 2000 by him.
+ * Copyright (C) 2001 Robin Adams
+ * 2011 Markus Dolze
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
@@ -22,8 +17,14 @@
/*-
* Driver history:
- * Moved the delay timing code by Charles Steinkuehler to timing.h.
- * Guillaume Filion , December 2001
+ * 2001, Guillaume Filion :
+ * - Moved the delay timing code by Charles Steinkuehler to timing.h.
+ * 2011, Markus Dolze:
+ * - Add 68-familiy style interface support and make it configurable
+ * - Make delay configurable
+ * - Correct swapped display halves
+ * - Resurrect vBar / hBar functions
+ * - Fix icon definitions and modify set_char for common data format
*/
#ifdef HAVE_CONFIG_H
@@ -45,9 +46,9 @@
#include "port.h"
#include "timing.h"
#include "sed1520fm.h"
+#include "lpt-port.h"
#define uPause timing_uPause
-#define IODELAY 500
#ifndef DEFAULT_PORT
# define DEFAULT_PORT 0x378
@@ -62,14 +63,16 @@
#define WIDTH ((int) (PIXELWIDTH / CELLWIDTH)) /* 20 */
#define HEIGHT ((int) (PIXELHEIGHT / CELLHEIGHT)) /* 4 */
-#define A0 0x08 /* nSEL */
-#define CS2 0x04 /* INIT */
-#define CS1 0x02 /* nLF */
-#define WR 0x01 /* nSTRB */
+#define A0 nSEL /* pin 17 */
+#define CS1 nLF /* pin 14 */
+#define CS2 INIT /* pin 16 */
+#define WR nSTRB /* pin 1 */
/** private data for the \c sed1520 driver */
typedef struct sed1520_private_data {
- unsigned int port;
+ unsigned short port;
+ int interface;
+ int delayMult;
unsigned char *framebuf;
} PrivateData;
@@ -83,71 +86,106 @@ MODULE_EXPORT char *symbol_prefix = "sed1520_";
/**
* Writes command value to one or both sed1520 selected by chip.
- * \param port Output port base address
+ * \param p Pointer to private data structure
* \param value Command byte to write
* \param chip Bitmap of controllers to send value to
+ *
+ * \note It is a little code duplication having writecommand and writedata
+ * both, but I leave it that way.
*/
void
-writecommand(unsigned int port, int value, int chip)
+writecommand(PrivateData *p, int value, int chip)
{
- port_out(port, value);
- /*
- * lower WR, rise A0 and CS1 and/or CS2. Take bit inversion of parallel
- * port into account.
- */
- port_out(port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
- /* rise WR */
- port_out(port + 2, CS1 - (chip & CS1) + (chip & CS2));
- uPause(IODELAY);
- /* lower WR again */
- port_out(port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
- uPause(IODELAY);
+ if (p->interface == 68) {
+ port_out(p->port + 2, 0 ^ OUTMASK);
+ port_out(p->port, value);
+ /* cycle E */
+ port_out(p->port + 2, ((chip & CS1) + (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult) uPause(p->delayMult);
+ port_out(p->port + 2, 0 ^ OUTMASK);
+ }
+ else {
+ port_out(p->port, value);
+ /*
+ * lower WR, rise A0 and CS1 and/or CS2. Take bit inversion of parallel
+ * port into account. External inverter required!
+ */
+ port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
+ /* rise WR */
+ port_out(p->port + 2, CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult) uPause(p->delayMult);
+ /* lower WR again */
+ port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult) uPause(p->delayMult);
+ }
}
/**
* Writes data value to one or both sed 1520 selected by chip.
- * \param port Output port base address
+ * \param p Pointer to private data structure
* \param value Data byte to write
* \param chip Bitmap of controllers to send value to
*/
void
-writedata(unsigned int port, int value, int chip)
+writedata(PrivateData *p, int value, int chip)
{
- port_out(port, value);
- /*
- * lower WR and A0, rise CS1 and/or CS2. Take bit inversion of parallel
- * port into account.
- */
- port_out(port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
- port_out(port + 2, A0 + CS1 - (chip & CS1) + (chip & CS2));
- uPause(IODELAY);
- port_out(port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
- uPause(IODELAY);
+ if (p->interface == 68) {
+ port_out(p->port + 2, (A0) ^ OUTMASK);
+ port_out(p->port, value);
+ /* cycle E */
+ port_out(p->port + 2, (A0 + (chip & CS1) + (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult) uPause(p->delayMult);
+ port_out(p->port + 2, (A0) ^ OUTMASK);
+ }
+ else {
+ port_out(p->port, value);
+ /* lower WR and A0, rise CS1 and/or CS2. See also writecommand. */
+ port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
+ port_out(p->port + 2, A0 + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult) uPause(p->delayMult);
+ port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult) uPause(p->delayMult);
+ }
}
/**
* Selects a page (=row) on both sed1520s.
- * \param port Output port base address
+ * \param p Pointer to private data structure
* \param page Page (=row) number (0-3)
*/
void
-selectpage(unsigned int port, int page)
+selectpage(PrivateData *p, int page)
{
- writecommand(port, 0xB8 + (page & 0x03), CS1 + CS2);
+ writecommand(p, PAGE_ADR + (page & 0x03), CS1 + CS2);
}
/**
- * Selects a column on the sed1520s specified by chip.
- * \param port Output port base address
- * \param column Select column (segment) in controller (0-79)
+ * Selects a column on the sed1520 specified by chip.
+ * \param p Pointer to private data structure
+ * \param column Select column (segment) in controller (0-60)
* \param chip Bitmap of controllers to send value to
*/
void
-selectcolumn(unsigned int port, int column, int chip)
+selectcolumn(PrivateData *p, int column, int chip)
{
- writecommand(port, (column & 0x7F), chip);
+ writecommand(p, COLUMN_ADR + (column & 0x7F), chip);
}
+/*-
+ * Display memory layout information:
+ *
+ * The SED1520 does not use a linear display data memory but a paged memory
+ * with four pages (0-3) corresponding to rows 0-7, 8-15, 16-23, and 24-31.
+ * Within each page, one bytes represents 8 pixels of one column (from 0-60)
+ * with bit 0 (LSB) being the top and bit 7 (MSB) the bottom pixel within
+ * that page.
+ *
+ * To write data to display memory one selects the page and column and then
+ * writes bytes of pixel data to the display. The column counter is increased
+ * by each write so the display fills from left ro right (the SED1520 can
+ * also be configured to write from right to left).
+ */
+
/**
* Draws character z from fontmap to the framebuffer at position x,y.
* The Fontmap is stored in rows while the framebuffer is stored in columns,
@@ -202,6 +240,13 @@ sed1520_init(Driver * drvthis)
report(RPT_ERR, "%s: timing_init() failed (%s)", drvthis->name, strerror(errno));
return -1;
}
+ p->delayMult = drvthis->config_get_int(drvthis->name, "delaymult", 0, 1);
+ if (p->delayMult < 0 || p->delayMult > 1000) {
+ report(RPT_WARNING, "%s: DelayMult value invalid, using default (1)", drvthis->name);
+ p->delayMult = 1;
+ }
+ if (p->delayMult == 0)
+ report(RPT_INFO, "%s: Delay is disabled", drvthis->name);
/* Allocate our framebuffer */
p->framebuf = (unsigned char *) calloc(PIXELWIDTH * HEIGHT, sizeof(unsigned char));
@@ -214,18 +259,23 @@ sed1520_init(Driver * drvthis)
memset(p->framebuf, '\0', PIXELWIDTH * HEIGHT);
/* Open port */
- if (port_access(p->port) || port_access(p->port + 2)) {
+ if (port_access_multiple(p->port, 3)) {
report(RPT_ERR, "%s: unable to access port 0x%03X", drvthis->name, p->port);
return -1;
}
+ /* Get interface style (68-family or 80-family) */
+ p->interface = drvthis->config_get_int(drvthis->name, "InterfaceType", 0, 80);
+ if (p->interface != 68 && p->interface != 80) {
+ report(RPT_WARNING, "%s: Invalid interface configured, using type 80", drvthis->name);
+ p->interface = 80;
+ }
+
/* Initialize display */
- port_out(p->port, 0);
- port_out(p->port + 2, WR + CS2);
- writecommand(p->port, 0xE2, CS1 + CS2); /* software reset */
- writecommand(p->port, 0xAF, CS1 + CS2); /* display on */
- writecommand(p->port, 0xC0, CS1 + CS2); /* display start address */
- selectpage(p->port, 3);
+ writecommand(p, SOFT_RESET, CS1 + CS2);
+ writecommand(p, DISP_ON, CS1 + CS2);
+ writecommand(p, DISP_START_LINE, CS1 + CS2);
+ selectpage(p, 3);
report(RPT_DEBUG, "%s: init() done", drvthis->name);
return 0;
@@ -306,18 +356,18 @@ sed1520_flush(Driver * drvthis)
int i, j;
for (i = 0; i < HEIGHT; i++) {
- /* select line */
- selectpage(p->port, i);
+ /* select line/page */
+ selectpage(p, i);
/* update left half of display */
- selectcolumn(p->port, 0, CS2);
+ selectcolumn(p, 0, CS1);
for (j = 0; j < PIXELWIDTH / 2; j++)
- writedata(p->port, p->framebuf[j + (i * PIXELWIDTH)], CS2);
+ writedata(p, p->framebuf[j + (i * PIXELWIDTH)], CS1);
/* update right half of display */
- selectcolumn(p->port, 0, CS1);
+ selectcolumn(p, 0, CS2);
for (j = PIXELWIDTH / 2; j < PIXELWIDTH; j++)
- writedata(p->port, p->framebuf[j + (i * PIXELWIDTH)], CS1);
+ writedata(p, p->framebuf[j + (i * PIXELWIDTH)], CS2);
}
}
@@ -406,7 +456,7 @@ sed1520_num(Driver * drvthis, int x, int num)
/**
* API: Changes the font of character n to a pattern given by *dat.
- * HD44780 Controllers only posses 8 programmable chars. But we store the
+ * HD44780 controllers only posses 8 programmable chars. But we store the
* fontmap completely in RAM, so every character can be altered.
*
* Important: Characters have to be redrawn by drawchar2fb() to show their
@@ -416,76 +466,80 @@ sed1520_num(Driver * drvthis, int x, int num)
MODULE_EXPORT void
sed1520_set_char(Driver * drvthis, int n, char *dat)
{
- int row, col;
+ int row;
+ unsigned char mask = (1 << CELLWIDTH) - 1;
if (n < 0 || n > 255)
return;
if (!dat)
return;
- for (row = 0; row < CELLHEIGHT; row++) {
- int i = 0;
-
- for (col = 0; col < CELLWIDTH; col++)
- i = (i << 1) | (dat[(row * CELLWIDTH) + col] > 0);
-
- fontmap[n][row] = i;
- }
+ for (row = 0; row < CELLHEIGHT; row++)
+ fontmap[n][row] = dat[row] & mask;
}
-
-/*
- * Draws a vertical from the bottom up to the last 3 rows of the framebuffer
- * at 1-based position x. len is given in pixels.
+/**
+ * API: Draws a vertical from the bottom up at 1-based position x.
*/
MODULE_EXPORT void
-sed1520_old_vbar(Driver * drvthis, int x, int len)
+sed1520_vbar(Driver *drvthis, int x, int y, int len, int promille, int options)
{
PrivateData *p = drvthis->private_data;
int i, j, k;
+ int pixels;
x--;
+ if (x < 0 || y < 1 || x >= WIDTH || y > HEIGHT || len > HEIGHT)
+ return;
+
+ pixels = len * CELLHEIGHT * promille / 1000;
+
for (j = 0; j < 3; j++) {
k = 0;
/* Set height of block. Bottom is leftmost bit */
for (i = 0; i < CELLHEIGHT; i++) {
- if (len > i)
+ if (pixels > i)
k |= (1 << (CELLHEIGHT - 1 - i));
}
/* Draw directly into framebuffer starting from bottom */
p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 0] = 0;
- p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 1] = 0;
+ p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 1] = k;
p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 2] = k;
p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 3] = k;
p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 4] = k;
p->framebuf[((3 - j) * PIXELWIDTH) + (x * CELLWIDTH) + 5] = 0;
- len -= CELLHEIGHT;
+ pixels -= CELLHEIGHT;
}
}
-
-/*
- * Draws a horizontal bar from left to right at 1-based position x,y into the
- * framebuffer. len is given in pixels.
+/**
+ * API: Draws a horizontal bar from left to right at 1-based position x,y into
+ * the framebuffer.
*/
MODULE_EXPORT void
-sed1520_old_hbar(Driver * drvthis, int x, int y, int len)
+sed1520_hbar(Driver *drvthis, int x, int y, int len, int promille, int options)
{
PrivateData *p = drvthis->private_data;
int i;
+ int pixels;
x--;
y--;
- if ((y < 0) || (y >= HEIGHT) || (x < 0) || (len < 0) || ((x + (len / CELLWIDTH)) >= WIDTH))
+ if ((y < 0) || (y >= HEIGHT) || (x < 0) || (len < 0) || (x + len > WIDTH))
return;
- /* Draw directly into framebuffer. Use 4 dots in the middle (0x3C). */
- for (i = 0; i < len; i++)
- p->framebuf[(y * PIXELWIDTH) + (x * CELLWIDTH) + i] = 0x3C;
+ pixels = len * CELLWIDTH * promille / 1000;
+
+ /*
+ * Draw directly into framebuffer. Drawing is easy, as one byte is one
+ * column in a page. Use 5 dots in the middle (0x3E).
+ */
+ for (i = 0; i < pixels; i++)
+ p->framebuf[(y * PIXELWIDTH) + (x * CELLWIDTH) + i] = 0x3E;
}
/**
@@ -496,26 +550,26 @@ sed1520_icon(Driver * drvthis, int x, int y, int icon)
{
static char heart_open[] =
{
- 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
+ b_OOOOO,
+ b_O_O_O,
+ b______,
+ b______,
+ b______,
+ b_O___O,
+ b_OO_OO,
+ b_OOOOO
};
static char heart_filled[] =
{
- 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
+ b_OOOOO,
+ b_O_O_O,
+ b__O_O_,
+ b__OOO_,
+ b__OOO_,
+ b_O_O_O,
+ b_OO_OO,
+ b_OOOOO
};
switch (icon) {
diff --git a/server/drivers/sed1520.h b/server/drivers/sed1520.h
index 123fbc4..89c366d 100644
--- a/server/drivers/sed1520.h
+++ b/server/drivers/sed1520.h
@@ -3,6 +3,20 @@
#include "lcd.h"
+/* Commands for SED1520 */
+#define DISP_OFF 0xAE
+#define DISP_ON 0xAF
+#define DISP_START_LINE 0xC0
+#define PAGE_ADR 0xB8
+#define COLUMN_ADR 0x00
+#define ADC_NORM 0xA0 /* left-to-right */
+#define ADC_INV 0xA1 /* right-to-left */
+#define STATIC_DR_OFF 0xA4 /* normal operation */
+#define STATIC_DR_ON 0xA5 /* power safe */
+#define DUTY_1_16 0xA8
+#define DUTY_1_32 0xA9
+#define SOFT_RESET 0xE2
+
MODULE_EXPORT int sed1520_init (Driver *drvthis);
MODULE_EXPORT void sed1520_close (Driver *drvthis);
MODULE_EXPORT int sed1520_width (Driver *drvthis);
diff --git a/server/drivers/sed1520fm.c b/server/drivers/sed1520fm.c
index bdabef5..5e78fe4 100644
--- a/server/drivers/sed1520fm.c
+++ b/server/drivers/sed1520fm.c
@@ -11,42 +11,9 @@
// package for further details. //
//////////////////////////////////////////////////////////////////////////
-#define b______ 0x00
-#define b_____O 0x01
-#define b____O_ 0x02
-#define b____OO 0x03
-#define b___O__ 0x04
-#define b___O_O 0x05
-#define b___OO_ 0x06
-#define b___OOO 0x07
-#define b__O___ 0x08
-#define b__O__O 0x09
-#define b__O_O_ 0x0a
-#define b__O_OO 0x0b
-#define b__OO__ 0x0c
-#define b__OO_O 0x0d
-#define b__OOO_ 0x0e
-#define b__OOOO 0x0f
-#define b_O____ 0x10
-#define b_O___O 0x11
-#define b_O__O_ 0x12
-#define b_O__OO 0x13
-#define b_O_O__ 0x14
-#define b_O_O_O 0x15
-#define b_O_OO_ 0x16
-#define b_O_OOO 0x17
-#define b_OO___ 0x18
-#define b_OO__O 0x19
-#define b_OO_O_ 0x1a
-#define b_OO_OO 0x1b
-#define b_OOO__ 0x1c
-#define b_OOO_O 0x1d
-#define b_OOOO_ 0x1e
-#define b_OOOOO 0x1f
-#define b_OOOOO 0x1f
-#define bOOOOOO 0x3f
+#include "sed1520fm.h"
-unsigned char fontmap[256][8] = {
+char fontmap[256][8] = {
[0x20] {b______,
b______,
b______,
diff --git a/server/drivers/sed1520fm.h b/server/drivers/sed1520fm.h
index efa728c..86664ba 100644
--- a/server/drivers/sed1520fm.h
+++ b/server/drivers/sed1520fm.h
@@ -1,8 +1,43 @@
#ifndef SED1520FM_H
#define SED1520FM_H
-unsigned char fontmap[256][8];
-unsigned char *fontbignum[10][24];
-unsigned char *fontbigdp[24];
+#define b______ 0x00
+#define b_____O 0x01
+#define b____O_ 0x02
+#define b____OO 0x03
+#define b___O__ 0x04
+#define b___O_O 0x05
+#define b___OO_ 0x06
+#define b___OOO 0x07
+#define b__O___ 0x08
+#define b__O__O 0x09
+#define b__O_O_ 0x0a
+#define b__O_OO 0x0b
+#define b__OO__ 0x0c
+#define b__OO_O 0x0d
+#define b__OOO_ 0x0e
+#define b__OOOO 0x0f
+#define b_O____ 0x10
+#define b_O___O 0x11
+#define b_O__O_ 0x12
+#define b_O__OO 0x13
+#define b_O_O__ 0x14
+#define b_O_O_O 0x15
+#define b_O_OO_ 0x16
+#define b_O_OOO 0x17
+#define b_OO___ 0x18
+#define b_OO__O 0x19
+#define b_OO_O_ 0x1a
+#define b_OO_OO 0x1b
+#define b_OOO__ 0x1c
+#define b_OOO_O 0x1d
+#define b_OOOO_ 0x1e
+#define b_OOOOO 0x1f
+#define b_OOOOO 0x1f
+#define bOOOOOO 0x3f
+
+char fontmap[256][8];
+char *fontbignum[10][24];
+char *fontbigdp[24];
#endif