[Linux-parport] LCD epp mode display problem

Shunguang Ding (BJ) shunguang.ding at o2micro.com
Mon Aug 22 07:50:01 EDT 2005


Hi all,

I got one problem when I use the standard parallel port on Linux 2.4.18.

When I gcc u.c -o ku
./ku test

At the first time, the "test" string is displaying on the LCD screen
properly, but after I ran the command line for 6 times, the LCD screen
is empty.  
What's the problem then? Anybody can help me?

Thanks a lot,
Jet

The sample codes are the below:

(u.c )

#include	<stdio.h>
#include 	<stdlib.h>
#include 	<string.h>
#include	<errno.h>
#include	<fcntl.h>
#include 	<ctype.h>
#include 	<sys/sysctl.h>
#include 	<linux/sysctl.h>
#include 	<linux/version.h>
#include	<sys/ioctl.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<asm/io.h>
#include	<asm/unistd.h>
#include	<sys/time.h> 
#include	<termios.h>
#include	<unistd.h>
#include	<sys/stat.h>
#include	<linux/ppdev.h>
#include	<linux/parport.h>
#include	<sys/types.h>  
#include	<sys/times.h>  
#include	<sys/select.h> 

#define u8        unsigned char
#define LCD_CONTROL_ADDR 0x1
#define BLANK_CHAR_VALUE 0x20
#ifndef SUCCESS
	#define SUCCESS	0
#endif
#ifndef FAIL
	#define FAIL 	-1
#endif
#define LCD_CHECK_TIMES 5000000
#define SHOWING_STRING_LEN 33
#define HIGH_BIT 0x80
#define LINE_WIDTH_LCD 16
#define BASE_ZERO_LCD 0x30
#define LCD_DATA_ADDR 0x0


int MemWriteReg( int iNode, u8 Reg, u8 Value )
{
	u8 arg1;
	int mode;
	mode = IEEE1284_MODE_EPP|IEEE1284_ADDR ; 
	ioctl (iNode, PPSETMODE, &mode);
	write(iNode,&Reg,1); 
	mode = IEEE1284_MODE_EPP|IEEE1284_DATA; 
	ioctl (iNode, PPSETMODE, &mode);
	write(iNode,&Value,1);
	return SUCCESS;	
}

u8 MemReadReg(int iNode, u8 Reg )
{
	u8 arg1;
	int mode; 
	Reg &= 0xff;
	
	mode = IEEE1284_MODE_EPP|IEEE1284_ADDR; 
	ioctl (iNode, PPSETMODE, &mode);
	write(iNode,&Reg,1); //Set Address
 	mode = IEEE1284_MODE_EPP|IEEE1284_DATA; 
	ioctl (iNode, PPSETMODE, &mode);
	read(iNode,&arg1,1);
	arg1 &= 0xff; 
	return arg1 ;
}

static int waitlcdready(int iNode)
{
    	int i = 0;
	int v;

	v = MemReadReg(iNode, LCD_CONTROL_ADDR);
	while( (v & HIGH_BIT)&&( i < LCD_CHECK_TIMES))   
	{
         i ++;
	 v = MemReadReg(iNode, LCD_CONTROL_ADDR);
	 }

   	if( i >= LCD_CHECK_TIMES)
   	{
   		return FAIL;
   	}
   	return SUCCESS;
}
static void writeChars(int iNode, char *p)
{
	int n;
	char cTemp[SHOWING_STRING_LEN] = {0}; 
	if(!p)
		return;
	n = strlen(p);
	if(n == 0)	{
		return; 
	}
	n = strlen(p);
	if(n > SHOWING_STRING_LEN - 1) 
		return;
	strncpy(cTemp, p, n); 
	int k =0; 
	if(n < SHOWING_STRING_LEN) 	
	{
		for(k = n ; k < SHOWING_STRING_LEN - 1; k ++)		
		{
			 cTemp[k] = BLANK_CHAR_VALUE;
		}
	} 
	int i = 0;	
	if(waitlcdready(iNode))
		return;
	MemWriteReg(iNode,LCD_CONTROL_ADDR, HIGH_BIT);
	for(i = 0 ; i < SHOWING_STRING_LEN - 1; i ++)	
	{	
		if(i == LINE_WIDTH_LCD) 
		{
			if(waitlcdready(iNode))
				continue;
			MemWriteReg(iNode,LCD_CONTROL_ADDR,
(BASE_ZERO_LCD + LINE_WIDTH_LCD) |HIGH_BIT);
		}
		if(waitlcdready(iNode))
				continue;
		MemWriteReg(iNode,LCD_DATA_ADDR, cTemp[i]);
	}
	return;	
}

int main(int argc, char *argv[])
{
	int mode, i;
	int iNode; 
	if(argc < 2)
	{
		printf("<cmd> <string>\n");
		return -1;
	}
	iNode = open("/dev/parport0", O_RDWR );
	if( iNode <= 0 )
		return -1;
	ioctl(iNode, PPCLAIM);
	printf("%s\n", argv[1]);
	writeChars(iNode,argv[1]);
	 
	ioctl (iNode, PPRELEASE); 
	close(iNode); 
	return 0;
}




More information about the Linux-parport mailing list