www.pudn.com > LCDRT12232F.rar > lcd_12232F.c


/* Copyright (c) 2007,9,18  北京华龙通有限公司事业二部一室 
* 
* 文件名称:lcd12232F.c 
* 摘 要:使用Avalon总线的4×4键盘底层驱动。 
* 
* 当前版本:v1.1.0 
* 日期:2008年2月18日 
*/ 
#include 	 
#include 	 
#include  
#include 	 
#include  
 
#include "lcd_12232F.h" 
 
#define SUCCESS 0 
 
 
static int Device_Open = 0;
static int line=1; 
 static char Message[BUF_LEN]; 
static char *Message_Ptr; 
 
/***************************************** 
 *    定义用户程序访问外设接口函数 
 ****************************************/ 
  
/* 
 * Function 1:device_open 
 */ 
static int device_open(struct inode *inode, struct file *file) 
{  
  if (Device_Open) 
    return -EBUSY; 
   
  Device_Open++; 
  Message_Ptr = Message; 
  try_module_get(THIS_MODULE); 
  return SUCCESS; 
} 
 
/* 
 * Function 2:device_release 
 */ 
static int device_release(struct inode *inode, struct file *file) 
{   
  Device_Open--; 
   
  module_put(THIS_MODULE); 
  return SUCCESS; 
} 
 
/* 
 * Function 3:device_read 
 */ 
static ssize_t device_read(struct file *file,char __user * buffer,size_t length,loff_t * offset) 
{ 
  int bytes_read = 0;      
  if (*Message_Ptr == 0)       
    return 0;   
  while (length && *Message_Ptr) { 
    put_user(*(Message_Ptr++), buffer++); 
    length--; 
    bytes_read++; 
  }   
  return bytes_read; 
} 
 
/* 
 * Function 4:device_write 
 */
static ssize_t device_write(struct file *file,const char __user * buffer, size_t length, loff_t * offset)
{
  int ii; 
  unsigned char c;
  switch(line)
     {
      case 1:
         WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE1_OFFSET); 
         udelay(50); 
         for (ii = 0; ii < length && ii < BUF_LEN; ii++) 
                          { 
            get_user(c, buffer + ii); 
            WriteNios(ADR_LCD_DATA, (unsigned long) c); 
            udelay(50); 
                          }  
          if (length < BUF_LEN)         
                          {      	 
	         for (ii = length; ii < BUF_LEN; ii++) 
		                    { 
		         WriteNios(ADR_LCD_DATA,0x20); 
		         udelay(50); 
		                    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                	          WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE2_OFFSET); 
	          udelay(50); 
	         for (ii = BUF_LEN; ii < BUF_LEN+BUF_LEN; ii++) 
		                   { 
		         WriteNios(ADR_LCD_DATA,0x20); 
		         udelay(50); 
		                   }       
                            } 
          else                     //当用户缓冲区长度大于16bytes 
                          { 
                                //此时,用户数据已经将第一行写满,准备接着写第二行 
            WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE2_OFFSET); 
            udelay(50); 
            for (ii = BUF_LEN; ii < length && ii < BUF_LEN+BUF_LEN; ii++) 
		                   { 
		         get_user(c, buffer + ii); 
		         WriteNios(ADR_LCD_DATA,(unsigned long) c); 
		         udelay(50); 
		                    }		   
		        if (length < BUF_LEN + BUF_LEN)  //如果用户缓冲区数据长度小于或等于32bytes 
		                   { 
		          for (ii = length; ii < BUF_LEN + BUF_LEN; ii++) 
			                      { 
			          WriteNios(ADR_LCD_DATA, 0x20); 
			          udelay(50); 
			                      } 
		                   }
                            }
           break;
      case 2:
	          WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE2_OFFSET); 
	          udelay(50);
             for (ii = 0; ii < length && ii < BUF_LEN; ii++) 
		                   { 
		         get_user(c, buffer + ii); 
		         WriteNios(ADR_LCD_DATA,(unsigned long) c); 
		         udelay(50); 
		                    }		   
		        if (length < BUF_LEN )  //如果用户缓冲区数据长度小于或等于32bytes 
		                   { 
		          for (ii = length; ii < BUF_LEN ; ii++) 
			                      { 
			          WriteNios(ADR_LCD_DATA, 0x20); 
			          udelay(50); 
			                      } 
		                   }
           break;
        }
   return length;
}
/*
 
static ssize_t device_write(struct file *file,const char __user * buffer, size_t length, loff_t * offset) 
{ 
  int ii; 
  unsigned char c; 
  //0x80=10000000;代表设定DDRAM第一行地址到地址计数器AC, 
  WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE1_OFFSET); 
  udelay(50); 
  //length为用户缓冲区的长度,BUF_LEN=16   
  for (ii = 0; ii < length && ii < BUF_LEN; ii++) 
    { 
      get_user(c, buffer + ii); 
      //将从用户空间得到的字符c写到LCD的Data Register中 
      WriteNios(ADR_LCD_DATA, (unsigned long) c); 
      udelay(50); 
    }  
  if (length < BUF_LEN)        //当用户缓冲区长度小于或等于16bytes 
    {      	 
	    //将第一行其它写成空,0x20的ASCII值为空 
	    for (ii = length; ii < BUF_LEN; ii++) 
		   { 
		    WriteNios(ADR_LCD_DATA,0x20); 
		    udelay(50); 
		   }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
	    //将第二行其它全部写成空,0x20的ASCII值为空 
	    WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE2_OFFSET); 
	    udelay(50); 
	   for (ii = BUF_LEN; ii < BUF_LEN+BUF_LEN; ii++) 
		  { 
		  WriteNios(ADR_LCD_DATA,0x20); 
		  udelay(50); 
		  }       
    } 
   else                     //当用户缓冲区长度大于16bytes 
    { 
     //此时,用户数据已经将第一行写满,准备接着写第二行 
     WriteNios(ADR_LCD_COMMAND,ADR_LCD_LINE2_OFFSET); 
     udelay(50); 
     for (ii = BUF_LEN; ii < length && ii < BUF_LEN+BUF_LEN; ii++) 
		 { 
		  get_user(c, buffer + ii); 
		  WriteNios(ADR_LCD_DATA,(unsigned long) c); 
		  udelay(50); 
		 }		   
		 if (length < BUF_LEN + BUF_LEN)  //如果用户缓冲区数据长度小于或等于32bytes 
		 { 
		  //将第二行未写满的DDRAM写成空 
		  for (ii = length; ii < BUF_LEN + BUF_LEN; ii++) 
			{ 
			  WriteNios(ADR_LCD_DATA, 0x20); 
			  udelay(50); 
			} 
		 } 
    } 
  //返回从用户段写入内核段数据的长度 
  return length; 
} 
*/ 
/*  
 *  Function 5:device_ioctl 
 */ 
static int device_ioctl(struct inode *inode,struct file *file, unsigned int ioctl_num,unsigned long ioctl_param) 
{ 
  int i; 
  char *temp; 
  char ch; 
   
  switch (ioctl_num)  
  { 
    case IOCTL_WRITE:                       // 将temp指针指向用户空间的message数据,将这条信息设置为需要传递给LCD设备的信息           
         temp = (char *)ioctl_param;        // 得到用户进程传递给ioctl函数的地址内的数据取出           
         get_user(ch, temp);                    
         for (i = 0; ch && i < BUF_LEN + BUF_LEN; i++, temp++) 
           { 
        	   get_user(ch, temp); 
           }                               //解析这条message的长度,得到i值 
         if (i