[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