七、在U-boot中让LCD显示图片

1. 增加Nandflash读取代码

  因为要显示图片,而图片明显是放在Nandflash中比较合适,因此需要有能够操作Nandflash的函数。在U-boot中已经有能操作Nandflash的函数了,但是我找了半天也不知道该怎么调用,因此还是上自己的代码吧。

  1 #define NFCONF *(volatile unsigned int *)0x70200000
  2 #define NFCONT *(volatile unsigned int *)0x70200004
  3 #define NFCMMD *(volatile unsigned char *)0x70200008
  4 #define NFADDR *(volatile unsigned int *)0x7020000c
  5 #define NFDATA *(volatile unsigned char *)0x70200010
  6 #define NFSTAT *(volatile unsigned int *)0x70200028
  7 #define NAND_SECTOR_SIZE 2048
  8 #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
  9 
 10 #define TACLS   7
 11 #define TWRPH0  7
 12 #define TWRPH1  7
 13 
 14 /**
 15  * \brief Nandflash初始化
 16  */
 17 static void __nand_init(void)
 18 {
 19     NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
 20     NFCONT = (1<<4) | (1<<1) | (1);
 21 }
 22 
 23 static void __nand_select(void)
 24 {
 25     NFCONT &= ~(1<<1);
 26 }
 27 
 28 static void __nand_deselect(void)
 29 {
 30     NFCONT |= (1<<1);
 31 }
 32 
 33 static void __nand_cmd(unsigned char cmd)
 34 {
 35     NFCMMD = cmd;
 36 }
 37 
 38 static void __nand_addr (unsigned int addr) 
 39 {
 40     unsigned int col = addr&NAND_BLOCK_MASK;
 41     unsigned int page = addr/NAND_SECTOR_SIZE;
 42 
 43     NFADDR = col & 0xff;
 44     NFADDR = (col>>8) & 0xff;
 45     NFADDR = page & 0xff;
 46     NFADDR = (page >> 8) & 0xff;
 47     NFADDR = (page >> 16) & 0x3;
 48 }
 49 
 50 static void __nand_wait_teady(void)
 51 {
 52     int i;
 53     while (!(NFSTAT & 1))
 54         for (i = 0; i < 10; i++);
 55 }
 56 
 57 static unsigned char __nand_data(void)
 58 {
 59     unsigned char p;
 60     p = NFDATA;
 61     return p;
 62 }
 63 
 64 /**
 65  * \brief 从Nandflash中读取数据至内存中
 66  */
 67 static void __nand_read (unsigned int addr, unsigned char *buf, unsigned int len)
 68 {
 69     int col = addr % 2048;
 70     int i = 0;
 71     __nand_select();
 72     while (i < len) {
 73         __nand_cmd(0);
 74         __nand_addr(addr);
 75         __nand_cmd(0x30);
 76         __nand_wait_teady();
 77 
 78         for (; col < 2048&&(i < len); col++) {
 79             buf[i] = __nand_data();
 80             i++;
 81             addr++;
 82         }
 83         col = 0;
 84     }
 85     __nand_deselect();
 86 }
 87 
 88 static void __nand_reset(void)
 89 {
 90     __nand_select();
 91     __nand_cmd(0xff);
 92     __nand_wait_teady();
 93     __nand_deselect();
 94 }
 95 
 96 /**
 97  * \brief 将Nandflash中的内容读取至内存
 98  */
 99 void nand_copy2ram(unsigned int addr, unsigned char *buff, unsigned int len) 
100 {
101     //__nand_init();
102     __nand_reset();
103     __nand_read(addr, buff, len);
104 }

  注意第101行我把__nand_init注释掉了,因为U-boot起来之后肯定已经对Nandflash初始化过了。

