tiny4412 裸机程序 八、重定位到DRAM及LCD实验【转】
本文轉(zhuǎn)載自:http://blog.csdn.net/eshing/article/details/37407423
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
目錄(?)[+]
一、實(shí)驗(yàn)原理
上一章已經(jīng)解釋的很清楚了,如何將所要運(yùn)行的user_bin程序定位到DRAM中,這一章要進(jìn)行重定位到DRAM后運(yùn)行LCD程序,實(shí)際上一章中BL2中程序可以不用改動(dòng),直接重寫我們的USER目錄下的程序即可,將USER目錄下的LED燈閃爍程序用LCD程序替換就行,最后編譯出的程序名字也叫user_bin.bin即可,這樣也可以用上一章中的fast_fuse.sh進(jìn)行燒寫到SD卡運(yùn)行。
1、LCD控制器
Exynos4412的LCD控制器可以通過編程支持不同LCD屏的要求,例如行和列像素?cái)?shù),數(shù)據(jù)總線寬度,接口時(shí)序和刷新頻率等。LCD控制器的主要作用,是將定位在系統(tǒng)存儲(chǔ)器中的顯示緩沖區(qū)中的LCD圖像數(shù)據(jù)傳送到外部LCD驅(qū)動(dòng)器,并產(chǎn)生必要的控制信號(hào),例如RGB_VSYNC,RGB_HSYNC, RGB_VCLK等。
?
圖8-1、Exynos4412 LCD控制器框圖
(下面的部分來自網(wǎng)絡(luò)翻譯,規(guī)格書中的描述)
如上圖8-1所示,在Exynos4412規(guī)格書中截圖,LCD控制器的構(gòu)成主要由VSFR,VDMA,VPRCS , VTIME和視頻時(shí)鐘產(chǎn)生器幾個(gè)模塊組成:
(1)、VSFR由121個(gè)可編程控制器組,一套gammaLUT寄存器組(包括64個(gè)寄存器),一套i80命令寄存器組(包括12個(gè)寄存器)和5塊256*32調(diào)色板存儲(chǔ)器組成,主要用于對(duì)lcd控制器進(jìn)行配置。
(2)、VDMA是LCD專用的DMA傳輸通道,可以自動(dòng)從系統(tǒng)總線上獲取視頻數(shù)據(jù)傳送到VPRCS,無需CPU干涉。
(3)、VPRCS收到數(shù)據(jù)后組成特定的格式(如16bpp或24bpp),然后通過數(shù)據(jù)接口(RGB_VD, VEN_VD, V656_VD or SYS_VD)傳送到外部LCD屏上。
(4)、VTIME模塊由可編程邏輯組成,負(fù)責(zé)不同lcd驅(qū)動(dòng)器的接口時(shí)序控制需求。VTIME模塊產(chǎn)生?RGB_VSYNC, RGB_HSYNC, RGB_VCLK, RGB_VDEN,VEN_VSYNC等信號(hào)。
Exynos4412的LCD主要特性:
(1)、支持4種接口類型:RGB/i80/ITU601(656)/YTU444
(2)、支持單色、4級(jí)灰度、16級(jí)灰度、256色的調(diào)色板顯示模式
(3)、支持64K和16M色非調(diào)色板顯示模式
(4)、支持多種規(guī)格和分辨率的LCD
(5)、虛擬屏幕最大可達(dá)16MB
(6)、5個(gè)256*32位調(diào)色板內(nèi)存
(7)、支持透明疊加
2、接口信號(hào)
LCD的FIMD顯示控制器全部信號(hào)定義如下表8-1所示
表8-1、LCD接口信號(hào)表
| Signal | I/O | Description | LCD Type |
| LCD_HSYNC | O | 水平同步信號(hào) | RGB I/F |
| LCD_VSYNC | O | 垂直同步信號(hào) | |
| LCD_VDEN | O | 數(shù)據(jù)使能 | |
| LCD_VCLK | O | 視頻時(shí)鐘 | |
| LCD_VD[23:0] | O | LCD像素?cái)?shù)據(jù)輸出 | |
| SYS_OE | O | 輸出使能 | |
| VSYNC_LDI | O | Indirect i80接口,垂直同步信號(hào) | i80 I/F |
| SYS_CS0 | O | Indirect i80接口,片選LCD0 | |
| SYS_CS1 | O | Indirect i80接口,片選LCD1 | |
| SYS_RS | O | Indirect i80接口,寄存器選擇信號(hào) | |
| SYS_WE | O | Indirect i80接口,寫使能信號(hào) | |
| SYS_VD[23:0] | IO | Indirect i80接口,視頻數(shù)據(jù)輸入輸出 | |
| SYS_OE | O | Indirect i80接口,輸出使能信號(hào) | |
| VEN_HSYNC | O | 601接口水平同步信號(hào) | ITU 601/656 I/F |
| VEN_VSYNC | O | 601接口垂直同步信號(hào) | |
| VEN_HREF | O | 601接口數(shù)據(jù)使能 | |
| V601_CLK | O | 601接口數(shù)據(jù)時(shí)鐘 | |
| VEN_DATA[7:0] | O | 601接口YUV422格式數(shù)據(jù)輸出 | |
| V656_DATA[7:0] | O | 656接口YUV422格式數(shù)據(jù)輸出 | |
| V656_CLK | O | 656接口數(shù)據(jù)時(shí)鐘 | |
| VEN_FIELD | O | 601接口域信號(hào) |
其中主要的RGB接口信號(hào):
(1)、LCD_HSYNC:行同步信號(hào),表示一行數(shù)據(jù)的開始,LCD控制器在整個(gè)水平線(整行)數(shù)據(jù)移入LCD驅(qū)動(dòng)器后,插入一個(gè)LCD_HSYNC信號(hào);
(2)、LCD_VSYNC:?幀同步信號(hào),表示一幀數(shù)據(jù)的開始,LCD控制器在一個(gè)完整幀顯示完成后立即插入一個(gè)LCD_VSYNC信號(hào),開始新一幀的顯示;VSYNC信號(hào)出現(xiàn)的頻率表示一秒鐘內(nèi)能顯示多少幀圖像,稱為“顯示器的頻率”
(3)、LCD_VCLK:像素時(shí)鐘信號(hào),表示正在傳輸一個(gè)像素的數(shù)據(jù);
(4)、LCD_VDEN:數(shù)據(jù)使能信號(hào);
(5)、?LCD_VD[23:0]:?LCD像素?cái)?shù)據(jù)輸出端口
3、RGB信號(hào)的時(shí)序
如下圖8-2是LCD的RGB接口工作時(shí)序圖,圖中各時(shí)鐘延時(shí)參數(shù)的含義如下,這些配置可以在所使用的LCD規(guī)格書中查取:
(1)、相關(guān)參數(shù)說明
VBPD(vertical back porch):表示在一幀圖像開始時(shí),垂直同步信號(hào)以后的無效的行數(shù)。
VFBD(vertical front porch):表示在一幀圖像結(jié)束后,垂直同步信號(hào)以前的無效的行數(shù)。VSPW(vertical sync pulse width):表示垂直同步脈沖的寬度,用行數(shù)計(jì)算。
HBPD(horizontal back porch):表示從水平同步信號(hào)開始到一行的有效數(shù)據(jù)開始之間的VCLK的個(gè)數(shù)。
HFPD(horizontal front porth):表示一行的有效數(shù)據(jù)結(jié)束到下一個(gè)水平同步信號(hào)開始之間的VCLK的個(gè)數(shù)。
HSPW(horizontal sync pulse width):表示水平同步信號(hào)的寬度,用VCLK計(jì)算。
(2)、幀的傳輸過程
VSYNC信號(hào)有效時(shí),表示一幀數(shù)據(jù)的開始,信號(hào)寬度為(VSPW +1)個(gè)HSYNC信號(hào)周期,即(VSPW +1)個(gè)無效行;
VSYNC信號(hào)脈沖之后,總共還要經(jīng)過(VBPD+ 1)個(gè)HSYNC信號(hào)周期,有效的行數(shù)據(jù)才出現(xiàn);?所以,在VSYNC信號(hào)有效之后,還要經(jīng)過(VSPW +1? + VBPD + 1)個(gè)無效的行;
隨即發(fā)出(LINEVAL+ 1)行的有效數(shù)據(jù);
最后是(VFPD + 1)個(gè)無效的行。
(3)、行中像素?cái)?shù)據(jù)的傳輸過程
HSYNC信號(hào)有效時(shí),表示一行數(shù)據(jù)的開始,信號(hào)寬度為(HSPW+ 1)個(gè)VCLK信號(hào)周期,即(HSPW +1)個(gè)無效像素;
HSYNC信號(hào)脈沖之后,還要經(jīng)過(HBPD +1)個(gè)VCLK信號(hào)周期,有效的像素?cái)?shù)據(jù)才出現(xiàn);
隨后發(fā)出(HOZVAL+1)個(gè)像素的有效數(shù)據(jù);
最后是(HFPD +1)個(gè)無效的像素。
(4)、將VSYNC、HSYNC、VCLK等信號(hào)的時(shí)間參數(shù)設(shè)置好之后,并將幀內(nèi)存的地址告訴LCD控制器,它即可自動(dòng)地發(fā)起DMA傳輸從幀內(nèi)存中得到圖像數(shù)據(jù),最終在上述信號(hào)的控制下RGB數(shù)據(jù)出現(xiàn)在數(shù)據(jù)總線VD[23:0]上。用戶只需要把要顯示的圖像數(shù)據(jù)寫入幀內(nèi)存中。
其實(shí)現(xiàn)實(shí)的圖像有像素點(diǎn)組成行、行組成場(chǎng)、場(chǎng)組成動(dòng)畫、動(dòng)畫疊加也就是3D的出現(xiàn),也就是我們所說的“點(diǎn)動(dòng)成線、線動(dòng)成面、面動(dòng)成體”。
圖8-2、LCD的RGB工作時(shí)序圖
4、LCD的硬件接口
圖8-3、LCD的部分硬件電路圖
5、16M(24BPP)色的顯示模式
由于我的Tiny4412所用屏幕是S07,是24bit(A888)顯示模式,即用24位的數(shù)據(jù)來表示一個(gè)像素的顏色,每種顏色使用8位。?LCD控制器從內(nèi)存中獲得某個(gè)像素的24為顏色值后,直接通過VD[23:0]數(shù)據(jù)線發(fā)送給LCD;在內(nèi)存中,使用4個(gè)字節(jié)(32位)來表示一個(gè)像素,其中的3個(gè)字節(jié)從高到低分別表示紅、綠、藍(lán),剩余的1個(gè)字節(jié)無效;
以上內(nèi)容是我從以前調(diào)試uboot中LCD顯示查閱到的資料整合,其主要來自于網(wǎng)絡(luò),網(wǎng)絡(luò)上還有各種介紹LCD的相交資料,有興趣的朋友可以自己深究,也可以參考我即將整理的UBOOT相關(guān)文檔。
二、程序說明
下面對(duì)程序進(jìn)行簡(jiǎn)要說明,這時(shí)我只對(duì)USER目錄下的程序?qū)崿F(xiàn)過程進(jìn)行必要說明,其他相關(guān)細(xì)節(jié),請(qǐng)自行對(duì)照手冊(cè)來分析程序,這一章的程序我也進(jìn)行必要的注釋,
首先來看一下Makefile和sdram.lds start.S幾個(gè)文件
1、USER/Makefile sdram.lds start.S
上面三個(gè)程序的說明請(qǐng)參考上一章,其主要作用就是將user_bin.bin中的而start.s鏈接地址設(shè)置為0X43E00000讓程序重定們DRAM中時(shí),就執(zhí)行這個(gè)程序,而start.s唯一做的事就是跳轉(zhuǎn)到main.c中的main函數(shù)執(zhí)行。
2、USER/main.c
Mian函數(shù)很清楚,一開始調(diào)用lcd_init();然后調(diào)用lcd_clear_screen(0x000000)清屏,接著畫一個(gè)十字,再畫了幾條水平線和一條垂直線,最后讓LDE燈一直閃爍。
3、USER/LCD.C
首先需要說明的一點(diǎn)時(shí),這個(gè)程序我參考了網(wǎng)上很多人關(guān)于S5PV210的寫法,但或多或少總存在一些問題,最后在FriendlyARM的BBS的論壇上一個(gè)ID號(hào)為“趙遠(yuǎn)遠(yuǎn)”提供的lcd_chinese_char程序,這個(gè)程序初始化流程可以很好的工作。所以,這個(gè)程序里的初始化部分主要取自于此!
lcd_init()
3.1、寄存器設(shè)置方法
如下面兩句話所示:
#define LCDBLK_CFG (*(volatile unsigned int *)0x10010210)
LCDBLK_CFG = a;
語句中0x10010210是寄存器LCDBLK_CFG的地址,(volatileunsigned int *)0x10010210是將此0x10010210值強(qiáng)制轉(zhuǎn)換成一個(gè)指向unsigned int的指針,volatile作用是防止編譯器優(yōu)化,再在外面加一個(gè)*就是取0x10010210地址處的值了,所以用LCDBLK_CFG就可改寫0x10010210處的數(shù)據(jù),
下面來按著LCD的初始化順序進(jìn)行說明。
3.2、定義IO引腳功能為RGB接口。
由上圖8-3所示,所用的GPIO口分別是GPIO的F口的0/1/2/3四組,查看手冊(cè)可知要想將其設(shè)置為L(zhǎng)CD的RGB接口,只需要將其設(shè)置為2即可。同時(shí)將其IO口設(shè)置成為內(nèi)部上拉,且將其驅(qū)動(dòng)能力設(shè)置為最強(qiáng)代碼如下:
GPF0CON = 0x22222222;????????????????????????????????????
GPF1CON = 0x22222222;
GPF2CON = 0x22222222;
GPF3CON = 0x00222222;
// Set pull-up,down disable
GPF0PUD = 0x0000FFFF;
GPF1PUD = 0x0000FFFF;
GPF2PUD = 0x0000FFFF;
GPF3PUD = 0x00000FFF;
//MAX drive strength---------//
GPF0DRV = 0x0000FFFF;
GPF1DRV = 0x0000FFFF;
GPF2DRV = 0x0000FFFF;
GPF3DRV = 0x00000FFF;
3.3、接著設(shè)置LCD相關(guān)時(shí)鐘寄存器
這一步主要設(shè)置選擇LCD時(shí)鐘輸入源為MPLL,且不對(duì)其進(jìn)行分頻,同時(shí)設(shè)置LCDBLK_CFG使其使用FIMD接口,且設(shè)置LCDBLK_CFG2使其PWM輸出使能,其實(shí),LCDBLK_CFG2可以不用設(shè)置。
3.4、清除Fram Buffer處的數(shù)據(jù)
這里調(diào)用一個(gè)Memset()函數(shù),對(duì)地址0x54000000處,0X200000大小的DRAM進(jìn)行初始化為統(tǒng)一值,一開始我設(shè)置為,后來為了調(diào)試,我將其設(shè)置為0xff00,即可以顯示為綠色。
3.5、設(shè)置VIDCONx,設(shè)置接口類型,時(shí)鐘分頻,極性以及使能LCD控制器等
A、VIDCON0參考數(shù)據(jù)手冊(cè),這一個(gè)寄存器主要設(shè)置接口類型和時(shí)鐘分頻,這里僅僅設(shè)置了其時(shí)鐘分頻值。參考S07的手冊(cè),找到時(shí)像素時(shí)鐘。由于我們的MPLL為800MHZ,所以這里設(shè)置值,根據(jù)手冊(cè)進(jìn)行計(jì)算,要得到33.3MHZ左右的像素時(shí)鐘,所以寄存器第6~13bit設(shè)置為23.其他都保持為0即可。
代碼如下:
VIDCON0 = (23 << 6);
此代碼中也給出了如下代碼風(fēng)格的寫法,后面很多寄存器配置我也均寫好相類似風(fēng)格的代碼,但我要遺憾的說一聲,這種風(fēng)格的寫法且總不能執(zhí)行成功,LCD像是初始化成功,但且不能將圖形給畫出,這在此比對(duì)代碼比對(duì)了很久,也沒有找出原由來,所以這里代碼中可運(yùn)行的部分是受高手唾棄的一種寫作風(fēng)格,同時(shí)也給出了另一種寫作風(fēng)格的代碼,希望細(xì)心的網(wǎng)友能發(fā)現(xiàn)其中那里我設(shè)置有差別,而讓后一種風(fēng)格的代碼能正常運(yùn)行。
// #define EXYNOS_VIDCON0_CLKVAL_F(x)?????????????????????? (((x) & 0xff) << 6)
//VIDCON0 =?EXYNOS_VIDCON0_CLKVAL_F(23);??//not use this method ,it does not work???
B、VIDCON1主要設(shè)置像表時(shí)鐘信號(hào)一直存在,且高電平有效,而IHSYNC=1,極性反轉(zhuǎn)IVSYNC=1,極性反轉(zhuǎn),這是由于S07的時(shí)序圖中VSYNC和HSYNC都是低脈沖有效,而Exynos4412芯片手冊(cè)時(shí)序圖,如上圖8-2所示:VSYNC和HSYNC都是高脈沖有效,所以需要反轉(zhuǎn)。
C、VIDTCONx用來設(shè)置時(shí)序和長(zhǎng)寬等參數(shù),這里就主要設(shè)置VBPD(vertical back porch)、 VFBD(vertical frontporch)、VSPW(vertical sync pulse width)、HBPD(horizontal backporch)、 HFPD(horizontal sync pulse width)等參數(shù),參數(shù)的意義前面已有簡(jiǎn)要說明,這里簡(jiǎn)單用圖片的方式說明如何取值。
如下圖8.4所示是VIDTCON0取值過程,VIDTCON0設(shè)置幀同步時(shí)序。
圖8-4、VIDTCON0寄存器取值參考圖
VBPDE與RGB接口無關(guān),不用關(guān)心,所以其代碼設(shè)置如下:
VIDTCON0 = (22 << 16) | (21 << 8) | (0);
如下圖8.5所示是VIDTCON1取值過程,VIDTCON1設(shè)置像素同步時(shí)序。
圖8-5、VIDTCON1寄存器取值參考圖
VFPDE與RGB接口無關(guān),不用關(guān)心,所以其代碼設(shè)置如下:
VIDTCON1 = (45 << 16) | (209 << 8) | (0);
如下圖8-6所示,為寄存器VIDTCON2設(shè)置取值要點(diǎn):
圖8-6、VIDTCON2寄存器取值參考圖
VIDTCON2 = (479 << 11) | 799;
D、設(shè)置WINCON0寄存器,即設(shè)置數(shù)據(jù)格式。
Exynos4412的LCD控制器有overlay功能,它支持5個(gè)window。這里只使用window0,設(shè)置其代碼RGB模式為24bit(A888)且使能window0,其相關(guān)的代碼設(shè)置如下:
WINCON0 = (11 << 2) | 1;
E、設(shè)置VID0SD0A/B/C,即設(shè)置Window0的坐標(biāo)系。
相關(guān)代碼如下:
VIDOSD0A = 0;
VIDOSD0B = (799 << 11) | 479;
VIDOSD0C = 480 * 800;
F、配置VIDW00ADD0B0和VIDW00ADD1B0,設(shè)置framebuffer的地址;
相關(guān)代碼如下:
VIDW00ADD0B0 = LCD_VIDEO_ADDR;
VIDW00ADD1B0 = LCD_VIDEO_ADDR + VIDOSD0C * 4;
G、配置SHADOWCON和WINCHMAP2、選擇使能DMA通道0。由于我們使用的是Window0,所以需要使能DMA通道0;
相關(guān)代碼如下:
SHADOWCON |= 1;
WINCHMAP2 &= ~(7 << 16);
WINCHMAP2 |= 1 << 16;
WINCHMAP2 &= ~7;
WINCHMAP2 |= 1;
H、最后設(shè)置VIDCON0低兩位使能LCD,代碼如下:
VIDCON0?|= 3;
我們不需要使用很強(qiáng)大的功能,所有只需設(shè)置這幾個(gè)寄存器即可。
lcd_draw_pixel()
經(jīng)過lcd_init()初始化LCD控制器之后,我們就可以在LCD上描繪圖形了,代碼里的所有繪制圖形的函數(shù)都是基于lcd_draw_pixel()這個(gè)函數(shù),它的作用是在LCD上描繪一個(gè)點(diǎn),通過描繪一個(gè)個(gè)的點(diǎn)最終會(huì)可以組成圖形了。在LCD上描點(diǎn)的本質(zhì)就是往Frame Buffer中寫入顏色值而已。LCD控制器自己會(huì)去讀所定義的Frame Buffer內(nèi)存位置處讀取數(shù)據(jù),然后輸出到LCD。
lcd_draw_pixel()這個(gè)函數(shù)以及后面幾個(gè)畫水平線、垂直線和十字的函數(shù)我完成COPY了《Linux平臺(tái)下Mini210S裸機(jī)程序開發(fā)指南》里的代碼,下面我們僅僅COPY說明一下此函數(shù),其代碼如下:
void lcd_draw_pixel(int row, int col, intcolor)
{
unsigned long * pixel = (unsigned long *)LCD_VIDEO_ADDR;
*(pixel + row * COL + col) = color;
}
其中LCD_VIDEO_ADDR = 0x54000000,即framebuffer的基地址,這個(gè)值只要是DRAM中,一塊可分配16M大小的DRAM的一個(gè)地址即可。row和col用來決定偏移,color是顏色值,只要在framebuffer中對(duì)應(yīng)的地址處寫入顏色值就可以在LCD上描繪出該點(diǎn)。
后面其他函數(shù)很簡(jiǎn)單,這里就不費(fèi)時(shí)間做過多說明。
三、完整的燒寫過程
已將SD卡插入電腦,假設(shè)linux識(shí)別了SD卡,其識(shí)別號(hào)為sdb。執(zhí)行下面命令:
# chmod 777 –R 7_sdram_LCD
# cd 7_sdram_LCD
# make
# ./ fast_fuse /dev/sdb
四、上電實(shí)驗(yàn)
將sd卡插入Tiny4412中,選擇sd卡啟動(dòng),和電腦能過串口0連接好,打開一個(gè)串口調(diào)試助手,然后上電,可以看到以下現(xiàn)象:
串口助手中會(huì)顯示一些信息,LCD初始化完成后,LCD屏幕首先會(huì)顯示一整幅的綠色背景。 一兩秒鐘后,會(huì)顯示Mian()函數(shù)中所畫的幾條橫線和一條豎線以及一個(gè)十字,板上的LED燈會(huì)一直閃爍。
前面說過,這一章中留有一點(diǎn)問題,就是兩種寫法,同樣的設(shè)置,為什么第二種代碼風(fēng)格卻不能運(yùn)行,我自己用人眼對(duì)比了好多次,也沒有發(fā)現(xiàn)代碼那里有問題,沒辦法人眼排查,只能試著將串口重新初始化,然后打印出相關(guān)信息,找出原因吧。
總結(jié)
以上是生活随笔為你收集整理的tiny4412 裸机程序 八、重定位到DRAM及LCD实验【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Raft和Paxos简易漫画理解
- 下一篇: overleaf 插入图片_latex中