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

📄 at91_lcd.c

📁 ARM9200+嵌入式linux下的lcd驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
}
/*******************************************************************/
static void drawdot(unsigned short x,unsigned short y,unsigned char set)
{
	unsigned short i=0;
	unsigned char * p;
	p=(unsigned char *)&i;
	//set Address Pointer
	
	if(x>239) x=239;
	if(y>127) y=127;
	
	i=x/8+y*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);
	if(set)	
		  cmd = 0xf8|(7- (x & 7)); 
	else  cmd = 0xf0|(7- (x & 7)); 
	sendcmd(cmd);
}

static void setcursoraddr(unsigned char ascx,unsigned char ascy)
{
	if(ascx>30) ascx=30;
	if(ascy>16) ascy=16;
	//i=ascx+((ascy+1)<<1);
	//set the Cursor Pointer
	data[0]=ascx;
	data[1]=(ascy<<1)+1;      //when x=1,y=2,i/256=1,then data[1]=0x21
	//printk("\nkernel cursor==x is %d,y is %d\n",data[0],data[1]);
	senddata(data,2);
	sendcmd(CURSOR);
	DPRINTK("setcursoraddr in ioctl");
}
/*******************************************************************/
static int lcm_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
{
	if (_IOC_TYPE(cmd)!=LCM_MAGIC)
		return -ENOTTY;
	switch(cmd){
		case LCM_SETDISPLAYMODE:
			if(get_user(displaytype,(unsigned char * )arg))
				return -EFAULT;
			if(displaytype!=DISPLAY_GRAPHY && displaytype!=DISPLAY_TEXT && displaytype!=DISPLAY_GRAPHYCURSOR){
				displaytype=DISPLAY_TEXT;
				return -ENOTTY;
			}
			if(displaytype == DISPLAY_TEXT){
				setdisplaymode(0x94);
				DPRINTK("setdisplaymode text in ioctl");
			}
			else if(displaytype == DISPLAY_GRAPHYCURSOR){
				setdisplaymode(0x9F);
				//printk("setdisplaymode cursor in ioctl")
				DPRINTK("setdisplaymode cursor in ioctl");
			}
			else{
				setdisplaymode(0x98);
				DPRINTK("setdisplaymode graphy in ioctl");
			}
			//DPRINTK("\nioctl setdisplaymode success,now is %d\n",displaytype);
			break;
		case LCM_CLEARSCREENTEXT:
			if(displaytype!=DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_CLEARSCREENTEXT;
			clearscreentext();
			DPRINTK("\nioctl clearscreentext success,now operatetype is %d\n",opratetype);
			break;
		case LCM_WRITETEXT:
			if(displaytype != DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_WRITETEXT;
			DPRINTK("\nioctl writetext success,now operatetype is %d\n",opratetype);
			break;
		case LCM_CLEARSCREENGRAPHY:
			DPRINTK("\nioctl clearscreengraphy begin\n");
			if(displaytype==DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_CLEARSCREENGRAPHY;
			clearscreengraphy();
			DPRINTK("\nioctl clearscreengraphy success,now operatetype is %d\n",opratetype);
			break;
		case LCM_CLEARBLOCK:
		{
			DPRINTK("\nioctl clearblock begin\n");
			if(displaytype ==DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_CLEARBLOCK;
			//clearblock(p1,p2);
			DPRINTK("\nioctl clearblock success,now operatetype is %d\n",opratetype);
			break;
		}
		case LCM_WRITETMAP:
			if(displaytype==DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_WRITETMAP;
			DPRINTK("\nioctl writemap success,now operatetype is %d\n",opratetype);
			break;	
        case LCM_READMAP:
            if(displaytype==DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_READMAP;
			DPRINTK("\nioctl readmap success,now operatetype is %d\n",opratetype);
            break;		
		case LCM_DRAWDOT:
			DPRINTK("\nioctl drawdot begin\n");
			if(displaytype==DISPLAY_TEXT)
				return -ENOTTY;
			opratetype=OPRATE_DRAWDOT;
			DPRINTK("\nioctl drawdot success,now operatetype is %d\n",opratetype);
			break;
		case LCM_SETCURSORADDR:
			DPRINTK("\nioctl setcursoraddr begin\n");
		    if(displaytype!=DISPLAY_GRAPHYCURSOR)
				return -ENOTTY;
			opratetype=OPRATE_SETCUSORADDR;
			DPRINTK("\nioctl set cursor addr success,now operatetype is %d\n",opratetype);
			break;
	}
	return 0;
}
/*******************************************************************/
static int lcm_open (struct inode *inode, struct file *filp)
{
		
	/*DPRINTK("\nlcm_open begin\n");
	AT91_SYS->PMC_PCER |= (1<<AT91C_ID_PIOC);
	//AT91F_SMC2_CfgPIO();	//we required,lh
	AT91_SYS->PIOC_ASR = ((unsigned int) AT91C_PC10_NCS4_CFCS) |((unsigned int) AT91C_PC9_A25_CFRNW) |((unsigned int) AT91C_PC12_NCS6_CFCE2) |((unsigned int) AT91C_PC11_NCS5_CFCE1);
	//DPRINTK("\nat91_sys->pioc_asr assignment success.\n");
	AT91_SYS->PIOC_BSR = 0;
	AT91_SYS->PIOC_PDR = ((unsigned int) AT91C_PC10_NCS4_CFCS) |((unsigned int) AT91C_PC9_A25_CFRNW) |((unsigned int) AT91C_PC12_NCS6_CFCE2) |((unsigned int) AT91C_PC11_NCS5_CFCE1);
	//here we config the pc14 and pc1 as gpio pins,lh
	//Step1 Enable PIOC
    AT91_SYS->PIOC_PER=(unsigned int)(1<<14)|(unsigned int)(1<<1);
 	//Step2 Select Peripheral B
 	//*(AT91C_PIOC_BSR)=(unsigned int)(1<<15)|(unsigned int)(1<<14)|(unsigned int)(1)|(unsigned int)(1<<1);
 	//Step3 Enable Output
    AT91_SYS->PIOC_OER=(unsigned int)(1<<14)|(unsigned int)(1<<1);
    AT91_SYS->PIOC_OWER=(unsigned int)(1<<14)|(unsigned int)(1<<1);
 	//Step4 Enable Pull-up 
    AT91_SYS->PIOC_PPUER=(unsigned int)(1<<14)|(unsigned int)(1<<1);
 	//Step5 Exchange light PIO14 and PIO15 For 10 Times
    //as pc_14 is high,the data as cmd else as data,lh 
	AT91_SYS->PIOC_CODR=(unsigned int)(1<<14);      //input data ,8 pin,low
    AT91_SYS->PIOC_SODR=(unsigned int)(1<<14);      //input cmd ,8 pin ,high
	//DPRINTK("\ncycle begin.\n");
	//while(1);
	AT91_SYS->EBI_CSA &= 0xef;                               //the cs4a(4) must be 0,we required,lh
	AT91_SYS->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);	//we required,lh
	AT91_SYS->EBI_SMC2_CSR[4] = (AT91C_SMC2_NWS & 0x7F) | 
	                             AT91C_SMC2_WSEN |
								(AT91C_SMC2_TDF & 0x100) | 
								 AT91C_SMC2_DBW_8|
								 0x33000000;	//we required,lh
								 */
	DPRINTK("\nlcm_open begin\n");
	//enable clock 
	AT91_SYS->PMC_PCER = (1<<AT91C_ID_PIOC);
	//AT91F_SMC2_CfgPIO();	//we required,lh
	//Step1 Enable PIOC
    AT91_SYS->PIOC_PER = LCM_CD_PIN;
 	//Step3 Enable Output
    AT91_SYS->PIOC_OER = LCM_CD_PIN;
    AT91_SYS->PIOC_OWER = LCM_CD_PIN;
 	//Step4 Enable Pull-up 
    AT91_SYS->PIOC_PPUER = LCM_CD_PIN;
    //as pc_14 is high,the data as cmd else as data,lh 
	
	AT91_SYS->PIOC_CODR = LCM_CD_PIN;      //input data ,8 pin,low
	
    AT91_SYS->PIOC_SODR = LCM_CD_PIN;      //input cmd ,8 pin ,high
	//AT91_SYS->EBI_CSA &= 0xef;                               //the cs4a(4) must be 0,we required,lh
	AT91_SYS->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);	//we required,lh
	
	//config the bank 4 for lcm 8bit bus 
	AT91_SYS->EBI_SMC2_CSR[4] = (AT91C_SMC2_NWS & 0x7F) | 
	                             AT91C_SMC2_WSEN |
								(AT91C_SMC2_TDF & 0x100) | 
								 AT91C_SMC2_DBW_8|
								 0x33000000;	//we required,lh
	AT91_SYS->EBI_SMC2_CSR[4] = 0X408F;
	data[0]=0x00;
	settexthomeaddr(data);
	setgraphichomeaddr(data);
	settextarea(data);
	setgraphicarea(data);
	modeset(0);	//set the displaymode  or
	//setoffsetreg(data);	//set the external cgram
	mdelay(100);
	//setdisplaymode(0x94);	//text mode display,30*16
	//displaytype=DISPLAY_TEXT;
	//clearscreentext();
	//XJZ  MODIFY  2005-05-10
	sendcmd(CURSORSHAPE|1);  
	setdisplaymode(0x9C);	//text mode display,30*16
	displaytype=DISPLAY_GRAPHYCURSOR;
	clearscreentext();
	
	//XJZ  MODIFY END
	//DPRINTK("open success\n");
	MOD_INC_USE_COUNT;
//	printk("open success\n");
	
	return 0;          /* success */
}
/*******************************************************************/
static int lcm_release (struct inode *inode, struct file *filp)
{
	//release_mem_region(LCM_BASE,2);
	MOD_DEC_USE_COUNT;
	return 0;
}
/*******************************************************************/
ssize_t lcm_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
	struct point p1,p2;
	int i;
	unsigned short * p=(unsigned short *)bf;
	unsigned char * q=(unsigned char *)bf;

	DPRINTK("\nlcm_read begin,count is %d.\n",count);
	if(count >3848)
		count=3848;
	copy_from_user(bf,buf,8);
	//copy_to_user(buf,bf,count);
	switch(opratetype){
		case OPRATE_READMAP:{
			DPRINTK("\nreadmap in lcm_read begin.\n");
			p1.x=*p;
			p1.y=*(p+1);
			p2.x=*(p+2);
			p2.y=*(p+3);
			DPRINTK("\np1.x is %d,p1.y is %d,p2.x is %d,p2.y is %d\n",p1.x,p1.y,p2.x,p2.y);
			//printk("\np1.x is %d,p1.y is %d,p2.x is %d,p2.y is %d\n",p1.x,p1.y,p2.x,p2.y);
			readmap(p1, p2, (unsigned char *)(q+8));
			//printk("kernel count = %d\n",count);
			copy_to_user(buf,(char *)q,count);
		}
	}
	//DPRINTK("\ncopy_from_user count :%d in the lcm_write.\n",count);
	return count;
}
/*******************************************************************/
ssize_t lcm_write (struct file *filp, const char *buf,size_t count,  loff_t *f_pos)
{

	unsigned short * p=(unsigned short *)bf;
	unsigned char * q=(unsigned char *)bf;
	struct point p1,p2;
	int i;
	DPRINTK("\nlcm_write begin,count is %d.\n",count);
	//unsigned int  * q=(unsigned int *)bf;
	if(count >3848)
		count=3848;

	copy_from_user(bf,buf,count);
	DPRINTK("\ncopy_from_user count :%d in the lcm_write.\n",count);
	switch(opratetype){
		case OPRATE_DRAWDOT:{
			DPRINTK("\ndrawdot in lcm_write begin.\n");
			DPRINTK("\nx is %d,y is %d,set is %d\n",*p,*(p+1),*(q+4));
			drawdot(*p,*(p+1), *(q+4));
			DPRINTK("\ndrawdot success in the lcm_write.\n");
			break;
		}
		case OPRATE_SETCUSORADDR:{
			DPRINTK("\nset cursor addr in lcm_write begin.\n");
			//DPRINTK("\np==x is %d,y is %d\n",*p,*(p+1));
			DPRINTK("\nkernel q==x is %d,y is %d\n",*q,*(q+1));
			//printk("\nkernel q==x is %d,y is %d\n",*q,*(q+1));
			setcursoraddr(*q,*(q+1));
			DPRINTK("\nsetcursor addr success in the lcm_write.\n");
			break;
		}
		case OPRATE_CLEARBLOCK:{
			struct point p1,p2;
			DPRINTK("\nclear block in lcm_write begin.\n");
			//DPRINTK("\np==x is %d,y is %d\n",*p,*(p+1));
			//DPRINTK("\nkernel q==x is %d,y is %d\n",*q,*(q+1));
			p1.x=*p;
			p1.y=*(p+1);
			p2.x=*(p+2);
			p2.y=*(p+3);
			//printk("p1.x=%d\n",p1.x);
			//printk("p1.y=%d\n",p1.y);
			//printk("p2.x=%d\n",p2.x);
			//printk("p2.y=%d\n",p2.y);
			
			clearblock(p1,p2);
			DPRINTK("\nclear block success in the lcm_write.\n");
			break;
		}
		case OPRATE_WRITETEXT:{
			DPRINTK("\nwritetext in lcm_write begin.\n");
			DPRINTK("\nx is %d,y is %d,len is %d in the lcm_write\n",*q,*(q+1),*((int *)(q+2)));
			DPRINTK("\nchar is %c ,char is %c ,char is %c ,char is %c ,char is %c in the lcm_write.",*(q+6),*(q+7),*(q+8),*(q+9),*(q+10));
			writetext(*q, *(q+1), bf+2, count);
			DPRINTK("\nwrite success in the lcm_write.\n");
			break;
		}
		case OPRATE_WRITETMAP:{
			DPRINTK("\nwritemap in lcm_write begin.\n");
			p1.x=*p;
			p1.y=*(p+1);
			p2.x=*(p+2);
			p2.y=*(p+3);
			//DPRINTK("\np1.x is %d,p1.y is %d,p2.x is %d,p2.y is %d\n",p1.x,p1.y,p2.x,p2.y);
			//for(i=8;i<count;i++)
			//	DPRINTK("\nbuf +%d is %d\n",i,*(q+i));
			writemap(p1, p2, (unsigned char **)(q+8));
			DPRINTK("\nwrite success in the writemap of lcm_write .\n");
		}
	}
	DPRINTK("\nwrite success\n");
	return count;
}
/*******************************************************************/
struct file_operations lcm_fops = {
	owner:		THIS_MODULE,
	open:	    lcm_open,
	release:   	lcm_release,
	read:		lcm_read,
	write:	    lcm_write,
	ioctl:		lcm_ioctl,
};
/*********************************************************************/
#ifdef CONFIG_DEVFS_FS
//static devfs_handle_t  devfs_lcm_dir, devfs_lcmraw,devfs_lcm;
static devfs_handle_t  devfs_lcm;
#endif
/*******************************************************************/
static int __init at91_lcm_init(void)
{
	

#ifdef CONFIG_DEVFS_FS
	//devfs_lcm_dir = devfs_mk_dir(NULL, "lcm", NULL);
	devfs_lcm = devfs_register(NULL, "lcm", DEVFS_FL_DEFAULT,
			lcm_MAJOR, lcm_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,
			&lcm_fops, NULL);
	//devfs_lcmraw  = devfs_register(NULL, "lcm", DEVFS_FL_DEFAULT,lcm_MAJOR, lcm_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&lcm_fops, NULL);
#else
    int result = 0;
	result = register_chrdev(lcm_major, DEVICE_NAME, &lcm_fops);
	if (result < 0) 	{
		DPRINTK("LCM ERROR: Can't  get MAJOR %d", lcm_major);
		return result;
	}
	if (lcm_major == 0)  
	{
		lcm_major = result; /* dynamic */
		DPRINTK("the major is %d\n",lcm_major);
	}
    
#endif
	//DPRINTK(DEVICE_NAME " initialized\n");
	LCM_BASE=ioremap_nocache(0x50000000,2);
	printk(DEVICE_NAME " initialized\n");
	return 0;
}
/*******************************************************************/
static void __exit at91_lcm_cleanup(void)
{
#ifdef CONFIG_DEVFS_FS
	devfs_unregister(devfs_lcm);
#else
   unregister_chrdev(lcm_major, DEVICE_NAME);
#endif
	//unregister_chrdev(lcm_MAJOR, DEVICE_NAME);
	iounmap(LCM_BASE);
	printk("\nlcm_cleanup finished\n");
}

module_init(at91_lcm_init);
module_exit(at91_lcm_cleanup);

MODULE_AUTHOR("zounix");
MODULE_DESCRIPTION("AT91 lcm 2401281 Driver (AT91_LCM)");
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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