2. 修改LCD代码

  lcd.c

  1 #include "lcd.h"
  2 
  3 static int PEN_COLOR = LCD_RED;     /* 定义画笔(前景)颜色 */
  4 static int BK_COLOR  = LCD_BLACK;   /* 定义背景颜色 */
  5 
  6 /**
  7  * \brief LCD初始化
  8  */
  9 void lcd_init (void)
 10 {
 11     GPICON = 0;
 12     GPICON |= 0xaaaaaaaa;
 13     GPJCON = 0;
 14     GPJCON |= 0xaaaaaa;
 15 
 16     MIFPCON &= ~(0x1<<3);
 17     SPCON &= ~0x3;
 18     SPCON |= 0x1;
 19 
 20     VIDCON0 = (14<<6) | (0x1<<4) | (0x3);
 21     VIDCON1 = (0x1<6) | (0x1<<5);
 22 
 23     VIDTCON0 = (1<<16) | (1<<8) | (9);
 24     VIDTCON1 = (1<<16) | (1<<8) | (40);
 25 
 26     VIDTCON2 = ((LCD_HEIGHT - 1) << 11) | (LCD_WIDTH - 1);
 27     WINCON0 = (0xb<<2) | (0x1);
 28 
 29     VIDOSD0A = 0;
 30     VIDOSD0B = ((LCD_WIDTH - 1) << 11) | ((LCD_HEIGHT - 1));
 31 
 32     VIDOSD0C = LCD_WIDTH * LCD_HEIGHT;
 33 
 34     VIDW00ADD0B0 = SHOW_BUF;
 35 }
 36 
 37 /**
 38  * \brief 设置画笔颜色
 39  */
 40 void lcd_set_pen_color (int color)
 41 {
 42     PEN_COLOR = color;
 43 }
 44 
 45 /**
 46  * \brief 设置背景颜色
 47  */
 48 void lcd_set_bk_color (int color)
 49 {
 50     BK_COLOR = color;
 51 }
 52 
 53 /**
 54  * \brief 绘制一个点
 55  */
 56 void lcd_draw_point (int x, int y)
 57 {
 58     *((int *)SHOW_BUF + x + y * LCD_WIDTH) = PEN_COLOR;
 59 }
 60 
 61 void lcd_draw_bk (int x, int y)
 62 {
 63     *((int *)SHOW_BUF + x + y * LCD_WIDTH) = BK_COLOR;
 64 }
 65 
 66 /**
 67  * \brief 清屏(填充背景色)
 68  */
 69 void lcd_clean (void)
 70 {
 71     int i, j;
 72     for(i=0; i) {
 73         for(j=0; j) {
 74             lcd_draw_bk(j, i);
 75         }
 76     }
 77 }
 78 
 79 /**
 80  * \brief 显示一张BMP图片
 81  */
 82 void lcd_show_bmp (int x , int y , unsigned char *pic)
 83 {
 84     col_t c;
 85     BITMAPFILEHEADER filehead;
 86     BITMAPINFOHEADER infohead;
 87     int i, j;
 88     unsigned char *p = 0;
 89     int width_error = 0;
 90     int old_pen_color;
 91 
 92     memcpy(&filehead , pic, sizeof(filehead));
 93     memcpy(&infohead , pic + sizeof(filehead), sizeof(infohead));
 94 
 95     width_error = (4 - infohead.biWidth * 3 % 4) % 4;
 96 
 97     p = pic + sizeof(filehead) + sizeof(infohead);
 98 
 99     old_pen_color = PEN_COLOR;
100     
101     c.c.non = 0;
102     for (j = infohead.biHeight-1; j>=0; j--) {
103         for (i = 0; i < infohead.biWidth; i++) {
104             c.c.b = *p++;
105             c.c.g = *p++;
106             c.c.r = *p++;
107 
108             PEN_COLOR = c.l;
109             lcd_draw_point(x + i, y + j);
110         }
111         p += width_error;
112     }
113     PEN_COLOR = old_pen_color;
114 }

  lcd.h

  1 #ifndef __LCD_H
  2 #define __LCD_H
  3 
  4 /* 定义寄存器地址 */
  5 #define GPICON  (*(unsigned int *)0x7F008100)
  6 #define SPCON   (*(unsigned int *)0x7F0081A0)
  7 #define MIFPCON (*(unsigned int *)0x7410800c)
  8 #define GPJCON  (*(unsigned int *)0x7F008120)
  9 
 10 #define VIDCON0       (*(unsigned int *)0x77100000) 
 11 #define VIDCON1       (*(unsigned int *)0x77100004) 
 12 #define VIDCON2       (*(unsigned int *)0x77100008) 
 13 #define VIDTCON0      (*(unsigned int *)0x77100010) 
 14 #define VIDTCON1      (*(unsigned int *)0x77100014) 
 15 #define VIDTCON2      (*(unsigned int *)0x77100018) 
 16 #define WINCON0       (*(unsigned int *)0x77100020) 
 17 #define WINCON1       (*(unsigned int *)0x77100024) 
 18 #define WINCON2       (*(unsigned int *)0x77100028) 
 19 #define WINCON3       (*(unsigned int *)0x7710002C) 
 20 #define WINCON4       (*(unsigned int *)0x77100030) 
 21 #define VIDOSD0A      (*(unsigned int *)0x77100040) 
 22 #define VIDOSD0B      (*(unsigned int *)0x77100044) 
 23 #define VIDOSD0C      (*(unsigned int *)0x77100048) 
 24 #define VIDOSD1A      (*(unsigned int *)0x77100050) 
 25 #define VIDOSD1B      (*(unsigned int *)0x77100054) 
 26 #define VIDOSD1C      (*(unsigned int *)0x77100058) 
 27 #define VIDW00ADD0B0  (*(unsigned int *)0x771000A0)
 28 #define GPECON        (*(unsigned int *)0x7f008080)
 29 #define GPEDAT        (*(unsigned int *)0x7f008084)
 30 
 31 #define LCD_WIDTH   480     /* 定义LCD宽度 */
 32 #define LCD_HEIGHT  272     /* 定义LCD高度 */
 33 
 34 /* 定义显存地址 */
 35 #define SHOW_BUF 0x54000000
 36 
 37 /* 定义常用颜色 */
 38 #define COL(R,G,B)   ((R<<16) | (G<<8) | (B))
 39 #define LCD_RED          COL(0xFF, 0, 0)
 40 #define LCD_GREEN     COL(0, 0xFF, 0)
 41 #define LCD_BLUE      COL(0, 0, 0xFF)
 42 #define LCD_WHITE     COL(0xFF, 0xFF, 0xFF)
 43 #define LCD_BLACK     COL(0, 0, 0)
 44 
 45 typedef unsigned short WORD; 
 46 typedef unsigned char BYTE; 
 47 typedef unsigned int DWORD; 
 48 typedef int LONG; 
 49 
 50 #pragma pack(2)
 51 typedef struct tagBITMAPFILEHEADER
 52 {
 53     WORD bfType;            // 位图文件的类型,必须为BM
 54     DWORD bfSize;           // 位图文件的大小,以字节为单位 
 55     WORD bfReserved1;       // 位图文件保留字,必须为0
 56     WORD bfReserved2;       // 位图文件保留字,必须为0
 57     DWORD bfOffBits;        // 位图数据的起始位置,以相对于位图
 58     // 文件头的偏移量表示,以字节为单位
 59 } BITMAPFILEHEADER;
 60 
 61 typedef struct tagBITMAPINFOHEADER
 62 {
 63     DWORD biSize;           // 本结构所占用字节数
 64     LONG biWidth;           // 位图的宽度,以像素为单位
 65     LONG biHeight;          // 位图的高度,以像素为单位
 66     WORD biPlanes;          // 目标设备的级别,必须为1
 67     WORD biBitCount;        // 每个像素所需的位数,必须是1(双色),
 68          // 4(16色),8(256色)或24(真彩色)之一
 69     DWORD biCompression;    // 位图压缩类型,必须是 0(不压缩),
 70         // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
 71     DWORD biSizeImage;      // 位图的大小,以字节为单位
 72     LONG biXPelsPerMeter;   // 位图水平分辨率,每米像素数
 73     LONG biYPelsPerMeter;   // 位图垂直分辨率,每米像素数
 74     DWORD biClrUsed;        // 位图实际使用的颜色表中的颜色数
 75     DWORD biClrImportant;   // 位图显示过程中重要的颜色数
 76 } BITMAPINFOHEADER;
 77 #pragma pack(4)
 78 
 79 struct _rgb_
 80 {
 81     unsigned char b;
 82     unsigned char g;
 83     unsigned char r;
 84     unsigned char non;
 85 };
 86 
 87 typedef union _color_
 88 {
 89     struct _rgb_ c;
 90     unsigned int l;
 91 } col_t;
 92 
 93 /******************************* 函数声明 **************************/
 94 /**
 95  * \brief LCD初始化
 96  */
 97 extern void lcd_init (void);
 98 
 99 /**
100  * \brief 设置画笔颜色
101  */
102 extern void lcd_set_pen_color (int color);
103 
104 /**
105  * \brief 设置背景颜色
106  */
107 extern void lcd_set_bk_color (int color);
108 
109 /**
110  * \brief 绘制一个点
111  */
112 extern void lcd_draw_point (int x, int y);
113 
114 /**
115  * \brief 清屏(填充背景色)
116  */
117 extern void lcd_clean (void);
118 
119 /**
120  * \brief 显示一张BMP图片
121  */
122 extern void lcd_show_bmp (int x , int y , unsigned char *pic);
123 
124 #endif

3. 修改board.c和Makefile

  去掉原先填充纯色的代码,改为显示图片的代码:
七、在U-boot中让LCD显示图片_第1张图片

  nand_copy2ram第一个参数为Nandflash中要读取的地址,在这里我写的是0x100000,因此运行程序前需要保证该地址有我想要的图片;第二个参数为内存地址,需要与保证其他程序不会使用该地址,且与lcd_show_bmp传入的地址相同;第三个参数为拷贝数据大小,一张480*272的24位图大小不会超过400K,这里传入0x80000足够了。

  此外还要修改lib_arm下的Makefile,在COBJS后面加上nand.o后编译。

4. 下载程序

  编译成功后在U-boot中将新编译出的U-boot下载进Nandflash的0地址,将BMP图片下载到0x100000地址。重启开发板,能看到LCD上显示出图片。

  

转载于:https://www.cnblogs.com/Suzkfly/p/10312454.html

你可能感兴趣的:(七、在U-boot中让LCD显示图片)