From 7b316f4d969f90861cfe5121033e663e1e9f5b71 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Thu, 27 Dec 2012 11:19:41 +0000 Subject: [PATCH] sed1520 driver: Add an option for inverted segment mapping (idea by R. Buchert) --- ChangeLog | 3 +++ LCDd.conf | 11 ++++++++- server/drivers/sed1520.c | 50 ++++++++++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 945d57f..446e97e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,9 @@ Key: * Something changed / fixed v0.5dev (ongoing development) + * sed1520: Add an option for inverted segment mapping (idea by R. Buchert) + +v0.5.6 - Remove deprecated CFontz633 driver. Use CFontzPacket with Model=633 instead! + new driver: glcd unified graphic display driver (M. Dolze) + new driver: vlsys_m428 driver for Moneual MonCaso 320 (W. Hauck) diff --git a/LCDd.conf b/LCDd.conf index ebea746..4f986bf 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -1054,8 +1054,17 @@ DelayMult=0 # The original wiring used an inverter to drive the control lines. If you do # not use an inverter set haveInverter to no. [default: yes; legal: yes, no] -haveInverter=no +HaveInverter=no +# On some displays column data in memory is mapped to segment lines from right +# to left. This is called inverted mapping (not to be confused with +# 'haveInverter' from above). [default: no; legal: yes, no] +#InvertedMapping=yes + +# At least one display is reported (Everbouquet MG1203D) that requires sending +# three times 0xFF before a reset during initialization. +# [default: no; legal: yes, no] +#UseHardReset=yes ## serial POS display driver ## diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c index 11da781..ea45dac 100644 --- a/server/drivers/sed1520.c +++ b/server/drivers/sed1520.c @@ -48,8 +48,8 @@ #define HEIGHT ((int) (PIXELHEIGHT / CELLHEIGHT)) /* 4 */ #define A0 nSEL /* pin 17 */ -#define CS1 nLF /* pin 14 */ -#define CS2 INIT /* pin 16 */ +#define CS1 nLF /* pin 14, EN1 for 68-style connection */ +#define CS2 INIT /* pin 16, EN2 for 68-style connection */ #define WR nSTRB /* pin 1 */ /** private data for the \c sed1520 driver */ @@ -58,6 +58,7 @@ typedef struct sed1520_private_data { int interface; int delayMult; int haveInverter; + unsigned char colStartAdd; unsigned char *framebuf; } PrivateData; @@ -70,7 +71,7 @@ MODULE_EXPORT int supports_multiple = 0; MODULE_EXPORT char *symbol_prefix = "sed1520_"; /** - * Writes command value to one or both sed1520 selected by chip. + * Writes command value to one or both SED1520 selected by chip. * \param p Pointer to private data structure * \param value Command byte to write * \param chip Bitmap of controllers to send value to @@ -86,7 +87,8 @@ writecommand(PrivateData *p, int value, int chip) port_out(p->port, value); /* cycle E */ port_out(p->port + 2, ((chip & CS1) + (chip & CS2)) ^ OUTMASK); - if (p->delayMult) uPause(p->delayMult); + if (p->delayMult) + uPause(p->delayMult); port_out(p->port + 2, 0 ^ OUTMASK); } else { @@ -120,7 +122,7 @@ writecommand(PrivateData *p, int value, int chip) } /** - * Writes data value to one or both sed 1520 selected by chip. + * Writes data value to one or both SED1520 selected by chip. * \param p Pointer to private data structure * \param value Data byte to write * \param chip Bitmap of controllers to send value to @@ -133,7 +135,8 @@ writedata(PrivateData *p, int value, int chip) port_out(p->port, value); /* cycle E */ port_out(p->port + 2, (A0 + (chip & CS1) + (chip & CS2)) ^ OUTMASK); - if (p->delayMult) uPause(p->delayMult); + if (p->delayMult) + uPause(p->delayMult); port_out(p->port + 2, (A0) ^ OUTMASK); } else { @@ -161,7 +164,7 @@ writedata(PrivateData *p, int value, int chip) } /** - * Selects a page (=row) on both sed1520s. + * Selects a page (=row) on both SED1520. * \param p Pointer to private data structure * \param page Page (=row) number (0-3) */ @@ -172,7 +175,7 @@ selectpage(PrivateData *p, int page) } /** - * Selects a column on the sed1520 specified by chip. + * 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 @@ -194,13 +197,13 @@ selectcolumn(PrivateData *p, int column, int chip) * * 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). + * by each write so the display fills from left to right (normal mode) or + * right to left (inverted mapping). */ /** * 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, + * The fontmap is stored in rows while the framebuffer is stored in columns, * so we need a little conversion. * * \param framebuf Pointer to framebuffer @@ -236,6 +239,7 @@ MODULE_EXPORT int sed1520_init(Driver * drvthis) { PrivateData *p; + char inverted; /* Allocate and store private data */ p = (PrivateData *) calloc(1, sizeof(PrivateData)); @@ -287,10 +291,26 @@ sed1520_init(Driver * drvthis) * The original wiring used an inverter to drive the control lines. As * someone may still be using this, the following setting in ON by default. */ - p->haveInverter = drvthis->config_get_bool(drvthis->name, "haveInverter", 0, 1); + p->haveInverter = drvthis->config_get_bool(drvthis->name, "HaveInverter", 0, 1); + + /* + * Inverted Mapping: Segments are addressed from right to left and start + * at column 19 (address 0x13) up to column 79 (address 0x4F). + */ + inverted = drvthis->config_get_bool(drvthis->name, "InvertedMapping", 0, 0); + if (inverted) + p->colStartAdd = 0x13; + else + p->colStartAdd = 0; /* Initialize display */ + if (drvthis->config_get_bool(drvthis->name, "UseHardReset", 0, 0) == 1) { + writedata(p, 0xFF, CS1 + CS2); + writedata(p, 0xFF, CS1 + CS2); + writedata(p, 0xFF, CS1 + CS2); + } writecommand(p, SOFT_RESET, CS1 + CS2); + writecommand(p, (inverted) ? ADC_INV : ADC_NORM, CS1 + CS2); writecommand(p, DISP_ON, CS1 + CS2); writecommand(p, DISP_START_LINE, CS1 + CS2); selectpage(p, 3); @@ -300,7 +320,7 @@ sed1520_init(Driver * drvthis) } /** - * API: Frees the frambuffer and exits the driver. + * API: Frees the framebuffer and exits the driver. */ MODULE_EXPORT void sed1520_close(Driver * drvthis) @@ -378,12 +398,12 @@ sed1520_flush(Driver * drvthis) selectpage(p, i); /* update left half of display */ - selectcolumn(p, 0, CS1); + selectcolumn(p, p->colStartAdd, CS1); for (j = 0; j < PIXELWIDTH / 2; j++) writedata(p, p->framebuf[j + (i * PIXELWIDTH)], CS1); /* update right half of display */ - selectcolumn(p, 0, CS2); + selectcolumn(p, p->colStartAdd, CS2); for (j = PIXELWIDTH / 2; j < PIXELWIDTH; j++) writedata(p, p->framebuf[j + (i * PIXELWIDTH)], CS2); }