📄 at91_lcd.c
字号:
}
/*******************************************************************/
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 + -