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