天嵌 ARM开发社区

 找回密码
 注册
查看: 1722|回复: 1

参照裸机测试程序写的linux下lcd的驱动(仅用于显示一幅图片)求助~~~

[复制链接]
桥~ 发表于 2012-4-21 11:08:26 | 显示全部楼层 |阅读模式
本帖最后由 桥~ 于 2012-4-21 11:23 编辑

初学驱动~试着写了下面的程序
insmod qiao_lcd.ko   后屏幕黑屏了  只能说有反应
运行测试程序后写数据成功了,但是没显示图片

求指导~~~
驱动程序如下:

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/delay.h>
  6. #include <linux/poll.h>
  7. #include <asm/irq.h>
  8. #include <asm/io.h>
  9. #include <linux/interrupt.h>
  10. #include <asm/uaccess.h>
  11. #include <mach/regs-gpio.h>
  12. #include <mach/hardware.h>
  13. #include <plat/regs-timer.h>
  14. #include <mach/regs-irq.h>
  15. #include <mach/regs-lcd.h>
  16. #include <asm/mach/time.h>
  17. #include <linux/clk.h>
  18. #include <linux/cdev.h>
  19. #include <linux/device.h>
  20. #include <linux/miscdevice.h>

  21. #define DEVICE_NAME "qiao_lcd"

  22. #define MVAL  (13)
  23. #define MVAL_USED  (0)   //0=each frame   1=rate by MVAL
  24. #define INVVDEN  (1)   //0=normal       1=inverted
  25. #define BSWP  (0)   //Byte swap control
  26. #define HWSWP  (1)   //Half word swap control
  27. #define PNRMODE  (3)   // 设置为TFT屏
  28. #define BPPMODE  (12)   // 设置为16bpp模式
  29. //TFT_SIZE
  30. #define LCD_XSIZE_TFT  (480)
  31. #define LCD_YSIZE_TFT  (272)
  32. #define SCR_XSIZE_TFT  (480)
  33. #define SCR_YSIZE_TFT  (272)
  34. //Timing parameter for 4.3' LCD
  35. #define VBPD   (2)   //垂直同步信号的后肩
  36. #define VFPD   (4)   //垂直同步信号的前肩
  37. #define VSPW   (8)   //垂直同步信号的脉宽
  38. #define HBPD   (10)   //水平同步信号的后肩
  39. #define HFPD   (19)   //水平同步信号的前肩
  40. #define HSPW   (30)   //水平同步信号的脉宽
  41. #define CLKVAL_TFT  (4)  
  42. #define HOZVAL_TFT (LCD_XSIZE_TFT-1)
  43. #define LINEVAL_TFT (LCD_YSIZE_TFT-1)

  44. #define M5D(n)    ((n) & 0x1fffff) // To get lower 21bits

  45. #undef DEBUG
  46. #define DEBUG
  47. #ifdef DEBUG
  48. #define PRINTK(fmt, args...) printk("debug information: " fmt, ## args)
  49. #else
  50. #define PRINTK(fmt, args...)
  51. #endif

  52. static void *LCD_BUFFER;
  53. static void __iomem *p;

  54. static ssize_t lcd_write (struct file *file, const char __user *buff, size_t count, loff_t *offp)
  55. {
  56. ssize_t ret;
  57. ret = copy_from_user(LCD_BUFFER,buff,count);
  58. if(!ret) printk( KERN_ERR "driver write success!\n");
  59. else
  60. {
  61.   printk( KERN_ERR "write faild bytes = %d",ret);
  62.   return ret;
  63. }
  64. return ret;
  65. }

  66. struct file_operations fops={
  67. .owner = THIS_MODULE,
  68. .write = lcd_write,
  69. };

  70. struct miscdevice misc={
  71. .minor = MISC_DYNAMIC_MINOR,
  72. .name = DEVICE_NAME,
  73. .fops = &fops,
  74. };

  75. static int __init qiao_lcd_init(void)
  76. {
  77. int ret;
  78. p = ioremap(0x4d000000, 0x63);
  79. PRINTK("p = %x \n", p);
  80. LCD_BUFFER = kmalloc(SCR_YSIZE_TFT * SCR_XSIZE_TFT * 2 ,GFP_KERNEL);
  81. PRINTK("LCD_BUFFER = %x \n", LCD_BUFFER);
  82. __raw_writel(0x00000000,S3C2410_GPCUP);
  83. __raw_writel(0xaaaa02a9,S3C2410_GPCCON);
  84. __raw_writel(0x00000000,S3C2410_GPDUP);
  85. __raw_writel(0xaaaaaaaa,S3C2410_GPDCON);

  86. __raw_writel((CLKVAL_TFT<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0,p+S3C2410_LCDCON1);
  87. PRINTK("p+S3C2410_LCDCON1 = %x \n", readl(p+S3C2410_LCDCON1));
  88. __raw_writel((VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW),p+S3C2410_LCDCON2);
  89. __raw_writel((HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD),p+S3C2410_LCDCON3);
  90. __raw_writel((MVAL<<8)|(HSPW),p+S3C2410_LCDCON4);
  91. __raw_writel((1<<11) | (0<<10) | (1<<9) | (1<<8) | (0<<7) | (0<<6) | (1<<3)  |(BSWP<<1) | (HWSWP),p+S3C2410_LCDCON5);
  92. __raw_writel((((unsigned long)LCD_BUFFER>>22)<<21)|M5D((unsigned long)LCD_BUFFER>>1),p+S3C2410_LCDSADDR1);
  93. __raw_writel(M5D( ((unsigned long)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 ),p+S3C2410_LCDSADDR2);
  94. __raw_writel((((SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1),p+S3C2410_LCDSADDR3);
  95. __raw_writel(__raw_readl(p+S3C2410_LCDINTMSK)|(3),p+S3C2410_LCDINTMSK);
  96. __raw_writel(__raw_readl(p+S3C2410_LPCSEL)&(~7),p+S3C2410_LPCSEL);
  97. __raw_writel(0,p+S3C2410_LCDREG(0x50));

  98. __raw_writel(__raw_readl(S3C2410_GPGUP)&(~(1<<4))|(1<<4),S3C2410_GPGUP);
  99. __raw_writel(__raw_readl(S3C2410_GPGCON)&(~(3<<8))|(3<<8),S3C2410_GPGCON);
  100. __raw_writel(__raw_readl(S3C2410_GPGDAT) | (1<<4),S3C2410_GPGDAT);

  101. __raw_writel(__raw_readl(p+S3C2410_LCDCON5)&(~(1<<3))|(1<<3),p+S3C2410_LCDCON5);
  102. __raw_writel(__raw_readl(p+S3C2410_LCDCON5)&(~(1<<5))|(0<<5),p+S3C2410_LCDCON5);

  103. __raw_writel(__raw_readl(p+S3C2410_LCDCON1) | (1),p+S3C2410_LCDCON1);
  104. PRINTK("p+S3C2410_LCDCON1 = %x \n", readl(p+S3C2410_LCDCON1));
  105. PRINTK("p+S3C2410_LCDCON2 = %x \n", readl(p+S3C2410_LCDCON2));
  106. PRINTK("p+S3C2410_LCDCON3 = %x \n", readl(p+S3C2410_LCDCON3));
  107. PRINTK("p+S3C2410_LCDCON4 = %x \n", readl(p+S3C2410_LCDCON4));
  108. PRINTK("p+S3C2410_LCDCON5 = %x \n", readl(p+S3C2410_LCDCON5));
  109. ret = misc_register(&misc);
  110. if(! ret) printk(DEVICE_NAME "initialized\n");
  111. return ret;
  112. }

  113. static void __exit qiao_lcd_exit(void)
  114. {
  115. misc_deregister(&misc);
  116. }

  117. module_init(qiao_lcd_init);
  118. module_exit(qiao_lcd_exit);

  119. MODULE_LICENSE("GPL");
  120. MODULE_AUTHOR("qiao");
  121. MODULE_DESCRIPTION("qiao_lcd_driver");
复制代码

测试程序如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include "meimei.h"
  8. int main()
  9. {
  10. int fd;
  11. long ret;
  12. fd = open("/dev/qiao_lcd", 2);
  13. if (fd < 0)
  14. {
  15. printf("open device qiao_lcd faild");
  16. exit(1);
  17. }

  18. ret = write(fd,&gImage_meimei,sizeof(gImage_meimei));
  19. if(!ret) printf("test successfully!\n");
  20. else
  21. {
  22. printf("bytes filed number is %d",ret);
  23. }
  24. close(fd);
  25. return 0;
  26. }
复制代码




 楼主| 桥~ 发表于 2012-4-22 10:47:47 | 显示全部楼层
解决了~~~
        vi_lcd_buffer = __get_free_pages(GFP_KERNEL ,6);
        //vi_lcd_buffer = kmalloc( LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2,GFP_KERNEL);
返回的还不是硬件的物理地址
要:LCD_BUFFER = virt_to_phys(vi_lcd_buffer);后才是
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2024-6-11 05:40 , Processed in 1.046875 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表