diff --git a/docs/lcdproc-user/Makefile.am b/docs/lcdproc-user/Makefile.am
index e16d6d7..79ff064 100644
--- a/docs/lcdproc-user/Makefile.am
+++ b/docs/lcdproc-user/Makefile.am
@@ -19,7 +19,7 @@ EXTRA_DIST = bookinfo.docbook \
## convenience targets
xmlto ?= /usr/bin/xmlto
-userguidedir = $(DESTDIR)$(htmldir)/user-guide/
+userguidedir ?= $(DESTDIR)$(htmldir)/user-guide/
.PHONY: install-html-userguide
diff --git a/docs/lcdproc-user/drivers/sed1330.docbook b/docs/lcdproc-user/drivers/sed1330.docbook
index 374d1ec..4bf35f3 100644
--- a/docs/lcdproc-user/drivers/sed1330.docbook
+++ b/docs/lcdproc-user/drivers/sed1330.docbook
@@ -8,7 +8,8 @@ new names: S1D13300 (= SED1330) and S1D13305 (= SED1335).
-The displays are driven in text mode using their built-in character generator.
+The displays are driven in text mode using their built-in character generator
+and the graphic mode for bars and the heartbeat icon (a bouncing ball).
@@ -16,423 +17,246 @@ The displays are driven in text mode using their built-in character generator.
-Connections below are for the G242C, G121C and G321D displays.
-Always consult documentation about the specific display before asuming
-the connections given here are also correct for your display !
+Displays using SED1330/1335 chipset come in a variety of pin-outs and power
+configurations. They usually require negative voltage for contrast and some
+displays have a negative voltage generator onboard.
+
+
+Connections below are for the G242C, G121C and G321D displays. Always consult
+documentation about the specific display before asuming the connections given
+here are also correct for your display!
-
-ConnectionType classic ordered by LCD pins
+
+ConnectionType classic ordered by LPT port pins
-
-
+
+
-
-
+
+
- LCD
- <->
LPT port
+ <->
+ LCD
- name
- pin
pin
name
+ name
+ pin
- ^RESET
- 1
-
1
^STROBE
+
+ ^RESET
+ 1
- ^RD
- 2
- +5V
-
+ 2-9
+ D0-D7
+ D0-D7
+ 8-15
- ^WR
- 3
-
16
^INIT
+
+ ^WR
+ 3
- SEL1
- 4
- GND
-
-
-
-
- SEL2
- 5
- GND
-
-
-
-
- ^CS
- 6
- GND
-
-
-
-
- A0
- 7
-
17
^SELECT_IN
-
-
- D0
- 8
-
- 2
- D0
-
-
- D1
- 9
-
- 3
- D1
-
-
- D2
- 10
-
- 4
- D2
-
-
- D3
- 11
-
- 5
- D3
-
-
- D4
- 12
-
- 6
- D4
-
-
- D5
- 13
+ A0
7
- D5
-
-
- D6
- 14
-
- 8
- D6
-
-
- D7
- 15
-
- 9
- D7
-
-
- VCC
- 16
- +5V
-
-
+ 18-25
+ GND
+ GND
VEE
17
- GND
- 18..25
- GND
+
+
+ +5V
+ ^RD
+ 2
+
+
+
+
+ GND
+ SEL1
+ 4
+
+
+
+
+ GND
+ SEL2
+ 5
+
+
+
+
+ GND
+ ^CS
+ 6
+
+
+
+
+ +5V
+ VCC
+ 16
+
+
+
+
+ potentiometer
V0
18
- potentiometer
-
-
+
+
+ -24V (not required for G242C)
VLC
19
- -24V (not required for G242C)
-
-
- Frame
+
+
+ GND
+ FGND
20
- GND
-
-
-
-
-
-
-
- 10
- ^ACK
-
-
-
-
- GND
- 11
- BUSY
-
-
-
-
-
- 12
- PAPEREND
-
-
-
-
-
- 13
- ^SELECT
-
-
-
-
-
- 14
- ^LF
-
-
-
-
-
- 15
- ^ERROR
-
-ConnectionType classic ordered by LPT port pins
+
+ConnectionType bitshaker ordered by LPT port pins
-
-
+
+
-
-
+
+
- LCD
- <->
LPT port
+ <->
+ LCD
- name
- pin
pin
name
+ name
+ pin
- ^RESET
- 1
-
1
^STROBE
-
-
- D0
- 8
- 2
- D0
-
-
- D1
- 9
-
- 3
- D1
-
-
- D2
- 10
-
- 4
- D2
-
-
- D3
- 11
-
- 5
- D3
-
-
- D4
- 12
-
- 6
- D4
-
-
- D5
- 13
-
- 7
- D5
-
-
- D6
- 14
-
- 8
- D6
-
-
- D7
- 15
-
- 9
- D7
-
-
-
-
-
- 10
- ^ACK
-
-
-
-
- GND
- 11
- BUSY
-
-
-
-
-
- 12
- PAPEREND
-
-
-
-
-
- 13
- ^SELECT
-
-
-
-
-
- 14
- ^LF
-
-
-
-
-
- 15
- ^ERROR
-
-
^WR
3
-
- 16
- ^INIT
+ 2-9
+ D0-D7
+
+ D0-D7
+ 8-15
+
+
+ 14
+ ^LF
+
A0
7
-
- 17
- ^SELECT_IN
+ 16
+ ^INIT
+
+ ^RESET
+ 1
+
+
+ 18-25
+ GND
+ GND
VEE
17
- GND
- 18..25
- GND
+
+
+ +5V
^RD
2
- +5V
-
-
+
+
+ GND
SEL1
4
- GND
-
-
+
+
+ GND
SEL2
5
- GND
-
-
+
+
+ GND
^CS
6
- GND
-
-
+
+
+ +5V
VCC
16
- +5V
-
-
+
+
+ potentiometer
V0
18
- potentiometer
-
-
+
+
+ -24V (not required for G242C)
VLC
19
- -24V (not required for G242C)
-
-
- Frame
- 20
+
+
GND
-
-
+ FGND
+ 20
@@ -504,6 +328,14 @@ use the following circuit.
+
+Keypad
+
+The sed1330 driver supports the same direct keys and matrix keypad
+connections as the hd44780 driver. See .
+
+
+
@@ -523,6 +355,12 @@ use the following circuit.
legal values for HEIGHT range from 7 to
16.
If not given CellSize defaults to 6x10.
+
+
+ Contrary to other drivers the character size of an LCD using the sed1330
+ driver is not given directly. Instead it is determined by the pixel size
+ of the display, which is derived from the display type setting and the
+ character cell size specified with this setting.
@@ -536,30 +374,8 @@ use the following circuit.
- Select the type of the wiring.
+ Select the type of the wiring, see .
-
-
-
-
-
- ConnectionType
- Wiring
-
-
-
-
- classic
- ^WR = LPT pin 16, A0 = LPT pin 17, ^RESET = LPT pin 1
-
-
- bitshaker
- ^WR = LPT pin 1, A0 = LPT pin 14, ^RESET = LPT pin 16
-
-
-
-
-
If not given, it defaults to classic.
@@ -646,13 +462,6 @@ use the following circuit.
-
-Contrary to other drivers the character size of an LCD using the sed1330
-driver is not given directly.
-Instead it is determined by the pixel size of the display, which is derived from
-the display type setting and the character cell size.
-
-
diff --git a/server/drivers/sed1330.c b/server/drivers/sed1330.c
index 9dc390d..0cdf5f5 100644
--- a/server/drivers/sed1330.c
+++ b/server/drivers/sed1330.c
@@ -1,27 +1,25 @@
/** \file server/drivers/sed1330.c
* LCDd \c sed1330 driver for SED1330/1335 graphical displays.
+ *
+ * EPSON has changed the the chip-labeling. SED1330 now is S1D13300 and
+ * SED1335 is S1D13305.
+ *
+ * This driver drives the LCD in text mode and uses graphic mode to draw
+ * the heartbeart and bars.
*/
-/*
+/*-
* Driver for SED1330/1335 graphical displays
*
- * EPSON has changed the the chip-labeling.
- * SED1330 now is S1D13300 and SED1335 is S1D13305
- *
- * This driver drives the LCD in text mode.
- * Probably the driver can easily be adapted to work for 1336 too.
- *
- * Moved the delay timing code by Charles Steinkuehler to timing.h.
- * Guillaume Filion , December 2001
- *
- * This file is released under the GNU General Public License. Refer to the
- * COPYING file distributed with this package.
- *
* Copyright (c) 2001-2003, Joris Robijn
* 2003, Michael Rohde
* 2006, Benjamin Wiedmann
*
- *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ */
+
+/*-
* Changelog:
*
* November 2001, Joris Robijn:
@@ -29,6 +27,8 @@
* - Parts copied from HD44780 driver
* December 2001, Joris Robijn:
* - Adapted to v0.5 API
+ * December 2001, Guillaume Filion:
+ * - Moved the delay timing code by Charles Steinkuehler to timing.h.
* June 2002, Joris Robijn:
* - Modified init things to support multiple font sizes
* - More calculations v.s. static init data
@@ -56,204 +56,37 @@
* December 2006, Benjamin Wiedmann (additional changes, fixup)
* - wiring scheme can now be changed at run time using "ConnectionType" config parameter
* in sed1330 driver section
- * Usage of ConnectionType in LCDd.conf:
- * ConnectionType=
+ * Usage of ConnectionType in LCDd.conf:
+ * ConnectionType=
* - if no ConnectionType is set it defaults to "classic" wiring
- *
- * IMPORTANT: MODULES OTHER THAN G321D
- * ===================================
- * If you are using a module other than the G321D, beware that the software
- * has not been tested. You may need to adapt the initialization parameters
- * to get it working properly.
- *
- *
- *
- *
- * Connections
- * ===========
- *
- * Connections below are for the G242C, G121C and G321D displays.
- * Always consult documentation about the specific display before asuming
- * the connections given here are also correct for your display !
- *
- * Ordered by LCD pins
- * LCD pin? <---> pin LPT port
- * ^RESET 1 1 ^STROBE
- * ^RD 2 +5V
- * ^WR 3 16 ^INIT
- * SEL1 4 GND
- * SEL2 5 GND
- * ^CS 6 GND
- * A0 7 17 ^SELECT_IN
- * D0 8 2 D0
- * D1 9 3 D1
- * D2 10 4 D2
- * D3 11 5 D3
- * D4 12 6 D4
- * D5 13 7 D5
- * D6 14 8 D6
- * D7 15 9 D7
- * Vdd 16 +5V
- * Vss 17 GND 18..25 GND
- * V0 18 potmeter
- * Vlc 19 -24V
- * Frame 20 GND
- * 10 ^ACK
- * GND 11 BUSY
- * 12 PAPEREND
- * 13 ^SELECT
- * 14 ^LF
- * 15 ^ERROR
- *
- * Or ordered by the LPT port pins:
- * LCD pin? <---> pin LPT port
- * ^RESET 1 1 ^STROBE
- * D0 8 2 D0
- * D1 9 3 D1
- * D2 10 4 D2
- * D3 11 5 D3
- * D4 12 6 D4
- * D5 13 7 D5
- * D6 14 8 D6
- * D7 15 9 D7
- * 10 ^ACK
- * GND 11 BUSY
- * 12 PAPEREND
- * 13 ^SELECT
- * 14 ^LF
- * 15 ^ERROR
- * ^WR 3 16 ^INIT
- * A0 7 17 ^SELECT_IN
- * Vss 17 GND 18..25 GND
- * ^RD 2 +5V
- * SEL1 4 GND
- * SEL2 5 GND
- * ^CS 6 GND
- * Vdd 16 +5V
- * V0 18 potmeter
- * Vlc 19 -24V (not required for G242C)
- * Frame 20 GND
- *
- * The potmeter should be connected like this on these display modules:
- *
- * === GND
- * |
- * .-.
- * | |
- * | |5k
- * '-'
- * |
- * |
- * .-.10k potmeter
- * | |
- * | |<----------------o V0
- * | |
- * '-'
- * |
- * O Vlc (= -24V)
- *
- * The G242C generates -24V internally. It is available on Vlc.
- *
- * Connections below are for the HG25504 displays.
- * Always consult documentation about the specific display before asuming
- * the connections given here are also correct for your display !
- *
- * Ordered by LCD pins
- * LCD pin? <---> pin LPT port
- * Frame 1 GND
- * Vss 2 GND 18..25 GND
- * Vdd 3 +5V
- * Vo 3 potmeter
- * ^RESET 5 1 ^STROBE
- * ^RD 6 +5V
- * ^WR 7 16 ^INIT
- * ^CS 8 GND
- * A0 9 17 ^SELECT_IN
- * D0 10 2 D0
- * D1 11 3 D1
- * D2 12 4 D2
- * D3 13 5 D3
- * D4 14 6 D4
- * D5 15 7 D5
- * D6 16 8 D6
- * D7 17 9 D7
- *
- * To generate -24 from the +5V without an external power source, you can
- * use the following circuit.
- *
- * 5V O------+----------+ pinout:
- * | | _____
- * | --- 100uF | _ |
- * | --- 10V | (_) | <-3
- * | | |_____|
- * | +--------+--------+--------+ | max |
- * |5 | | | | | 724 |
- * --------- === GND C - | |_____|
- * | | C coil | | | |||||
- * | | C 47uH | |10k | |||||.
- * | |4 | - | | | |
- * | MAX724 |--------------+ | | 12345
- * | or | | | |
- * | MAX726 |1 | | |+
- * | |-----------------------+ --- 47uF
- * | | | | --- 50V
- * | | | | |
- * --------- | - |
- * |2 |3 | | | |
- * | | '---, | |1k |
- * --- | SB160 / \ - |
- * 100nF--- | ^T^ | |
- * | | | | |
- * +-----+----------------+--------+--------+----O -24V out
- *
- *
- *
- *
- * Config options
- * ==============
- *
- * With the display= option you should specify what display module you have.
- * Accepted values are:
- * type=G121C
- * type=G242C
- * type=G321D
- * type=G191D
- * type=G2446
- * type=SP14Q002
- *
- * You can also change the wiring scheme by using the ConnectionType= option:
- * ConnectionType=
- * If not set, classic wiring is used.
- *
- * The port= value should be set to the LPT port address that the LCD is
- * connected to. Examples:
- * port=0x378
- * port=0x278
- * port=0x3BC
- *
- * The cellsize= value indicates the size of a character. Default:
- * cellsize=6x10
- *
+ * January 2011, Markus Dolze:
+ * - Add support for HG25504 (bye L. Lagendijk).
+ * - Remove instructions that have been transfered to the User's Guide.
+ * - Convert function comments to Doxygen.
+ * - Remove the unused line drawing function.
*/
-#include "lcd.h"
-#include "sed1330.h"
-
-#include "port.h"
-#include "lpt-port.h"
-#include "report.h"
-#include "timing.h"
-#define uPause timing_uPause
-
#include
#include
#include
-// Autorepeat values
+#include "lcd.h"
+#include "sed1330.h"
+#include "port.h"
+#include "lpt-port.h"
+#include "report.h"
+#include "timing.h"
+
+/* Use uPause from timing.h */
+#define uPause timing_uPause
+
+/* Keypad settings */
#define KEYPAD_AUTOREPEAT_DELAY 500
#define KEYPAD_AUTOREPEAT_FREQ 15
+#define KEYPAD_MAXX 5
+#define KEYPAD_MAXY 8
-// Command definitions
+/* Command definitions */
#define CMD_SYSTEM_SET 0x40
#define CMD_SLEEP_IN 0x53
#define CMD_DISP_DIS 0x58
@@ -272,19 +105,17 @@
#define CMD_MWRITE 0x42
#define CMD_MREAD 0x43
-// Data definitions
-#define KEYPAD_MAXX 5
-#define KEYPAD_MAXY 8
+/* LCD types known */
+#define TYPE_G321D 1
+#define TYPE_G121C 2
+#define TYPE_G242C 3
+#define TYPE_G191D 4
+#define TYPE_G2446 5
+#define TYPE_SP14Q002 6
+#define TYPE_HG25504 7
-#define TYPE_G321D 1
-#define TYPE_G121C 2
-#define TYPE_G242C 3
-#define TYPE_G191D 4
-#define TYPE_G2446 5
-#define TYPE_SP14Q002 6
-#define TYPE_HG25504 7
-
-#define SCR1_L 0x00 // Memory locations
+/* Memory locations */
+#define SCR1_L 0x00
#define SCR1_H 0x00
#define SCR2_L 0x00
#define SCR2_H 0x06
@@ -292,14 +123,14 @@
/** private data for the \c sed1330 driver */
typedef struct sed1330_private_data {
- int type; /**< display type */
+ int type; /**< display type */
- // wiring scheme variables to be set by sed1330_init()
+ /* wiring scheme variables to be set by sed1330_init() */
int A0;
int nRESET;
int nWR;
- int port; /**< LPT port to use */
+ int port; /**< LPT port to use */
unsigned char *framebuf_text;
unsigned char *lcd_contents_text;
@@ -313,12 +144,17 @@ typedef struct sed1330_private_data {
char have_keypad;
- // keyMapDirect contains an array of the ascii-codes that should be generated
- // when a directly connected key is pressed (not in matrix).
+ /*
+ * keyMapDirect contains an array of the ascii-codes that should be
+ * generated when a directly connected key is pressed (not in
+ * matrix).
+ */
char *keyMapDirect[KEYPAD_MAXX];
- // keyMapMatrix contrains an array with arrays of the ascii-codes that should be generated
- // when a key in the matrix is pressed.
+ /*
+ * keyMapMatrix contrains an array with arrays of the ascii-codes
+ * that should be generated when a key in the matrix is pressed.
+ */
char *keyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX];
char *pressed_key;
@@ -328,195 +164,198 @@ typedef struct sed1330_private_data {
int stuckinputs;
} PrivateData;
-static char *defaultKeyMapDirect[KEYPAD_MAXX] = { "Enter", "Up", "Down", "Escape", "F1" };
+static char *defaultKeyMapDirect[KEYPAD_MAXX] = {"Enter", "Up", "Down", "Escape", "F1"};
static char *defaultKeyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = {
- { "1", "2", "3", "A", "E" },
- { "4", "5", "6", "B", "F" },
- { "7", "8", "9", "C", "G" },
- { "*", "0", "#", "D", "H" },
- { NULL, NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL, NULL }};
+ {"1", "2", "3", "A", "E"},
+ {"4", "5", "6", "B", "F"},
+ {"7", "8", "9", "C", "G"},
+ {"*", "0", "#", "D", "H"},
+ {NULL, NULL, NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL}};
-
-// Vars for the server core
-MODULE_EXPORT char * api_version = API_VERSION;
+/* 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; // yes, we have no global variables (except for constants)
+MODULE_EXPORT int supports_multiple = 1;
MODULE_EXPORT char *symbol_prefix = "sed1330_";
-// Local functions
-//void uPause (int usecs);
-void sed1330_command( PrivateData * p, char command, int datacount, unsigned char * data );
-void sed1330_rect( PrivateData * p, int x1, int y1, int x2, int y2, char pattern );
-void sed1330_line ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern );
-inline void sed1330_set_pixel( PrivateData * p, int x, int y, int value );
-unsigned char sed1330_scankeypad(PrivateData *p);
-unsigned char sed1330_readkeypad (PrivateData *p, unsigned int YData);
+/* Local functions */
+void sed1330_command(PrivateData * p, char command, int datacount, unsigned char *data);
+void sed1330_rect(PrivateData * p, int x1, int y1, int x2, int y2, char pattern);
+inline void sed1330_set_pixel(PrivateData * p, int x, int y, int value);
+unsigned char sed1330_scankeypad(PrivateData * p);
+unsigned char sed1330_readkeypad(PrivateData * p, unsigned int YData);
-/////////////////////////////////////////////////////////////////
-// Init the driver and display
-//
+/**
+ * API: Init the driver and display
+ */
MODULE_EXPORT int
-sed1330_init( Driver * drvthis )
+sed1330_init(Driver * drvthis)
{
const char *s;
- PrivateData * p;
+ PrivateData *p;
unsigned char data[8];
debug(RPT_DEBUG, "%s( %p )", __FUNCTION__, drvthis);
- // Alocate and store private p
+ /* Allocate and store private data */
p = (PrivateData *) calloc(1, sizeof(PrivateData));
if (p == NULL)
return -1;
if (drvthis->store_private_ptr(drvthis, p))
return -1;
- // initialize PrivateData
+ /* initialize PrivateData */
p->framebuf_text = NULL;
p->lcd_contents_text = NULL;
p->framebuf_graph = NULL;
p->lcd_contents_graph = NULL;
- // READ THE CONFIG FILE
+ /* READ THE CONFIG FILE */
- // Port
+ /* Port. Default: 0x278 (second parallel port!) */
p->port = drvthis->config_get_int(drvthis->name, "Port", 0, 0x278);
- // Char size
+ /* Char size */
s = drvthis->config_get_string(drvthis->name, "CellSize", 0, "6x10");
if (sscanf(s, "%dx%d", &(p->cellwidth), &(p->cellheight)) != 2) {
report(RPT_ERR, "%s: cannot interpret CellSize %s",
- drvthis->name, s);
+ drvthis->name, s);
return -1;
}
if ((p->cellwidth < 6) || (p->cellwidth > 8)
- || (p->cellheight < 7) || (p->cellheight > 16)) {
+ || (p->cellheight < 7) || (p->cellheight > 16)) {
report(RPT_ERR, "%s: CellSize exceeds allowed range of 6x7 to 8x16",
- drvthis->name);
+ drvthis->name);
return -1;
}
- // Type
+ /* Type */
s = drvthis->config_get_string(drvthis->name, "Type", 0, NULL);
if (s == NULL) {
report(RPT_ERR, "%s: you need to specify the display type",
- drvthis->name);
+ drvthis->name);
return -1;
- } else if (strcmp(s, "G321D") == 0) {
+ }
+ else if (strcmp(s, "G321D") == 0) {
p->type = TYPE_G321D;
p->graph_width = 320;
p->graph_height = 200;
- } else if (strcmp(s, "G121C") == 0) {
+ }
+ else if (strcmp(s, "G121C") == 0) {
p->type = TYPE_G121C;
p->graph_width = 128;
p->graph_height = 128;
- } else if (strcmp(s, "G242C") == 0) {
+ }
+ else if (strcmp(s, "G242C") == 0) {
p->type = TYPE_G242C;
p->graph_width = 240;
p->graph_height = 128;
- } else if (strcmp(s, "G191D") == 0) {
+ }
+ else if (strcmp(s, "G191D") == 0) {
p->type = TYPE_G191D;
p->graph_width = 192;
p->graph_height = 192;
- } else if (strcmp(s, "G2446") == 0) {
+ }
+ else if (strcmp(s, "G2446") == 0) {
p->type = TYPE_G2446;
p->graph_width = 240;
p->graph_height = 64;
- } else if(strcmp(s, "SP14Q002") == 0) {
+ }
+ else if (strcmp(s, "SP14Q002") == 0) {
p->type = TYPE_SP14Q002;
p->graph_width = 320;
p->graph_height = 240;
- } else if(strcmp(s, "HG25504") == 0) {
+ }
+ else if (strcmp(s, "HG25504") == 0) {
p->type = TYPE_HG25504;
p->graph_width = 256;
p->graph_height = 128;
- } else {
+ }
+ else {
report(RPT_ERR, "%s: Unknown display type %s", drvthis->name, s);
return -1;
}
report(RPT_INFO, "%s: Using LCD type %s", drvthis->name, s);
- // Set wiring scheme to be used
- //
- // Valid ConnectionTypes:
- // - classic (default)
- // - bitshaker
- //
- // Get ConnectionType, if no type is set, default to "classic" wiring so it even
- // works with config files missing that ConnectionType entry in sed1330 driver section
+ /*
+ * Get ConnectionType, if no type is set, default to "classic" wiring
+ * so it even works with config files missing that ConnectionType entry
+ * in sed1330 driver section.
+ */
s = drvthis->config_get_string(drvthis->name, "ConnectionType", 0, "classic");
- // Set wiring initialization parameters based on ConnectionType
+ /* Set wiring initialization parameters based on ConnectionType */
if (strcmp(s, "classic") == 0) {
- // Use classic wiring
- p->A0 = SEL; // port 17
- p->nRESET = STRB; // port 1
- p->nWR = INIT; // port 16
- } else if(strcmp(s, "bitshaker") == 0) {
- // Use bitshaker wiring
- p->A0 = nLF; // port 14
- p->nRESET = INIT; // port 16
- p->nWR = STRB; // port 1
- } else {
+ p->A0 = SEL; /* port 17 */
+ p->nRESET = STRB; /* port 1 */
+ p->nWR = INIT; /* port 16 */
+ }
+ else if (strcmp(s, "bitshaker") == 0) {
+ p->A0 = nLF; /* port 14 */
+ p->nRESET = INIT; /* port 16 */
+ p->nWR = STRB; /* port 1 */
+ }
+ else {
report(RPT_ERR, "%s: Unknown ConnectionType %s", drvthis->name, s);
return -1;
}
report(RPT_INFO, "%s: Using ConnectionType %s", drvthis->name, s);
- // Keypad ?
+ /* Is a keypad attached? Default: no */
p->have_keypad = drvthis->config_get_bool(drvthis->name, "keypad", 0, 0);
- // Keymap
+ /* Set up keymap */
if (p->have_keypad) {
int x, y;
- // Read keymap
+ /* Set up direct keys first */
for (x = 0; x < KEYPAD_MAXX; x++) {
char buf[40];
- // First fill with default value
+ /* First fill with default value */
p->keyMapDirect[x] = defaultKeyMapDirect[x];
- // Read config value
- sprintf(buf, "keydirect_%1d", x+1);
+ /* Read config value */
+ sprintf(buf, "keydirect_%1d", x + 1);
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) {
p->keyMapDirect[x] = strdup(s);
report(RPT_INFO, "%s: Direct key %d: \"%s\"",
- drvthis->name, x, s );
+ drvthis->name, x, s);
}
}
+ /* Then set up matrix keys */
for (x = 0; x < KEYPAD_MAXX; x++) {
for (y = 0; y < KEYPAD_MAXY; y++) {
char buf[40];
- // First fill with default value
+ /* First fill with default value */
p->keyMapMatrix[y][x] = defaultKeyMapMatrix[y][x];
- // Read config value
- sprintf(buf, "keymatrix_%1d_%d", x+1, y+1);
+ /* Read config value */
+ sprintf(buf, "keymatrix_%1d_%d", x + 1, y + 1);
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) {
p->keyMapMatrix[y][x] = strdup(s);
report(RPT_INFO, "%s: Matrix key %d,%d: \"%s\"",
- drvthis->name, x, y, s);
+ drvthis->name, x, y, s);
}
}
}
}
- // Calculate some sizes
+ /* Calculate some sizes */
p->width = p->graph_width / p->cellwidth;
p->height = p->graph_height / p->cellheight;
p->bytesperline = (p->graph_width - 1) / p->cellwidth + 1;
@@ -526,111 +365,122 @@ sed1330_init( Driver * drvthis )
report(RPT_INFO, "%s: Cell size: %dx%d", drvthis->name, p->cellwidth, p->cellheight);
report(RPT_INFO, "%s: Graphical size: %dx%d", drvthis->name, p->graph_width, p->graph_height);
- // Allocate framebuffer
- p->framebuf_text = (unsigned char *) malloc(p->bytesperline * p->textlines_in_memory);
+ /* Allocate and clear framebuffers for text and graphic */
+ p->framebuf_text = (unsigned char *)malloc(p->bytesperline * p->textlines_in_memory);
if (p->framebuf_text == NULL) {
report(RPT_ERR, "%s: error allocating text framebuffer", drvthis->name);
return -1;
}
memset(p->framebuf_text, ' ', p->bytesperline * p->textlines_in_memory);
- p->lcd_contents_text = (unsigned char *) malloc(p->bytesperline * p->textlines_in_memory);
+ p->lcd_contents_text = (unsigned char *)malloc(p->bytesperline * p->textlines_in_memory);
if (p->lcd_contents_text == NULL) {
report(RPT_ERR, "%s: error allocating lcd_contents_text", drvthis->name);
return -1;
}
memset(p->lcd_contents_text, 0, p->bytesperline * p->textlines_in_memory);
- p->framebuf_graph = (unsigned char *) malloc(p->bytesperline * p->graph_height);
+ p->framebuf_graph = (unsigned char *)malloc(p->bytesperline * p->graph_height);
if (p->framebuf_graph == NULL) {
report(RPT_ERR, "%s: error allocating graphical framebuffer", drvthis->name);
return -1;
}
memset(p->framebuf_graph, 0, p->bytesperline * p->graph_height);
- p->lcd_contents_graph = (unsigned char *) malloc(p->bytesperline * p->graph_height);
+ p->lcd_contents_graph = (unsigned char *)malloc(p->bytesperline * p->graph_height);
if (p->lcd_contents_graph == NULL) {
report(RPT_ERR, "%s: error allocating lcd_contents_graph", drvthis->name);
return -1;
}
memset(p->lcd_contents_graph, 0xFF, p->bytesperline * p->graph_height);
- // Arrange for access to port
+ /* Arrange for access to port */
debug(RPT_DEBUG, "%s: getting port access", __FUNCTION__);
- if (port_access_multiple(p->port,3)) {
+ if (port_access_multiple(p->port, 3)) {
report(RPT_ERR, "%s: cannot get IO-permission for 0x%03X: %s",
- drvthis->name, p->port, strerror(errno));
+ drvthis->name, p->port, strerror(errno));
return -1;
}
if (timing_init() == -1) {
report(RPT_ERR, "%s: timing_init() failed (%s)",
- drvthis->name, strerror(errno));
+ drvthis->name, strerror(errno));
return -1;
}
- // INITIALIZE THE LCD
- // End reset-state
+ /* INITIALIZE THE LCD */
+
+ /* End reset-state */
debug(RPT_DEBUG, "%s: initializing LCD", __FUNCTION__);
- port_out(p->port+2, (p->nWR) ^ OUTMASK); // raise ^RD and ^WR
- port_out(p->port+2, (p->nRESET|p->nWR) ^ OUTMASK); // lower RESET
+ port_out(p->port+2, (p->nWR) ^ OUTMASK); /* raise ^WR */
+ port_out(p->port+2, (p->nRESET | p->nWR) ^ OUTMASK); /* lower RESET */
uPause(200);
- port_out(p->port+2, (p->nWR) ^ OUTMASK); // raise RESET
+ port_out(p->port+2, (p->nWR) ^ OUTMASK); /* raise RESET */
uPause(200);
- port_out(p->port+2, (p->nRESET|p->nWR) ^ OUTMASK); // lower RESET
+ port_out(p->port+2, (p->nRESET | p->nWR) ^ OUTMASK); /* lower RESET */
uPause(4000);
switch (p->type) {
- case TYPE_G321D:
+ case TYPE_G321D:
data[4] = 0x38;
break;
- case TYPE_SP14Q002:
+ case TYPE_SP14Q002:
data[4] = 0x38;
break;
- case TYPE_G121C:
- data[4] = 0x7F; // ? please confirm these numbers
+ case TYPE_G121C:
+ data[4] = 0x7F; /* ? FIXME: please confirm these numbers */
break;
- case TYPE_G242C:
- data[4] = 0x7F; // ?
+ case TYPE_G242C:
+ data[4] = 0x7F; /* ? */
break;
- case TYPE_G2446:
- data[4] = 0x7F; // ?
+ case TYPE_G2446:
+ data[4] = 0x7F; /* ? */
break;
- case TYPE_G191D:
- data[4] = 0x5c; // ?
+ case TYPE_G191D:
+ data[4] = 0x5c; /* ? */
break;
- case TYPE_HG25504:
- data[4] = 0x7F; // Confirmed
+ case TYPE_HG25504:
+ data[4] = 0x7F; /* Confirmed! */
break;
- default:
+ default:
return -1;
}
- data[0] = 0x30;
- data[1] = 0x80 + p->cellwidth - 1;
+ /* Prepare and send SYSTEM SET command */
+ data[0] = 0x30; /* Int. CGROM, no D6 cor., 8-pixel height, single-panel */
+ data[1] = 0x80 + p->cellwidth - 1; /* two-frame AC drive, cellwidth */
data[2] = p->cellheight - 1;
- data[3] = p->width - 1;
- // data[4] should be filled already
- // TC/R = ((clock / (refresh * (L/F - 1))) - 1) / 9
- data[5] = p->graph_height - 1;
- data[6] = p->bytesperline;
- data[7] = 0;
+ data[3] = p->width - 1; /* C/R: address range by one display line */
+ /* data[4] should be filled already */
+ /* C/R = ((clock / (refresh * (L/F - 1))) - 1) / 9 */
+ data[5] = p->graph_height - 1; /* L/F: frame height */
+ data[6] = p->bytesperline; /* APL: horizontal address range low */
+ data[7] = 0; /* APH: horizontal address range high */
sed1330_command(p, CMD_SYSTEM_SET, 8, data);
- // TODO: The memory locations need to be calculated !
- sed1330_command(p, CMD_SCROLL, 6, ((unsigned char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7})); // screen1 and screen2 memory locations
+ /* Set screen1 and screen2 memory locations */
+ /* FIXME: The memory locations need to be calculated! */
+ sed1330_command(p, CMD_SCROLL, 6, ((unsigned char[6]) {SCR1_L, SCR1_H, 0xC7, SCR2_L, SCR2_H, 0xC7}));
- data[0] = p->cellwidth-1;
- data[1] = 7;
- sed1330_command(p, CMD_CSR_FORM, 2, data); // set cursor size
+ /* Prepare and send 'set cursor size' command */
+ data[0] = p->cellwidth - 1;
+ data[1] = 7; /* underscore type, 8 pixels high */
+ sed1330_command(p, CMD_CSR_FORM, 2, data);
- sed1330_command(p, CMD_HDOT_SCR, 1, ((unsigned char[1]) {0x00})); // horizontal pixel shift=0
- sed1330_command(p, CMD_OVLAY, 1, ((unsigned char[1]) {0x01})); // XOR mode, screen1 text, screen3 text (screen2 and screen4 are always graph)
- sed1330_command(p, CMD_DISP_DIS, 1, ((unsigned char[1]) {0x14})); // display off,set cursor off, screen1 on, screen2 on, screen3 off
- sed1330_command(p, CMD_CSR_DIR_R, 0, NULL); // cursor move right
+ /* horizontal pixel shift=0 */
+ sed1330_command(p, CMD_HDOT_SCR, 1, ((unsigned char[1]) {0x00}));
+ /*
+ * XOR mode, set screen1 and screen3 as text (screen2 and screen4 are
+ * always graphic)
+ */
+ sed1330_command(p, CMD_OVLAY, 1, ((unsigned char[1]) {0x01}));
+ /* set display off, cursor off, screen1 on, screen2 on, screen3 off */
+ sed1330_command(p, CMD_DISP_DIS, 1, ((unsigned char[1]) {0x14}));
+ /* set cursor move right */
+ sed1330_command(p, CMD_CSR_DIR_R, 0, NULL);
- sed1330_flush(drvthis); // Clear the contents of the LCD
- sed1330_command(p, CMD_DISP_EN, 0, NULL); // And display on
+ sed1330_flush(drvthis);
+ sed1330_command(p, CMD_DISP_EN, 0, NULL); /* And display on */
report(RPT_DEBUG, "%s: init() done", drvthis->name);
@@ -638,37 +488,41 @@ sed1330_init( Driver * drvthis )
}
-/////////////////////////////////////////////////////////////////
-// Send a command and accompanying p
-// INTERNAL
-//
+/**
+ * Send a command and optionally accompanying data.
+ * \param p Pointer to private data
+ * \param command Command byte
+ * \param datacount Number of data bytes to send
+ * \param data Pointer to data buffer
+ */
void
-sed1330_command( PrivateData * p, char command, int datacount, unsigned char * data )
+sed1330_command(PrivateData * p, char command, int datacount, unsigned char *data)
{
int i;
int port = p->port;
- port_out(port+2, (p->nRESET|p->nWR|p->A0) ^ OUTMASK); // set A0 to indicate command
- port_out(port, command); // set up p
- port_out(port+2, (p->nRESET|p->A0) ^ OUTMASK); // activate ^WR
- port_out(port+2, (p->nRESET|p->nWR|p->A0) ^ OUTMASK); // deactivate ^WR again
- port_out(port+2, (p->nRESET|p->nWR) ^ OUTMASK); // clear A0 to indicate p
+ port_out(port+2, (p->nRESET | p->nWR | p->A0) ^ OUTMASK); /* set A0 to indicate command */
+ port_out(port, command); /* set up command */
+ port_out(port+2, (p->nRESET | p->A0) ^ OUTMASK); /* lower ^WR */
+ port_out(port+2, (p->nRESET | p->nWR | p->A0) ^ OUTMASK); /* rise ^WR again */
+ port_out(port+2, (p->nRESET | p->nWR) ^ OUTMASK); /* clear A0 to indicate data */
+ /* Optionally output data */
for (i = 0; i < datacount; i++) {
- port_out(port, data[i]); // set up data
- port_out(port+2, (p->nRESET) ^ OUTMASK); // activate ^WR
- port_out(port+2, (p->nRESET|p->nWR) ^ OUTMASK); // deactivate ^WR again
+ port_out(port, data[i]); /* set up data */
+ port_out(port + 2, (p->nRESET) ^ OUTMASK); /* lower ^WR */
+ port_out(port + 2, (p->nRESET | p->nWR) ^ OUTMASK); /* rise ^WR again */
}
}
-/////////////////////////////////////////////////////////////////
-// Close the display
-//
+/**
+ * API: Close the display
+ */
MODULE_EXPORT void
-sed1330_close( Driver * drvthis )
+sed1330_close(Driver * drvthis)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s()", __FUNCTION__);
@@ -699,13 +553,13 @@ sed1330_close( Driver * drvthis )
}
-/////////////////////////////////////////////////////////////////
-// Returns the display width
-//
+/**
+ * API: Returns the display width
+ */
MODULE_EXPORT int
-sed1330_width( Driver * drvthis )
+sed1330_width(Driver * drvthis)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_INFO, "%s()", __FUNCTION__);
@@ -713,13 +567,13 @@ sed1330_width( Driver * drvthis )
}
-/////////////////////////////////////////////////////////////////
-// Returns the display height
-//
+/**
+ * API: Returns the display height
+ */
MODULE_EXPORT int
-sed1330_height( Driver * drvthis )
+sed1330_height(Driver * drvthis)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_INFO, "%s()", __FUNCTION__);
@@ -733,9 +587,9 @@ sed1330_height( Driver * drvthis )
* \return Number of pixel columns a character cell is wide.
*/
MODULE_EXPORT int
-sed1330_cellwidth(Driver *drvthis)
+sed1330_cellwidth(Driver * drvthis)
{
-PrivateData *p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s: returning cellwidth", drvthis->name);
@@ -749,9 +603,9 @@ PrivateData *p = drvthis->private_data;
* \return Number of pixel lines a character cell is high.
*/
MODULE_EXPORT int
-sed1330_cellheight(Driver *drvthis)
+sed1330_cellheight(Driver * drvthis)
{
-PrivateData *p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s: returning cellheight", drvthis->name);
@@ -759,13 +613,13 @@ PrivateData *p = drvthis->private_data;
}
-/////////////////////////////////////////////////////////////////
-// Clear the framebuffer
-//
+/**
+ * API: Clear the framebuffers
+ */
MODULE_EXPORT void
-sed1330_clear( Driver * drvthis )
+sed1330_clear(Driver * drvthis)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s()", __FUNCTION__);
@@ -774,79 +628,81 @@ sed1330_clear( Driver * drvthis )
}
-/////////////////////////////////////////////////////////////////
-// Place a string in the framebuffer
-//
+/**
+ * API: Place a string in the (text) framebuffer
+ */
MODULE_EXPORT void
-sed1330_string( Driver * drvthis, int x, int y, char *str )
+sed1330_string(Driver * drvthis, int x, int y, char *str)
{
- PrivateData * p = drvthis->private_data;
- unsigned char * dest;
+ PrivateData *p = drvthis->private_data;
+ unsigned char *dest;
int offset, len;
debug(RPT_DEBUG, "%s( x=%d, y=%d, str=\"%s\" )", __FUNCTION__, x, y, str);
if ((y < 1) || (y > p->height)) {
- return; // outside framebuf
+ return; /* outside framebuf */
}
- // Calculate offset and length to write
+
+ /* Calculate offset and length to write */
if (x < 1) {
offset = (1 - x);
x = 1;
- } else {
+ }
+ else {
offset = 0;
}
len = strlen(str) - offset;
if (len > p->width - x + 1) {
len = p->width - x + 1;
}
- // Calculate destination address
- dest = p->framebuf_text + (y-1)*p->bytesperline + (x-1);
- // And write
+ /* Calculate destination address */
+ dest = p->framebuf_text + (y - 1) * p->bytesperline + (x - 1);
+
+ /* And write */
memcpy(dest, str, len);
}
-/////////////////////////////////////////////////////////////////
-// Place a character in the framebuffer
-//
+/**
+ * API: Place a single character in the text framebuffer
+ */
MODULE_EXPORT void
-sed1330_chr( Driver * drvthis, int x, int y, char c )
+sed1330_chr(Driver * drvthis, int x, int y, char c)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s( x=%d, y=%d, c='%c' )", __FUNCTION__, x, y, c);
if ((y < 1) || (y > p->height) || (x < 1) || (x > p->width)) {
- return; // outside framebuf
+ return; /* outside framebuf */
}
- p->framebuf_text[(y-1)*p->bytesperline + (x-1)] = c;
+ p->framebuf_text[(y - 1) * p->bytesperline + (x - 1)] = c;
}
-/////////////////////////////////////////////////////////////////
-// Flush the framebuffer to the display
-//
+/**
+ * API: Flush the framebuffer to the display. On call to this function
+ * both framebuffers (text and graphic) are written to the display.
+ */
MODULE_EXPORT void
-sed1330_flush( Driver * drvthis )
+sed1330_flush(Driver * drvthis)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
unsigned int pos, start_pos, nr_equal, fblen, len, cursor_pos;
unsigned char csrloc[2];
debug(RPT_DEBUG, "%s()", __FUNCTION__);
- /* sed1330_command(p, CMD_DISP_EN, 1, ((char[1]) {0x14})); // cursor off */
- // TODO: Flickering here needs to be prevented
-
fblen = p->bytesperline * p->textlines_in_memory;
- for (pos = 0; pos < fblen; ) {
+ for (pos = 0; pos < fblen;) {
start_pos = pos;
- for (nr_equal = 0; poslcd_contents_text[pos] == p->framebuf_text[pos]) {
- nr_equal ++;
- } else {
+ nr_equal++;
+ }
+ else {
nr_equal = 0;
}
}
@@ -862,12 +718,13 @@ sed1330_flush( Driver * drvthis )
}
fblen = p->bytesperline * p->graph_height;
- for (pos = 0; pos < fblen; ) {
+ for (pos = 0; pos < fblen;) {
start_pos = pos;
for (nr_equal = 0; pos < fblen && nr_equal < 4; pos++) {
if (p->lcd_contents_graph[pos] == p->framebuf_graph[pos]) {
- nr_equal ++;
- } else {
+ nr_equal++;
+ }
+ else {
nr_equal = 0;
}
}
@@ -884,30 +741,21 @@ sed1330_flush( Driver * drvthis )
}
-/////////////////////////////////////////////////////////////////
-// Sets the backlight on or off
-//
-MODULE_EXPORT void
-sed1330_backlight( Driver * drvthis, int on )
-{
- //PrivateData * p = drvthis->private_data;
-
- debug(RPT_DEBUG, "%s( on=%d )", __FUNCTION__, on);
- // unimplemented
-}
-
-
-/////////////////////////////////////////////////////////////////
-// Draws a rectangle
-// INTERNAL
-//
+/**
+ * Draws a rectangle into the graphic framebuffer.
+ * \param p Pointer to driver's private data
+ * \param x1 X-coordinate of start point
+ * \param y1 Y-coordinate of start point
+ * \param x2 X-coordinate of end point
+ * \param y2 Y-coordinate of end point
+ * \param pattern 0 = clear, 1 = set
+ */
void
-sed1330_rect ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern )
-/* pattern: 0=clear 1=set later more patterns ? */
+sed1330_rect(PrivateData * p, int x1, int y1, int x2, int y2, char pattern)
{
int x, y;
- // Swap coordinates if needed
+ /* Swap coordinates if needed */
if (x1 > x2) {
int swap;
swap = x1;
@@ -928,169 +776,116 @@ sed1330_rect ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern )
}
-/////////////////////////////////////////////////////////////////
-// Draws a line
-// INTERNAL
-//
-void
-sed1330_line ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern )
-/* pattern: 0=clear 1=set later more patterns ? */
-{
- int x, y;
- int more_x;
-
- /* Swap coordinates if needed. We want to draw the line from left
- * to right.
- */
- if (x1 > x2) {
- int swap;
- swap = x1; x1 = x2; x2 = swap;
- swap = y1; y1 = y2; y2 = swap;
- }
-
- /* Draw from left to right... */
- more_x = 1;
- for (x = x1, y = y1; x <= x2; x++) {
- int more_y = 1; /* always draw one pixel */
-
- while (more_y) {
- /* set the pixel */
- sed1330_set_pixel(p, x, y, pattern);
-
- /* Check what we need to do next */
- if (y1 < y2) {
- more_y = (y <= y2);
- if (x1 != x2) {
- more_y &= ((float)y+0.5-y1) < ((float) x+0.5-x1) * (y2-y1) / ((float) x2-x1) ;
- }
- } else {
- more_y = (y>=y2);
- if (x1 != x2) {
- more_y &= ((float)y+0.5-y1) > ((float) x+0.5-x1) * (y2-y1) / ((float) x2-x1) ;
- }
- }
- /* Increment y if we should draw a other pixel for this x value */
- if (more_y) {
- if (y1 < y2) {
- y ++;
- } else {
- y --;
- }
- }
- }
- }
-}
-
-
-/////////////////////////////////////////////////////////////////
-// Sets a specified pixel
-// INTERNAL
-//
+/**
+ * Set or clear a single pixel in the graphic framebuffer.
+ * \param p Pointer to driver's private data
+ * \param x LCD x coordinate (0-based)
+ * \param y LCD y coordinate (0-based)
+ * \param value 0 = clear, 1 = set
+ */
inline void
-sed1330_set_pixel( PrivateData * p, int x, int y, int value )
-/* x, y are graph LCD coordinates, 0-based */
-/* value: 0=clear 1=set */
+sed1330_set_pixel(PrivateData * p, int x, int y, int value)
{
unsigned int bytepos;
char bitmask;
- bytepos = y*p->bytesperline + x/p->cellwidth;
+ bytepos = y * p->bytesperline + x / p->cellwidth;
bitmask = 0x80 >> (x % p->cellwidth);
if (value) {
- p->framebuf_graph[bytepos] |= bitmask; /* set it */
- } else {
- p->framebuf_graph[bytepos] &= ~bitmask; /* clear it */
+ p->framebuf_graph[bytepos] |= bitmask; /* set it */
+ }
+ else {
+ p->framebuf_graph[bytepos] &= ~bitmask; /* clear it */
}
}
-/////////////////////////////////////////////////////////////////
-// Draws a vertical bar at the bottom
-//
+/**
+ * API: Draws a vertical bar at the bottom. Internally this in implemented by
+ * drawing a filled rectangle to the graphic framebuffer.
+ */
MODULE_EXPORT void
-sed1330_vbar( Driver * drvthis, int x, int y, int len, int promille, int pattern )
+sed1330_vbar(Driver * drvthis, int x, int y, int len, int promille, int pattern)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s( x=%d, y=%d, len=%d, promille=%d, pattern=%d )", __FUNCTION__, x, y, len, promille, pattern);
- sed1330_rect(p, (x-1) * p->cellwidth, y * p->cellheight,
- x * p->cellwidth - 2, y * p->cellheight - (long) len * p->cellheight * promille / 1000 - 1, 1);
+ sed1330_rect(p, (x - 1) * p->cellwidth, y * p->cellheight,
+ x * p->cellwidth - 2, y * p->cellheight - (long)len * p->cellheight * promille / 1000 - 1, 1);
}
-/////////////////////////////////////////////////////////////////
-// Draws a horizontal bar to the right (len=pos)
-// or to the left (len=neg)
-//
+/**
+ * API: Draws a horizontal bar to the right (len=pos) or to the left (len=neg).
+ * Internally this in implemented by drawing a filled rectangle to the graphic
+ * framebuffer.
+ */
MODULE_EXPORT void
-sed1330_hbar( Driver * drvthis, int x, int y, int len, int promille, int pattern )
+sed1330_hbar(Driver * drvthis, int x, int y, int len, int promille, int pattern)
{
- PrivateData * p = drvthis->private_data;
+ PrivateData *p = drvthis->private_data;
debug(RPT_DEBUG, "%s( x=%d, y=%d, len=%d, promille=%d, pattern=%d )", __FUNCTION__, x, y, len, promille, pattern);
- sed1330_rect(p, (x-1) * p->cellwidth, (y-1) * p->cellheight,
- (x-1) * p->cellwidth + (long) len * p->cellwidth * promille / 1000 - 1, y * p->cellheight - 3, 1);
+ sed1330_rect(p, (x - 1) * p->cellwidth, (y - 1) * p->cellheight,
+ (x - 1) * p->cellwidth + (long)len * p->cellwidth * promille / 1000 - 1, y * p->cellheight - 3, 1);
}
-/////////////////////////////////////////////////////////////////
-// Writes a big number.
-//
+/**
+ * API: Writes a big number.
+ * \note This is currently only a stub and prevents the alternate big
+ * characters from core to be used.
+ */
MODULE_EXPORT void
-sed1330_num( Driver * drvthis, int x, int y, int num )
+sed1330_num(Driver * drvthis, int x, int y, int num)
{
//PrivateData * p = drvthis->private_data;
debug(RPT_DEBUG, "%s( x=%d, y=%d, num=%d )", __FUNCTION__, x, y, num);
-
- // TODO: add code here :)
}
-/////////////////////////////////////////////////////////////
-// Does the heartbeat...
-// Or in fact a bouncing ball :)
-//
+/**
+ * API: Does the heartbeat.
+ * Or in fact a bouncing ball :)
+ */
MODULE_EXPORT void
-sed1330_heartbeat( Driver * drvthis, int type )
+sed1330_heartbeat(Driver * drvthis, int type)
{
- PrivateData * p = drvthis->private_data;
- static int timer = 0;
+ PrivateData *p = drvthis->private_data;
+ static int timer = 0; /* 'timer' for the bouncing ball */
int pos;
- //int whichIcon;
int n;
- //char heartdata[2][CHARHEIGHT] = {
- // { 0xFF, 0xFF, 0xAF, 0x07, 0x8F, 0xDF, 0xFF, 0xFF, 0x00, 0x00 },
- // { 0xFF, 0xAF, 0x07, 0x07, 0x07, 0x8F, 0xDF, 0xFF, 0x00, 0x00 }
- //};
- char bouncing_ball[8][8] = {
- { 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF },
- { 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF },
- { 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF },
- { 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF },
+ static char bouncing_ball[8][8] = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF},
+ {0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF},
+ {0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF},
+ {0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF},
+ {0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF},
};
debug(RPT_DEBUG, "%s( type=%d )", __FUNCTION__, type);
+ /* Do nothing if heartbeat is disabled */
if (type == HEARTBEAT_OFF)
return;
- p->framebuf_text[p->width-1] = ' ';
- //whichIcon = (! ((timer + 4) & 5));
+ pos = p->width - 1; /* Draw into top right corner */
+ p->framebuf_text[pos] = ' '; /* Clear the text framebuffer there */
- pos = p->width - 1;
+ /* Draw the bouncing ball based on timer into graphic framebuffer */
for (n = 0; n < p->cellheight; n++) {
- //p->framebuf_graph[pos] = heartdata[whichIcon][n];
+ /* We only have data for 8 rows */
if (n < 8) {
p->framebuf_graph[pos] = bouncing_ball[timer][n];
- } else {
+ }
+ else {
p->framebuf_graph[pos] = 0;
}
pos += p->bytesperline;
@@ -1101,82 +896,92 @@ sed1330_heartbeat( Driver * drvthis, int type )
}
-/////////////////////////////////////////////////////////////
-// Place an icon
-//
+/**
+ * API: Place an icon on the screen. Currently no icons are supported except
+ * ICON_BLOCK_FILLED.
+ */
MODULE_EXPORT int
-sed1330_icon( Driver * drvthis, int x, int y, int icon )
+sed1330_icon(Driver * drvthis, int x, int y, int icon)
{
switch (icon) {
- case ICON_BLOCK_FILLED:
+ case ICON_BLOCK_FILLED:
sed1330_chr(drvthis, x, y, 255);
break;
- default:
+ default:
return -1;
}
return 0;
}
-/////////////////////////////////////////////////////////////
-// Get a key from the keypad (if there is one)
-//
+/**
+ * API: Get a key from the keypad (if there is one)
+ */
MODULE_EXPORT const char *
-sed1330_get_key(Driver *drvthis)
+sed1330_get_key(Driver * drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
unsigned char scancode;
- char * keystr = NULL;
+ char *keystr = NULL;
struct timeval curr_time, time_diff;
if (!p->have_keypad)
return NULL;
- gettimeofday(&curr_time,NULL);
+ gettimeofday(&curr_time, NULL);
+ /* Get the key! */
scancode = sed1330_scankeypad(p);
if (scancode) {
if (scancode & 0xF0) {
- keystr = p->keyMapMatrix[((scancode&0xF0)>>4)-1][(scancode&0x0F)-1];
+ keystr = p->keyMapMatrix[((scancode & 0xF0) >> 4) - 1][(scancode & 0x0F) - 1];
}
else {
keystr = p->keyMapDirect[scancode - 1];
}
}
+ /* Check if a new or repeated key press event is to be reported */
if (keystr != NULL) {
if (keystr == p->pressed_key) {
- timersub (&curr_time, &(p->pressed_key_time), &time_diff);
+ timersub(&curr_time, &(p->pressed_key_time), &time_diff);
if (((time_diff.tv_usec / 1000 + time_diff.tv_sec * 1000) - KEYPAD_AUTOREPEAT_DELAY) < 1000 * p->pressed_key_repetitions / KEYPAD_AUTOREPEAT_FREQ) {
- // The key is already pressed quite some time
- // but it's not yet time to return a repeated keypress
+ /*
+ * The key is already pressed quite some time
+ * but it's not yet time to return a repeated
+ * keypress
+ */
return NULL;
}
- // Otherwise a keypress will be returned
- p->pressed_key_repetitions ++;
+ /* Otherwise a keypress will be returned */
+ p->pressed_key_repetitions++;
}
else {
- // It's a new keypress
+ /* It's a new keypress */
p->pressed_key_time = curr_time;
p->pressed_key_repetitions = 0;
report(RPT_INFO, "%s: Key pressed: %s (%d,%d)",
- drvthis->name, keystr, scancode&0x0F, (scancode&0xF0)>>4);
+ drvthis->name, keystr, scancode & 0x0F, (scancode & 0xF0) >> 4);
}
}
- // Store the key for the next round
+ /* Store the key for the next round */
p->pressed_key = keystr;
return keystr;
}
-/////////////////////////////////////////////////////////////
-// Scan the keypad
-//
-// Called by get_key
-//
-unsigned char sed1330_scankeypad(PrivateData *p)
+/**
+ * Scan the keypad. This is identical in function to the scankeypad function
+ * in hd44780.c (except it does not have connection type specific low-level
+ * read function), so read there for a complete description of this algorithm.
+ *
+ * \param p Pointer to PrivateData structure.
+ * \return Scancode of the key.
+ */
+unsigned char
+sed1330_scankeypad(PrivateData * p)
{
unsigned int keybits;
unsigned int shiftcount;
@@ -1187,81 +992,70 @@ unsigned char sed1330_scankeypad(PrivateData *p)
unsigned char scancode = 0;
- // First check if a directly connected key is pressed
- // Put all zeros on Y of keypad
- keybits = sed1330_readkeypad (p, 0);
+ keybits = sed1330_readkeypad(p, 0);
if (keybits) {
- // A directly connected key was pressed
- // Which key was it ?
shiftingbit = 1;
for (shiftcount = 0; shiftcount < KEYPAD_MAXX && !scancode; shiftcount++) {
if (keybits & shiftingbit) {
- // Found ! Return from function.
- scancode = shiftcount+1;
+ scancode = shiftcount + 1;
}
shiftingbit <<= 1;
}
}
else {
- // Now check the matrix
- // First check with all 1's
Ypattern = (1 << KEYPAD_MAXY) - 1;
+
if (sed1330_readkeypad(p, Ypattern)) {
- // Yes, a key on the matrix is pressed
-
- // OK, now we know a key is pressed.
- // Determine which one it is
-
- // First determine the row
- // Do a 'binary search' to minimize I/O
Ypattern = 0;
Yval = 0;
for (exp = 3; exp >= 0; exp--) {
Ypattern = ((1 << (1 << exp)) - 1) << Yval;
- keybits = sed1330_readkeypad (p, Ypattern);
+ keybits = sed1330_readkeypad(p, Ypattern);
if (!keybits) {
Yval += (1 << exp);
}
}
- // Which key is pressed in that row ?
keybits = sed1330_readkeypad(p, 1 << Yval);
shiftingbit = 1;
for (shiftcount = 0; shiftcount < KEYPAD_MAXX && !scancode; shiftcount++) {
if (keybits & shiftingbit) {
- // Found !
- scancode = (Yval+1) << 4 | (shiftcount+1);
+ scancode = (Yval + 1) << 4 | (shiftcount + 1);
}
shiftingbit <<= 1;
}
}
}
+
return scancode;
}
-/////////////////////////////////////////////////////////////
-// Read a keypad byte
-//
-// Called by scankeypad
-//
-unsigned char sed1330_readkeypad (PrivateData *p, unsigned int YData)
+/**
+ * Read keypress.
+ * \param p Pointer to driver's private data structure.
+ * \param YData Bitmap of rows / lines to enable.
+ * \return Bitmap of the pressed keys.
+ */
+unsigned char
+sed1330_readkeypad(PrivateData * p, unsigned int YData)
{
unsigned char readval;
- // 8 bits output
- // Convert the positive logic to the negative logic on the LPT port
+ /*
+ * Output 8 bits. Convert the positive logic to the negative logic on
+ * the LPT port.
+ */
port_out(p->port, ~YData & 0x00FF);
- // Read inputs
- readval = ~ port_in (p->port + 1) ^ INMASK;
+ /* Read inputs */
+ readval = ~port_in(p->port + 1) ^ INMASK;
- // And convert value back (MSB first).
- return (((readval & FAULT) / FAULT <<4) | /* pin 15 */
- ((readval & SELIN) / SELIN <<3) | /* pin 13 */
- ((readval & PAPEREND) / PAPEREND <<2) | /* pin 12 */
- ((readval & BUSY) / BUSY <<1) | /* pin 11 */
+ /* And convert value back (MSB first). */
+ return (((readval & FAULT) / FAULT << 4) | /* pin 15 */
+ ((readval & SELIN) / SELIN << 3) | /* pin 13 */
+ ((readval & PAPEREND) / PAPEREND << 2) | /* pin 12 */
+ ((readval & BUSY) / BUSY << 1) | /* pin 11 */
((readval & ACK) / ACK)) & ~p->stuckinputs; /* pin 10 */
}
-
diff --git a/server/drivers/sed1330.h b/server/drivers/sed1330.h
index 6af4592..47e8353 100644
--- a/server/drivers/sed1330.h
+++ b/server/drivers/sed1330.h
@@ -1,19 +1,16 @@
-/*
- * Driver for SED1330 graphical displays
- * Header file
+/** \file server/drivers/sed1330.h
+ * Driver for SED1330/1335 graphical displays.
*/
#ifndef SED1330_H
#define SED1330_H
-#include "lcd.h"
-
MODULE_EXPORT int sed1330_init(Driver *drvthis);
MODULE_EXPORT void sed1330_close(Driver *drvthis);
MODULE_EXPORT int sed1330_width(Driver *drvthis);
MODULE_EXPORT int sed1330_height(Driver *drvthis);
-MODULE_EXPORT int sed1330_cellheight(Driver *drvthis);
-MODULE_EXPORT int sed1330_cellwidth(Driver *drvthis);
+MODULE_EXPORT int sed1330_cellheight(Driver *drvthis);
+MODULE_EXPORT int sed1330_cellwidth(Driver *drvthis);
MODULE_EXPORT void sed1330_clear(Driver *drvthis);
MODULE_EXPORT void sed1330_flush(Driver *drvthis);
MODULE_EXPORT void sed1330_string(Driver *drvthis, int x, int y, char lcd[]);
@@ -23,10 +20,8 @@ MODULE_EXPORT void sed1330_vbar(Driver *drvthis, int x, int y, int len, int prom
MODULE_EXPORT void sed1330_hbar(Driver *drvthis, int x, int y, int len, int promille, int pattern);
MODULE_EXPORT void sed1330_num(Driver *drvthis, int x, int y, int num);
MODULE_EXPORT void sed1330_heartbeat(Driver *drvthis, int type);
-// No cursor function: use software cursor to prevent flickering ! */
MODULE_EXPORT int sed1330_icon(Driver *drvthis, int x, int y, int icon);
-MODULE_EXPORT void sed1330_backlight(Driver *drvthis, int on);
-MODULE_EXPORT const char * sed1330_get_key(Driver *drvthis);
+MODULE_EXPORT const char *sed1330_get_key(Driver *drvthis);
#endif