[Lcdproc] Parallel HD44780 LCD not working, Working demo source
Ralf Wessling
r.wessling@logiware.de
Sun May 20 23:05:01 2007
This is the source code from the working sample application. Perh=
abst someone is able to create a modified hd44780 driver.
/*LinuxLCM.c ,for LCM & KeyPad in Linux OS
*Compile: 'gcc -o linuxlcm linuxlcm.c' */
#include <stdio.h>
#include <unistd.h>
#include <machine/cpufunc.h>
#include <time.h>
#define LPT_DATA_OUT 0x378 //Which Paralle Port use
#define LPT_STATUS_IN 0x379 //PORT+1
#define LPT_CTL_OUT 0x37a //PORT+2
#define LCD_CLEAR 0x001
#define LCD_HOME 0x002
#define LCD_ENT 0x004
#define LCD_ENT_INC 0x002
#define LCD_ENT_SHIFT 0x001
#define LCD_DISP 0x008
#define LCD_DISP_ON 0x004
#define LCD_DISP_CURS_ON 0x002
#define LCD_DISP_BLINK_ON 0x001
#define LCD_SET_FUNC 0x020
#define LCD_FUNC_8BITS 0x010
#define LCD_FUNC_2LINE 0x008
#define LCD_SET_CG_ADDR 0x040
#define LCD_SET_DD_ADDR 0x080
#define LCD_KEY_DOWN 0x0c7
#define LCD_KEY_UP 0x0cf
#define LCD_KEY_RIGHT 0x0e7
#define LCD_KEY_LEFT 0x0ef
/* These simple code ,I use Macro way to make it work */
#define lcd_set_blinking_cursor(onoff) if (onoff) \
lcd_cmd(LCD_DISP|LCD_DISP_ON|LCD_DISP_CURS_ON|LCD_DISP_BLINK_ON);=
\
else lcd_cmd(LCD_DISP|LCD_DISP_ON|LCD_DISP_CURS_ON);
#define lcd_home_r lcd_cmd(LCD_HOME);\
usleep(10); // According to data sheet, need to wait longer
#define lcd_clear_r lcd_cmd(LCD_CLEAR);\
usleep(10); // According to data sheet, need to wait longer
void lcd_cmd(int para);
void lcd_init(void);
void print_menu(char *p);
void lcd_goto_rc(int row,int col);
void lcd_write(int wdata);
int main (void)
{
int keyboard_hit,return_key;
char Message5[]=3D{"'LCM(20*2) Panel Show and KeyPAd Test Program=
.......By Mark.(2003/11/06)\n"};
char Message[]=3D{"Press any key to test keypad.............Press=
Ctrl-C to exit!!\n"};
char Message0[]=3D{"Press Upper Key.........................\n"};=
char Message1[]=3D{"Press Lower Key.........................\n"};=
char Message2[]=3D{"Press ESC Key...........................\n"};=
char Message3[]=3D{"Press Enter Key.........................\n"};=
int iofd;
if ((iofd =3D open("/dev/io", 0)) =3D=3D -1)
err(1, "cannot open /dev/io");
/*iopl(3); allow to access all 65536 IO ports*/
printf(Message5);
printf(Message);
lcd_clear_r; //Clear the LCD
while(1){
return_key=3DRead_KeyPad();
if (return_key!=3D0){
switch (return_key) {
case LCD_KEY_DOWN:
lcd_init();
print_menu(Message1);
break;
case LCD_KEY_UP:
lcd_init();
print_menu(Message0);
break;
case LCD_KEY_RIGHT:
lcd_init();
print_menu(Message3);
break;
case LCD_KEY_LEFT:
lcd_init();
print_menu(Message2);
break;
}
}
}
exit(0);
}
int Read_KeyPad(void)
{
int r_temp,r_temp1;
r_temp=3Dinb(LPT_STATUS_IN);
usleep(5);
r_temp1=3Dinb(LPT_STATUS_IN);
if (r_temp1=3D=3Dr_temp)
return 0; //No Pressed KeyPad
else return r_temp1; //Yes,return the keypad value
}
/* ## lcd_init
## This routine need only be called ONCE
## This routine MUST be called prior to using any
## of the other lcd_* routines in this file (with
## the possible exception of lcd_cmd and lcd_read_key,
## but I'm not sure what will happen with lcd_read_key
## if this has not yet been called... */
void lcd_init(void)
{
int set_temp=3D0,i;
// set LCD interface for 8-bits, and 2-line display
set_temp|=3DLCD_SET_FUNC;
set_temp|=3DLCD_FUNC_8BITS;
set_temp|=3DLCD_FUNC_2LINE;
lcd_cmd(set_temp);
set_temp&=3D0;
// turn on the backlight, cursor is off, blink is off
set_temp|=3DLCD_DISP;
set_temp|=3DLCD_DISP_ON;
lcd_cmd(set_temp);
// set entry mode/cursor move direction to 'increase' (right)
// display will not be shifted (ie: insert mode off)
lcd_cmd(0x06);
// set CG address to 8 - char(1) -- we will skip char(0), since
// it may be problematic for NULL-term strings (ie:lcd_print_stri=
ng)
set_temp&=3D0;
set_temp|=3DLCD_SET_CG_ADDR;
set_temp|=3D8;
lcd_cmd(set_temp);
lcd_home_r;
lcd_clear_r;
return;
}
/* ## print_menu
## INPUT: pointer to a 40-character string to be
## displayed - the first 20 on the top line and the
## second 20 chars for the bottom line. The string
## need not be null-terminated and may contain any
## characters. */
void print_menu(char *p)
{
int set_1=3D0,i=3D0;
lcd_home_r;
p2: // move cursor to 0, 0 and print first 20 chars...
lcd_home_r;
for (i=3D0;i<20;i++)
lcd_write(p[i]);
// now, move cursor to 1,0 and print next 20 chars...
lcd_goto_rc(1,0);
for (i=3D0;i<20;i++)
lcd_write(p[i]);
return;
}
/* ## lcd_cmd
## INPUT: send byte as a command.
## This routine will set the LCD lines RS=3D=3Dlow, R/W=3D=3Dlow=20=
and
## then write the byte in %al to the lines DB0-DB7 -- all this
## good stuff is connected to the paralel port, DB0-DB7 is
## accessed through the DATA PORT and RS, R/W are accessed throug=
h
## the CONTROL PORT of the parallel port. */
void lcd_cmd(int para)
{
outb(LPT_CTL_OUT,0x0c8);
outb(LPT_DATA_OUT,para);
outb(LPT_CTL_OUT,0x0ca);
usleep(10);
return;
}
void lcd_goto_rc(int row,int col)
{
col&=3D0x01f;
col|=3DLCD_SET_DD_ADDR;
if (row)
col|=3D0x040;
lcd_cmd(col);
return;
}
/* ## lcd_write
## INPUT: byte to be written to DISPLAY or CG RAM in LCD.
## This routine will set the LCD line RS=3D=3Dhigh, R/W=3D=3Dlow=20=
and
## then send the data in %al to DB0-DB7 of the LCD.
## If the LCD is expecting Display data (default mode), the conte=
nts
## will appear on the LCD screen (so long as the cursor location
## is valid for writing -- there are off-screen locations!!!)
## If the LCD is expecting CG data, the contents will go into
## the CG RAM, etc... */
void lcd_write(int wdata)
{
outb(LPT_CTL_OUT,0x0c0);
outb(LPT_DATA_OUT,wdata);
outb(LPT_CTL_OUT,0x0c2);
usleep(10);
return;
}
---
Best regards ... Mit freundlichen Gr=FC=DFen ... Saludos cordiale=
s
Ralf Wessling
________________________________
Von: lcdproc-admin@lists.omnipotent.net [mailto:lcdproc-admin@lis=
ts.omnipotent.net] Im Auftrag von Ralf Wessling
Gesendet: Samstag, 19. Mai 2007 17:01
An: lcdproc@lists.omnipotent.net
Betreff: [Lcdproc] Parallel HD44780 LCD not working
Hi,
i have a Firewall box with an integrated LCD runnung on freeBSD.=20=
The LCD ist connected via a parallel port (0x0378) and seem to ha=
ve the hd44780 controller.
I was able to start LCDproc and tried every parallel driver and s=
etting without luck. I have a running sample application which is=
running fine.
This is the only information on the wiring from the manual :
http://forum.pfsense.org/index.php?action=3Ddlattach;topic=3D4847=
.0;attach=3D1220;image
I can provide the c source (very simple demo app) for the sample=20=
application which is running fine.
Who can help to make a driver for this popular firewall hardware.=
---
Best regards ... Mit freundlichen Gr=FC=DFen ... Saludos cordiale=
s
Ralf Wessling