⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at91_lcd.c

📁 ARM9200+嵌入式linux下的lcd驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	QINGYUN MONO LCM2401281 DRIVER 
	VERSION:1.0
	AUTHOR: LIHAO
	MODIFIED BY : Zou jian guo <zounix@126.com>
	date: 2005-2-1


*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
#include <linux/fcntl.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/compatmac.h>
#include <linux/vmalloc.h>
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/genhd.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/arch/pio.h>
#include <asm/semaphore.h>
#include <asm/sizes.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/arch/AT91RM9200_SYS.h>

#include "lcm.h"


#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__);printk(##x);}
#else
#define DPRINTK(x...) (void)(0)
#endif

#define DEVICE_NAME	"lcm"
#define lcm_MAJOR	221
#define lcm_MINOR	0
//extern AT91PS_SYS AT91_SYS; 
external AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS;

//#define setcdcmd()  (AT91_SYS->PIOC_SODR |=(unsigned int)(1<<14))
//#define setcddata() (AT91_SYS->PIOC_CODR |=(unsigned int)(1<<14))
//define cmds
#define TXHOME 0x40
#define TXAREA 0x41
#define GRHOME 0x42
#define GRAREA 0x43
#define CURSOR 0x21
#define OFFSET 0x22
#define ADPSET 0x24
#define CURSORSHAPE 0xA0
#define MODOR  0x80  //or mode
#define AWON  0xb0   //auto write
#define ARON  0xb1   //auto read
#define AWROFF 0xb2
#define AROFF  0xb3
#define RDBYTE 0xc5

#define LCM_CD_PIN (unsigned int)(1<<14) //LCM command & data ctrol pin

extern AT91PS_SYS AT91_SYS; 
static void * LCM_BASE;
static unsigned char status;
static unsigned char cmd;
static unsigned char data[2];
static unsigned char displaytype=0;
static unsigned char opratetype=0;
static unsigned char bf[3848];	//it is in use of copying data from user to kernel
//static void * LCM_BASE;
unsigned char map[127]={
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	0x00,0x00,0x00,0x00,
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,	0x0c,0x0d,0x0e,0x0f,
	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,	0x1c,0x1d,0x1e,0x1f,
	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,	0x2c,0x2d,0x2e,0x2f,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,	0x3c,0x3d,0x3e,0x3f,
	0x00,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,	0x4c,0x4d,0x4e,0x4f,
	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,	0x5c,0x5d,0x5e
	};

/*******************************************************************/
//set CD to command
static void setcdcmd(void)
{
	/*
    AT91_SYS->PIOC_PER = LCM_CD_PIN;
    AT91_SYS->PIOC_OER = LCM_CD_PIN;
    AT91_SYS->PIOC_OWER= LCM_CD_PIN;
*/
	AT91_SYS->PIOC_SODR = LCM_CD_PIN;
//	AT91_SYS->PIOC_CODR = ~(LCM_CD_PIN);

}	
/*******************************************************************/
//set CD to data
static void setcddata(void)
{
/*    AT91_SYS->PIOC_PER = LCM_CD_PIN;
    AT91_SYS->PIOC_OER = LCM_CD_PIN;
    AT91_SYS->PIOC_OWER= LCM_CD_PIN;
*/
//	AT91_SYS->PIOC_SODR = ~(LCM_CD_PIN);
	AT91_SYS->PIOC_CODR = LCM_CD_PIN;

}	
/*******************************************************************/
static void sendcmd(unsigned char cmd)
{
	//setcdcmd();
	///////////////////////////////////////////////
	//while(((status=readb(LCM_BASE)) & (0x03))!=3){
	//	set_current_state(TASK_INTERRUPTIBLE);
	//	schedule_timeout(10*HZ);
	//}
	///////////////////////////////////////////////////
	//setcdcmd();
	//writeb(cmd,LCM_BASE);
	
	setcdcmd();
	while(((status=readb(LCM_BASE)) & (0x03))!=3){
		;
	}
	setcdcmd();
	writeb(cmd,LCM_BASE);
}
/*******************************************************************/
static void senddata(unsigned char * data,unsigned short len)
{
	//unsigned short i;
	////////////////////////////////////////////////////
	//for(i=0;i<len;i++)	{
	//	setcdcmd();
	//	while(((status=readb(LCM_BASE)) & (0x03))!=3){
	//		set_current_state(TASK_INTERRUPTIBLE);
	//		schedule_timeout(10*HZ);
	//	}
	//	setcddata();
	//	writeb(data[i],LCM_BASE);
	//}
	
	unsigned short i;
	for(i=0;i<len;i++)	{
		setcdcmd();
		while(((status=readb(LCM_BASE)) & (0x03))!=3){
//				set_current_state(TASK_INTERRUPTIBLE);
//				schedule_timeout(1*HZ);
			;
		}
		setcddata();
		writeb(data[i],LCM_BASE);
	}
}

