Chinaunix首页 | 论坛 | 博客
  • 博客访问: 119393
  • 博文数量: 24
  • 博客积分: 616
  • 博客等级: 中士
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-01 10:54
文章分类
文章存档

2012年(24)

我的朋友

分类: LINUX

2012-08-08 14:49:06

 
 
一。显示效果: 
 
 
  
 
 
二。驱动:
 

/*********************************
**        LCD 驱动程序          **
*********************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define DEVICE_NAME "tft_tb35_micro2440_drv"
//寄存器定义
static void __iomem *base_addr;
static void __iomem *base_addr1;
static void __iomem *base_addr2;
static void __iomem *base_addr3;
static void __iomem *base_addr4;
#define LCDCON1_MICRO2440     (*(volatile unsigned long *)(base_addr 0)) //LCD控制1寄存器
#define LCDCON2_MICRO2440     (*(volatile unsigned long *)(base_addr 4))   //LCD控制2寄存器
#define LCDCON3_MICRO2440     (*(volatile unsigned long *)(base_addr 8))   //LCD控制3寄存器
#define LCDCON4_MICRO2440     (*(volatile unsigned long *)(base_addr 0x0c))//LCD控制4寄存器
#define LCDCON5_MICRO2440     (*(volatile unsigned long *)(base_addr 0x10))//LCD控制5寄存器
#define LCDSADDR1_MICRO2440   (*(volatile unsigned long *)(base_addr 0x14))//帧缓冲器开始地址1寄存器
#define LCDSADDR2_MICRO2440   (*(volatile unsigned long *)(base_addr 0x18))//帧缓冲器开始地址2寄存器
#define LCDSADDR3_MICRO2440   (*(volatile unsigned long *)(base_addr 0x1c))//帧缓冲器开始地址3寄存器
#define REDLUT_MICRO2440      (*(volatile unsigned long *)(base_addr 0x20))//红色查找表寄存器
#define GREENLUT_MICRO2440    (*(volatile unsigned long *)(base_addr 0x24))//绿色查找表寄存器
#define BLUELUT_MICRO2440     (*(volatile unsigned long *)(base_addr 0x28))//蓝色查找表寄存器
#define DITHMODE_MICRO2440    (*(volatile unsigned long *)(base_addr1 0))  //抖动模式寄存器
#define TPAL_MICRO2440        (*(volatile unsigned long *)(base_addr1 0x04))//临时调色板寄存器
#define LCDINTPND_MICRO2440   (*(volatile unsigned long *)(base_addr1 0x08))//LCD中断挂起寄存器
#define LCDSRCPND_MICRO2440   (*(volatile unsigned long *)(base_addr1 0x0c))//LCD源挂起寄存器
#define LCDINTMSK_MICRO2440   (*(volatile unsigned long *)(base_addr1 0x10))//LCD中断屏蔽寄存器
#define TCONSEL_MICRO2440     (*(volatile unsigned long *)(base_addr1 0x14))//TCON控制寄存器
#define GPCCON_MICRO2440      (*(volatile unsigned long *)(base_addr2 0))
#define GPCDAT_MICRO2440      (*(volatile unsigned long *)(base_addr2 0x04))
#define GPCUP_MICRO2440       (*(volatile unsigned long *)(base_addr2 0x08))
#define GPDCON_MICRO2440      (*(volatile unsigned long *)(base_addr2 0x10))
#define GPDDAT_MICRO2440      (*(volatile unsigned long *)(base_addr2 0x14))
#define GPDUP_MICRO2440       (*(volatile unsigned long *)(base_addr2 0x18))
#define GPGCON_MICRO2440       (*(volatile unsigned long *)(base_addr3 0))
#define GPGDAT_MICRO2440       (*(volatile unsigned long *)(base_addr3 4))
#define GPGUP_MICRO2440       (*(volatile unsigned long *)(base_addr3 8))
#define LCD_BUFFER_ADDRESS       (*(volatile unsigned long *)(base_addr4 0))
#define LOWER21BITS(n)   ((n)&0x1fffff)
#define BPPMODE_1BPP   0x08
#define BPPMODE_2BPP   0x09
#define BPPMODE_4BPP   0x0a
#define BPPMODE_8BPP   0x0b
#define BPPMODE_16BPP  0x0c
#define BPPMODE_24BPP  0x0d
#define LCDTYPE_TFT    0x03
#define ENVID_DISABLE  0
#define ENVID_ENABLE   1
#define FORMAT8BPP_5551  0
#define FORMAT8BPP_565   1
#define HSYNC_NORM       0
#define HSYNC_INV        1
#define VSYNC_NORM       0
#define VSYNC_INV        1
#define BSWP             1
#define HWSWP            1
//TFT LCD PANEL(240*320)
#define MODE_TFT_1BIT_240320    (0x4101)
#define MODE_TFT_8BIT_240320    (0x4102)
#define MODE_TFT_16BIT_240320   (0x4104)
#define MODE_TFT_24BIT_240320   (0x4108)
//TFT240320
#define LCD_XSIZE_TFT_240320    (240)
#define LCD_YSIZE_TFT_240320    (320)
#define HOZVAL_TFT_240320       (LCD_XSIZE_TFT_240320-1)
#define LINEVAL_TFT_240320      (LCD_YSIZE_TFT_240320-1)
#define CLKVAL_TFT_240320       (7)
#define VBPD_240320    1
#define VFPD_240320    2
#define VSPW_240320    1
#define HBPD_240320    19
#define HFPD_240320    10
#define HSPW_240320    10
//#define LCDFRAMEBUFFER     0x30400000
unsigned long fb_base_addr;
unsigned int bpp;
unsigned int xsize;
unsigned int ysize;
unsigned long lcd_buffer_base_addr;
unsigned long phyaddr;
static struct semaphore lock;
static struct clk *tft_clock;
unsigned long hclk;
struct page *data_temp;
unsigned long address;
static volatile unsigned long pointer=0;
 
static void tft_tb35_init(void)
{
      unsigned char red,green,blue;
      unsigned short *addr;
      unsigned int  i,j;
      //IO映射
      base_addr=ioremap(0x4d000000,0x30);
      base_addr1=ioremap(0x4d00004c,0x16);
      base_addr2=ioremap(0x56000020,0x20);
      base_addr3=ioremap(0x56000060,0x20);
      //获取时钟
      tft_clock = clk_get(NULL, "hclk");//获取PCLK
      clk_enable(tft_clock);
      hclk= clk_get_rate(tft_clock);
      //设置IO口
      GPCUP_MICRO2440=0xffffffff;
      GPDUP_MICRO2440=0xffffffff;
      GPCCON_MICRO2440=0xaaaaaaaa;
      GPDCON_MICRO2440=0xaaaaaaaa;
      GPGCON_MICRO2440=(GPGCON_MICRO2440&(~(3<<8)))|(3<<8);
      GPGUP_MICRO2440=(GPGUP_MICRO2440&(~(1<<4)))|(1<<4);
     
      //LCD初始化
      LCDCON1_MICRO2440=(CLKVAL_TFT_240320<<8)|(LCDTYPE_TFT<<5)|(BPPMODE_16BPP<<1)|(ENVID_DISABLE<<0);
      LCDCON2_MICRO2440=(VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320);
      LCDCON3_MICRO2440=(HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320);
      LCDCON4_MICRO2440=HSPW_240320;
      LCDCON5_MICRO2440=(FORMAT8BPP_565<<11)|(HSYNC_INV<<9)|(VSYNC_INV<<8)|(HWSWP<<1);
      LCDCON5_MICRO2440=(LCDCON5_MICRO2440&(~(1<<5)))|(0<<5);
      LCDCON5_MICRO2440=(LCDCON5_MICRO2440&(~(1<<3)))|(1<<3);
      //申请连续物理地址
      data_temp=alloc_pages(GFP_KERNEL,9);
      lcd_buffer_base_addr=(unsigned long)page_address(data_temp);//返回的为虚拟地址
      //定义LCD显存
       phyaddr=virt_to_phys(lcd_buffer_base_addr);//将返回的虚拟地址换算成物理地址然后赋值给帧缓冲寄存器
      LCDSADDR1_MICRO2440=(((phyaddr)>>22)<<21)|LOWER21BITS((phyaddr)>>1);
      LCDSADDR2_MICRO2440=LOWER21BITS((phyaddr (LINEVAL_TFT_240320 1)*(HOZVAL_TFT_240320 1)*2)>>1);
      LCDSADDR3_MICRO2440=(0<<11)|(LCD_XSIZE_TFT_240320*2/2);
      TPAL_MICRO2440=0;
      fb_base_addr=lcd_buffer_base_addr;
      bpp=16;
      xsize=240;
      ysize=320;
      LCDCON1_MICRO2440=LCDCON1_MICRO2440|(ENVID_ENABLE<<0);//使能屏幕输出
      addr=fb_base_addr;// (10*xsize 100);     
}
static ssize_t tft_write(struct file *file,char *buf,size_t count,loff_t *ppos)
{
   unsigned long ret=0;
   if((count pointer)<=(320*240*2))
   {
       ret=(unsigned long)copy_from_user(lcd_buffer_base_addr pointer,buf,count);//成功返回0,失败返回没有被COPY的字节数
       if(ret==0)
       {
            pointer=0;
       }
       else
       {
            pointer=pointer (320*240*2)-ret;
       }      
       return ret; 
   }
   else
   {
       pointer=0;
       return 0;
   }
  
  
  
}
static int tft_open(struct inode *inode,struct file *file)
{
       int ret;
       ret=down_trylock(&lock);
       if(ret==0)
       {
           tft_tb35_init();
           return 0;
       }       
      else
        return -EBUSY;
     
 } 
static int tft_close(struct inode *inodep,struct file *file)
{
     iounmap(base_addr);
     iounmap(base_addr1);
     iounmap(base_addr2);
     iounmap(base_addr3);
     iounmap(base_addr4);
     clk_disable(tft_clock);
      clk_put(tft_clock);
      tft_clock=NULL;
      up(&lock);//释放互斥锁
     return 0;
}

static struct file_operations dev_fops={
 .owner=THIS_MODULE,
 .open=tft_open,
 .release=tft_close,
 .write=tft_write,
};
static struct miscdevice misc={
 .name=DEVICE_NAME,
 .minor=MISC_DYNAMIC_MINOR,
 .fops=&dev_fops,
};
static int __init tft_micro2440_init(void)
{
     int ret;
     init_MUTEX(&lock);//初始化互斥锁
     ret=misc_register(&misc); //注册混杂设备
     return ret;
}
void __exit tft_micro2440_exit(void)
{
    misc_deregister(&misc); //注销混杂设备
}
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("xubin");
module_init(tft_micro2440_init);
module_exit(tft_micro2440_exit);
 
三。应用程序

#include
#include
#include
#include
#include
#include
#include "logo.h"
#define PWM_START  0x01
#define PWM_STOP   0x02
int main(int argc,char **argv)
{
    unsigned long i=1;
    unsigned long ret=0;
    int fd;
    unsigned long pointer=0;
    unsigned long count_send=0;
    fd=open("/dev/tft_tb35_micro2440_drv",O_RDWR);
    if(fd<0)
   {
     printf("error\n");
     exit(1);
   }
   pointer=0;
   count_send=153600;
   while(1)
   {     
       ret=write(fd,gImage_logo+pointer,count_send);
       printf("ret=%d\n",ret);
       if(ret==0)
       {
           pointer=0;
           count_send=153600;
       }
       else
       {
           pointer=pointer+153600-ret;
           count_send=ret;
       }
       sleep(1);
   }
   close(fd);
   return 0;
}
阅读(2335) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~