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