static void readdata(unsigned char *data,unsigned short len)
{
    unsigned short i,j;
	//printk("\n%x\n",data);
	for(i=0;i<len;i++)	{
//		setcdcmd();
	//	while(((status=readb(LCM_BASE)) & (0x04))!=4);
		//printk("\nxunhuan\n");
		//for(j=0;j<10000;j++);
		setcddata();
		//for(j=0;j<10000;j++);
		data[i]=readb(LCM_BASE);
	}
}

/*******************************************************************/
static void settexthomeaddr(unsigned char * data)
{
	data[0]=0x00;
	data[1]=0x00;
	senddata(data,2);
	sendcmd(TXHOME);
}
/*******************************************************************/
static void setgraphichomeaddr(unsigned char * data)
{
	data[0]=0x00;
	data[1]=0x20;	//512b,because 30(columns)*16(lines)=480b
	senddata(data,2);
	sendcmd(GRHOME);
}
/*******************************************************************/
static void settextarea(unsigned char * data)
{
	data[0]=0x1E;	//30 columns,because the lcm is 240*128 dots and the font is 8*8 dots
	data[1]=0x00;
	senddata(data,2);
	sendcmd(TXAREA);
}
/*******************************************************************/
static void setgraphicarea(unsigned char * data)
{
	data[0]=0x1E;	//30 columns,because the lcm is 240*128 dots and the font is 8*8 dots
	data[1]=0x00;
	senddata(data,2);
	sendcmd(GRAREA);
}
/*******************************************************************/
static void modeset(unsigned char cmd)
{
	sendcmd(0x80);
}
/*******************************************************************/
static void setoffsetreg(unsigned char * data)
{
	data[0]=0xf0;	//30 columns,because the lcm is 240*128 dots and the font is 8*8 dots
	data[1]=0x00;
	senddata(data,2);
	sendcmd(OFFSET);
}
/*******************************************************************/
static void setdisplaymode(unsigned char cmd)
{
	//cmd=0x94;
	//DPRINTK("\nrun setdisplaymode in the write of driver\n");
	sendcmd(cmd);
}
/*******************************************************************/
static void clearscreentext(void)
{
	unsigned int i=0;
	data[0]=0x00;
	data[1]=0x00;
	senddata(data,2);
	sendcmd(ADPSET);
	sendcmd(AWON);
	for(i=0;i<480;i++){	//30*16=480
		data[0]=0x00;
		senddata(data,1);
	}
	//DPRINTK("\nhave sent the datas in the clearscreentext of driver\n");
	cmd=AWROFF;
	sendcmd(cmd);
	DPRINTK("\nfinish clearscreentext of driver\n");	
} 
/*******************************************************************/
static void clearscreengraphy(void)
{
	unsigned int i=0;
	data[0]=0x00;
	data[1]=0x20;	//512b,because 30(columns)*16(lines)=480b
	senddata(data,2);
	sendcmd(ADPSET);
	sendcmd(AWON);
	for(i=0;i<(480*8);i++){	//30*16*8=480*8=3840byte
		data[0]=0x00;
		senddata(data,1);
	}
	sendcmd(AWROFF);
}
static void clearblock(struct point p1,struct point p2)
{
    unsigned char * p;
	unsigned short i,j,k;
	struct point datawidth;
	i=0;
	j=0;
	k=0;
	p=(unsigned char *)&i;
	
	datawidth.x=p2.x-p1.x;	//x in (0,30)
	datawidth.y=p2.y-p1.y;	//y in (0,128)
	for(k=0;k<datawidth.y;k++){
	    //compute the address pointer
	    i=p1.x+(p1.y+k)*30;
	    //set the Address Pointer
		data[0]=*p;	
		data[1]=(0x20+(*(p+1)));      //when x=1,y=2,i/256=1,then data[1]=0x21
		senddata(data,2);
		sendcmd(ADPSET);
		sendcmd(AWON);
		for(j=0;j<datawidth.x;j++){
			data[0]=0;
			senddata(data,1);
		}
		sendcmd(AWROFF);
	}
}
/*******************************************************************/
static void writetext(unsigned char x,unsigned char y,char * datachar,unsigned int len)	//x in [0,29],y in [0,15]
{
	unsigned int i;
	unsigned char data[2];
	unsigned char * p;
	unsigned short j;
	j=30*y+x;
	//DPRINTK("\nj in writetext kernel is %d\n",j);
	p=(unsigned char *)&j;
	data[0]=*p;
	data[1]=*(p+1);
	senddata(data,2);
	sendcmd(ADPSET);
	sendcmd(AWON);
	for(i=0;i<len;i++){
		data[0]=map[datachar[i]];
		senddata(data,1);
	}
	sendcmd(AWROFF);
}

