Skip to content

Commit

Permalink
Add support for HD44780-compatible WINSTAR WEH00xxyyA OLED Displays
Browse files Browse the repository at this point in the history
Added support for WINSTAR OLED displays - almost compatible to
HD44780 LCDs. These displays require slightly different initialization sequence,
especially required on display reinitialization without powering it off first.

This was achieved through additional Model option, incorporating to this
existing 'ExtendedMode' for KS0073 display which require also special
handling. Added also PT6314 VFD model to available models.

Tested on Raspberry PI and WINSTAR WEH001604ALPP5N00001 OLED display
connected through I2C PCF8574 connection (4-bits obviously) and
WINSTAR WEH002004ALPP5N00001 OLED. Should work on any connection.

Also tested other displays - few standard HD44780 16x4 and 20x4 LCDs,
PC2004LRU (which uses "extended-mode" commands"), all using
i2c-connection on Raspberry PI.

Also updated initialization sequence according to manual:
After setting interface length, turn off display to not show possible
garbage during configuration. After initialization display is turned on again.
  • Loading branch information
mskalski authored and haraldg committed Oct 9, 2017
1 parent e44f04c commit e8cfdd2
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 13 deletions.
13 changes: 13 additions & 0 deletions LCDd.conf
Expand Up @@ -544,6 +544,19 @@ Speed=19200
# Select what type of connection. See documentation for available types.
ConnectionType=4bit

# Select model if have non-standard one which require extra initialization or handling or
# just want extra features it offers.
# Available: standard (default), extended, winstar_oled, pt6314_vfd
# - standard is default, use for LCDs not mentioned below.
# - extended, hd66712, ks0073: allows use 4-line "extended" mode,
# same as deprecated now option ExtendedMode=yes
# - winstar_oled, weh00xxyya: changes initialization for WINSTAR's WEH00xxyyA displays
# and allows handling brightness
# - pt6314_vfd: allows handling brightness on PTC's PT6314 VFDs
#
# This option should be independent of connection type.
#Model = standard

# I/O address of the LPT port. Usual values are: 0x278, 0x378 and 0x3BC.
# For I2C connections this sets the slave address (usually 0x20).
Port=0x378
Expand Down
77 changes: 73 additions & 4 deletions docs/lcdproc-user/drivers/hd44780.docbook
Expand Up @@ -2585,7 +2585,7 @@ If your port expander has different wiring you can re-assign the pins in the con
</para>

<example id="hd44780-i2c-config.example.alternative.wiring">
<title>HD44780: Configuration for I<superscript>2</superscript>C with port expander
<title>HD44780: Configuration for I<superscript>2</superscript>C with port expander
Alternative Wiring</title>
<screen>
<![CDATA[
Expand Down Expand Up @@ -2619,7 +2619,7 @@ i2c_line_D6=0x40
i2c_line_D7=0x80
Backlight=yes
BacklightInvert=yes
#The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off,
#The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off,
i.e. PNP transistor
]]>
</screen>
Expand Down Expand Up @@ -3512,6 +3512,64 @@ This can be done by specifying <option>--enable-drivers=all</option> or by inclu
</listitem>
</varlistentry>

<varlistentry>
<term>
<property>Model</property> =
{
<!-- Keep this list sorted according to the table in hd44780-low.h -->
<emphasis><parameter><literal>standard</literal></parameter></emphasis> |
<parameter><literal>extended</literal></parameter> |
<parameter><literal>winstar_oled</literal></parameter> |
<parameter><literal>pt6314_vfd</literal></parameter>
}
</term>
<listitem>
<para>
Some devices (ie. WINSTAR WEH001602A OLED or PTC PT6314 VFD) require additional
initialization or configuration incompatible with "classic" LCD or just have extra
features, such as internal commands for brightness handling. If you have such display
setting this option may help in problems with initialization or adds extra
functionality.
<itemizedlist>
<listitem><para>
The default, <literal>standard</literal> or <literal>default</literal>,
is for "classic" HD44780 displays.
</para></listitem>
<listitem><para>
<literal>extended</literal>, <literal>hd66712</literal> or <literal>ks0073</literal>
is for displays which have "extended mode" turned on with special instruction.
If you have a Samsung KS0073, PowerTip Corp. PC2004LRU, other based on HD66710/HD66712 chip
or an other 'almost HD44780-compatible', set <literal>Model</literal> to
this value to get into extended, 4-line linear addressing mode.
</para>
<para>
Use this instead of deprecated option <literal>ExtendedMode</literal>.
</para></listitem>
<listitem><para>
<literal>winstar_oled</literal> or <literal>weh00xxyya</literal> is for
WINSTAR WEH00xxyyA OLED displays and allows performing proper initialization
of display device, especially after display reset without powering it off.
</para>
<para>It also allows handling backlight setting using internal commands
for such displays.
</para>
</listitem>
<listitem><para>
<literal>pt6314_vfd</literal> is for some Princeton Technology Corp.'s
PT6314 VFDs and allows handling brightness of display.
</para></listitem>
</itemizedlist>
You only may need to set this parameter if you have a non-standard
HD44780 display such as specified above and have problems with it and/or
want reveal extra functionality with these displays.
</para>
<para>
This option should be independent of connection type.
</para>
</listitem>
</varlistentry>


<varlistentry>
<term>
<property>Speed</property> =
Expand Down Expand Up @@ -3645,7 +3703,15 @@ This can be done by specifying <option>--enable-drivers=all</option> or by inclu
</itemizedlist>
You only need to set this parameter if you have a HD44780 display
such as the WINSTAR WEH001602A, which allows selecting the font bank
during initialization.
during initialization. Additionally you may need to set correct
<literal>CharMap</literal>.
<note>
<para>Setting this to nonzero value on standard HD44780 is usually harmless,
but some non-standard displays may use bits used for <literal>FontBank</literal>
selection, so it is safer to leave this option at default value for displays
not supporting Font bank.
</para>
</note>
</para>
</listitem>
</varlistentry>
Expand Down Expand Up @@ -3777,7 +3843,10 @@ This can be done by specifying <option>--enable-drivers=all</option> or by inclu
<listitem><para>
If you have a KS0073 or an other 'almost HD44780-compatible', set this
flag to get into extended,4-line linear addressing mode.
</para></listitem>
</para>
<note><para>
Deprecated, use <code>Model=extended</code> for such displays.
</para></note></listitem>
</varlistentry>

<varlistentry>
Expand Down
2 changes: 1 addition & 1 deletion server/drivers/hd44780-lis2.c
Expand Up @@ -211,7 +211,7 @@ static unsigned char rowNum = 0;
}
else { // RS_INSTR: we have an instruction
if ((ch & POSITION) != 0) {
unsigned char divisor = (p->ext_mode) ? 0x20 : 0x40;
unsigned char divisor = has_extended_mode(p) ? 0x20 : 0x40;

// get mangled position by stripping POSITION flag from given data
ch &= ~POSITION;
Expand Down
42 changes: 40 additions & 2 deletions server/drivers/hd44780-low.h
Expand Up @@ -75,6 +75,28 @@
#define IF_TYPE_SPI 6
/**@}*/

/** \name Symbolic name for specific models
* @{
* Used here to handle various conflicting differences in command sets.
* Some optional features are nottied to model even if it appears only in that model
* unless not are not conflicting, as default settings are compatible across all devices.
* (for example FontBank) */

/** Standard / default model. Should work with most of HD44780-compatible displays */
#define HD44780_MODEL_DEFAULT 0
/** Extended model - 4 lines activated with special bits and extra commands (EXTREG) */
#define HD44780_MODEL_EXTENDED 1
/** WINSTAR WEH00xxyyA (WEH001604A, WEH002004A, ...) and others, requires slightly different
* initialization sequence and have extra commands for handling brightness */
#define HD44780_MODEL_WINSTAR_OLED 2
/** PTC PT6314 VFD Displays - have extra command for setting four-level brightness.
* Otherwise is compatible to other HD44780s */
#define HD44780_MODEL_PT6314_VFD 3

/* Possibly extended further...*/

/** @} */

/** \name Symbolic default values
*@{*/
#define DEFAULT_CONTRAST 800
Expand Down Expand Up @@ -162,7 +184,7 @@ typedef struct hd44780_private_data {

#ifdef HAVE_I2C
/* i2c based connection types */

int i2c_backlight_invert;
int i2c_line_RS;
int i2c_line_RW;
Expand Down Expand Up @@ -228,7 +250,9 @@ typedef struct hd44780_private_data {
char have_output;
/**@}*/

char ext_mode; /**< use extended mode on some weird controllers */
int model; /**< model selected in configuration.
For extended mode on some weird controllers
set to HD44780_MODEL_EXTENDED */
int line_address; /**< address of the next line in extended mode */

int delayMult; /**< Delay multiplier for slow displays */
Expand Down Expand Up @@ -364,6 +388,13 @@ typedef struct hwDependentFns {
/* Prototypes */
void common_init(PrivateData *p, unsigned char if_bit);

/* returns if display needs/is using 'Extended mode'- nonzero if yes */
static short
has_extended_mode(PrivateData *p) {
return p->model == HD44780_MODEL_EXTENDED;
}



/* commands for senddata */
#define RS_DATA 0x00
Expand Down Expand Up @@ -420,6 +451,13 @@ void common_init(PrivateData *p, unsigned char if_bit);
/** Shift or scroll enable (RE=1) */
#define HSCROLLEN 0x10

/** Extra definitions on Winstar OLED displays - set last 2 bits (=0x03) to activate */
#define WINST_MODESET 0x13 /**< required bits for command */
#define WINST_TEXTMODE 0x00 /**< Activate text mode */
#define WINST_GRAPHMODE 0x08 /**< Activate graphic mode */
#define WINST_PWRON 0x04 /**< Internal power on (high brightness)*/
#define WINST_PWROFF 0x00 /**< Internal power off (low brightness)*/

/** Function set (RE=0) */
#define FUNCSET 0x20
#define IF_8BIT 0x10
Expand Down
99 changes: 93 additions & 6 deletions server/drivers/hd44780.c
Expand Up @@ -112,6 +112,49 @@ unsigned char HD44780_scankeypad(PrivateData *p);
static int parse_span_list(int *spanListArray[], int *spLsize, int *dispOffsets[], int *dOffsize, int *dispSizeArray[], const char *spanlist);


static const struct ModelMapping {
const char *name;
int model;
} model_mapping[] = {
{ "default", HD44780_MODEL_DEFAULT },
{ "standard", HD44780_MODEL_DEFAULT },

{ "extended", HD44780_MODEL_EXTENDED },
{ "ks0073", HD44780_MODEL_EXTENDED },
{ "hd66710", HD44780_MODEL_EXTENDED },

{ "winstar_oled", HD44780_MODEL_WINSTAR_OLED },
{ "weh00xxyya", HD44780_MODEL_WINSTAR_OLED },

{ "pt6314_vfd", HD44780_MODEL_PT6314_VFD },

{ "", HD44780_MODEL_DEFAULT }
};

static int model_by_name( const char *name )
{
int i;

for (i=0; i<sizeof(model_mapping)/sizeof(model_mapping[0]); i++) {
if (strcasecmp(model_mapping[i].name, name) == 0 )
return model_mapping[i].model;
}

return -1;
}

static const char *model_name( int type )
{
int i;

for (i=0; i<sizeof(model_mapping)/sizeof(model_mapping[0]); i++) {
if (model_mapping[i].model == type)
return model_mapping[i].name;
}

return "";
}

/**
* Initialize the driver.
* Initialize common part of drive & call sub-initialization
Expand All @@ -129,7 +172,7 @@ HD44780_init(Driver *drvthis)
int i = 0;
int (*init_fn) (Driver *drvthis) = NULL;
int if_type = IF_TYPE_UNKNOWN;
int tmp;
int tmp, ext_mode;
PrivateData *p;
char conf_charmap[MAX_CHARMAP_NAME_LENGTH];

Expand All @@ -153,7 +196,27 @@ HD44780_init(Driver *drvthis)
/* READ THE CONFIG FILE */

p->port = drvthis->config_get_int(drvthis->name, "port", 0, LPTPORT);
p->ext_mode = drvthis->config_get_bool(drvthis->name, "extendedmode", 0, 0);
s = drvthis->config_get_string(drvthis->name, "model", 0, "default");
p->model = model_by_name(s);
if (p->model < 0) {
report(RPT_ERR, "%s: unknown Model: %s", drvthis->name, s);
return -1;
}
/* config file compability stuff */
if (p->model == HD44780_MODEL_DEFAULT) {
ext_mode = drvthis->config_get_bool(drvthis->name, "extendedmode", 0, 0);
if (ext_mode)
p->model = HD44780_MODEL_EXTENDED;
}
else {
tmp = (p->model == HD44780_MODEL_EXTENDED);
ext_mode = !!drvthis->config_get_bool(drvthis->name, "extendedmode", 0, tmp);
if (ext_mode != tmp) {
report(RPT_ERR, "%s: conflicting Model %s and extended mode: %d", drvthis->name, model_name(p->model), ext_mode);
return -1;
}
}

p->line_address = drvthis->config_get_int(drvthis->name, "lineaddress", 0, LADDR);
p->have_keypad = drvthis->config_get_bool(drvthis->name, "keypad", 0, 0);
p->have_backlight = drvthis->config_get_bool(drvthis->name, "backlight", 0, 0);
Expand Down Expand Up @@ -184,6 +247,7 @@ HD44780_init(Driver *drvthis)
if_type = connectionMapping[i].if_type;
init_fn = connectionMapping[i].init_fn;
}
report(RPT_INFO, "HD44780: selecting Model: %s", model_name(p->model));

/* Get and parse vspan only when specified */
s = drvthis->config_get_string(drvthis->name, "vspan", 0, "");
Expand Down Expand Up @@ -466,23 +530,46 @@ HD44780_init(Driver *drvthis)
void
common_init(PrivateData *p, unsigned char if_bit)
{
if (p->ext_mode) {
if (has_extended_mode(p)) {
/* Set up extended mode */
p->hd44780_functions->senddata(p, 0, RS_INSTR, FUNCSET | if_bit | TWOLINE | SMALLCHAR | EXTREG);
p->hd44780_functions->uPause(p, 40);
p->hd44780_functions->senddata(p, 0, RS_INSTR, EXTMODESET | FOURLINE);
p->hd44780_functions->uPause(p, 40);
}

/* set up standard mode. by default font_bank is zero (and is ignored on most of displays) */
p->hd44780_functions->senddata(p, 0, RS_INSTR, FUNCSET | if_bit | TWOLINE | SMALLCHAR | p->font_bank);
p->hd44780_functions->uPause(p, 40);
p->hd44780_functions->senddata(p, 0, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK);

/* Turn off display, as manipulatimg below can cause some garbage on screen */
p->hd44780_functions->senddata(p, 0, RS_INSTR, ONOFFCTRL | DISPOFF | CURSOROFF | CURSORNOBLINK);
p->hd44780_functions->uPause(p, 40);

p->hd44780_functions->senddata(p, 0, RS_INSTR, CLEAR);
p->hd44780_functions->uPause(p, 1600);
/* winstar OLEDs require 6.2ms for this command, according to spec */
p->hd44780_functions->uPause(p, (p->model == HD44780_MODEL_WINSTAR_OLED) ? 6200 : 1600);

if (p->model == HD44780_MODEL_WINSTAR_OLED) {
/* For WINSTAR OLED displays need to set TEXT mode and additionally level of brigtness.
* It is particularly important on reinitialization without powering off it first */
unsigned char pwr = WINST_PWROFF;
if (p->brightness >= 500) {
pwr = WINST_PWRON;
}
p->hd44780_functions->senddata(p, 0, RS_INSTR, WINST_MODESET | WINST_TEXTMODE | pwr);
p->hd44780_functions->uPause(p, 500);
}

p->hd44780_functions->senddata(p, 0, RS_INSTR, ENTRYMODE | E_MOVERIGHT | NOSCROLL);
p->hd44780_functions->uPause(p, 40);
p->hd44780_functions->senddata(p, 0, RS_INSTR, HOMECURSOR);
p->hd44780_functions->uPause(p, 1600);

/* Turn on display again */
p->hd44780_functions->senddata(p, 0, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK);
p->hd44780_functions->uPause(p, 40);

if (p->hd44780_functions->flush != NULL)
p->hd44780_functions->flush(p);
}
Expand Down Expand Up @@ -595,7 +682,7 @@ HD44780_position(Driver *drvthis, int x, int y)
int relY = y - p->dispVOffset[dispID - 1];
int DDaddr;

if (p->ext_mode) {
if (has_extended_mode(p)) {
/* Linear addressing, each line starts 0x20 higher. */
DDaddr = x + relY * p->line_address;
} else {
Expand Down

0 comments on commit e8cfdd2

Please sign in to comment.