static void readmap(struct point lefttop,struct point rightbottom,unsigned char *datachar)
{
	//char ddd[1000];
	unsigned char * p;
	unsigned char * q;
	unsigned short i,j,k;
	struct point datawidth;
	i=0;
	j=0;
	k=0;
	p=(unsigned char *)&i;
	q=(unsigned char *)datachar;
	datawidth.x=rightbottom.x-lefttop.x;	//x in (0,30)
	datawidth.y=rightbottom.y-lefttop.y;	//y in (0,128)
	//printk("\ndatawidth.x is %d,datawidth.y is %d\n",datawidth.x,datawidth.y);
	//printk("\nlefttop.x is %d,lefttop.y is %d rightbottom.x is %d,rightbottom.y is %d\n",lefttop.x,lefttop.y,rightbottom.x,rightbottom.y);
	for(k=0;k<datawidth.y;k++){
	//compute the address pointer
		i=lefttop.x+(lefttop.y+k)*30;
	//set the Address Pointer
		data[0]=*p;
		data[1]=(0x20+(*(p+1)));      //when x=1,y=2,i/256=1,then data[1]=0x21
		//printk("\ndata[0]=%x\n",data[0]);
		//printk("\ndata[1]=%x\n",data[1]);
		senddata(data,2);
		sendcmd(ADPSET);
		sendcmd(ARON);
		readdata(q+(k*datawidth.x),datawidth.x);
		//readdata(ddd,datawidth.x);
		sendcmd(AWROFF);
	}
}
/*******************************************************************/
static void writemap(struct point lefttop,struct point rightbottom,unsigned char * * datachar)	//x in [0,30],y in [0,128] of struct point
{
	unsigned char * p;
	unsigned char * q;
	unsigned short i,j,k;
	struct point datawidth;
	i=0;
	j=0;
	k=0;
	p=(unsigned char *)&i;
	q=(unsigned char *)datachar;
	datawidth.x=rightbottom.x-lefttop.x;	//x in (0,30)
	datawidth.y=rightbottom.y-lefttop.y;	//y in (0,128)
	for(k=0;k<datawidth.y;k++){
	//compute the address pointer
		i=lefttop.x+(lefttop.y+k)*30;
	//set the Address Pointer
		data[0]=*p;	
		data[1]=(0x20+(*(p+1)));      //when x=1,y=2,i/256=1,then data[1]=0x21
		senddata(data,2);
		sendcmd(ADPSET);
		sendcmd(AWON);
		for(j=0;j<datawidth.x;j++){
			data[0]=*(q+(k*datawidth.x)+j);
			senddata(data,1);
		}
		sendcmd(AWROFF);
	}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -