(原創) 如何控制TRDB-LTM輸出時某座標的顏色? (SOC) (DE2-70) (TRDB-LTM)
Abstract
很多人問到如何在TRDB-LTM控制某xy座標輸出的顏色,本文提出解決方法。
Introduction
使用環境:Quartus II 8.1 + Nios II EDS 8.1 + DE2-70 (Cyclone II EP2C70F896C6N) + TRDB-D5M + TRDB-LCM
小美與阿帥從DE2轉移到DE2-70後,一些原來DE2會發生的問題,在DE2-70也是會遇到。在DE2,大家都習慣用VGA輸出,不過既然有了DE2-70 + TRDB-D5M + TRDB-LTM這種三合一套件後,就不用再多找一個螢幕當VGA輸出了,直接用TRDB-LTM輸出即可。
『小美,你知道如何控制TRDB-LTM輸出時某座標的顏色嗎?』
『無雙學長在(原創) 如何控制DE2 VGA輸出時某座標的顏色? (IC Design) (DE2) (Quartus II)與(原創) 如何產生VGA的Color Pattern Generator? (SOC) (Verilog) (DE2) (DE2-70)兩篇曾經提過,TRDB-LTM應該也可以用這種方是去控制吧!!』
『理論上是這樣沒錯,就是加上coord_x與coord_y兩個register得到x,y座標就可以控制了,但就是改不出來啊~~~』阿帥花了很多天去改,但還是改不出來。
『一起去請教無雙學長好了....』
無雙學長最近比較忙,常常找不到人,連blog都很少更新了,小美與阿帥好不容易才找到無雙學長。
『很多人email問過我這個問題,我直覺以為應該與控制VGA類似,所以就沒再深入研究,今天連你們兩個也改不出來,看來TRDB-LTM與VGA應該有些差異,我就來改看看好了。』無雙學長最後還是決定親自下手。
touch_tcon.v / Verilog
2 input iCLK, // LCD display clock
3 input iRST_n, // systen reset
4 // SDRAM SIDE
5 input [15:0] iREAD_DATA1, // R and G color data form sdram
6 input [15:0] iREAD_DATA2, // B color data form sdram
7 output oREAD_SDRAM_EN, // read sdram data control signal
8 //LCD SIDE
9 output reg oHD, // LCD Horizontal sync
10 output reg oVD, // LCD Vertical sync
11 output reg oDEN, // LCD Data Enable
12 output reg [7:0] oLCD_R, // LCD Red color data
13 output reg [7:0] oLCD_G, // LCD Green color data
14 output reg [7:0] oLCD_B // LCD Blue color data
15 );
16
17 parameter H_LINE = 1056;
18 parameter V_LINE = 525;
19 parameter Hsync_Blank = 216;
20 parameter Hsync_Front_Porch = 40;
21 parameter Vertical_Back_Porch = 35;
22 parameter Vertical_Front_Porch = 10;
23
24 reg [10:0] x_cnt;
25 reg [9:0] y_cnt;
26 wire [7:0] read_red;
27 wire [7:0] read_green;
28 wire [7:0] read_blue;
29 wire display_area;
30 reg mhd;
31 reg mvd;
32 reg mden;
33
34 // This signal control reading data form SDRAM , if high read color data form sdram .
35 assign oREAD_SDRAM_EN = ( (x_cnt>Hsync_Blank-2)&&
36 (x_cnt<(H_LINE-Hsync_Front_Porch-1))&&
37 (y_cnt>(Vertical_Back_Porch-1))&&
38 (y_cnt<(V_LINE - Vertical_Front_Porch))
39 )? 1'b1 : 1'b0;
40
41 // This signal indicate the lcd display area .
42 assign display_area = ((x_cnt>(Hsync_Blank-1)&& //>215
43 (x_cnt<(H_LINE-Hsync_Front_Porch))&& //< 1016
44 (y_cnt>(Vertical_Back_Porch-1))&&
45 (y_cnt<(V_LINE - Vertical_Front_Porch))
46 )) ? 1'b1 : 1'b0;
47
48 assign read_red = display_area ? iREAD_DATA2[9:2] : 8'b0;
49 assign read_green = display_area ? {iREAD_DATA1[14:10],iREAD_DATA2[14:12]}: 8'b0;
50 assign read_blue = display_area ? iREAD_DATA1[9:2] : 8'b0;
51
52 ///////////////////////// x y counter and lcd hd generator //////////////////
53 always@(posedge iCLK or negedge iRST_n) begin
54 if (!iRST_n) begin
55 x_cnt <= 11'd0;
56 mhd <= 1'd0;
57 end
58 else if (x_cnt == (H_LINE-1)) begin
59 x_cnt <= 11'd0;
60 mhd <= 1'd0;
61 end
62 else begin
63 x_cnt <= x_cnt + 11'd1;
64 mhd <= 1'd1;
65 end
66 end
67
68 always@(posedge iCLK or negedge iRST_n) begin
69 if (!iRST_n)
70 y_cnt <= 10'd0;
71 else if (x_cnt == (H_LINE-1)) begin
72 if (y_cnt == (V_LINE-1))
73 y_cnt <= 10'd0;
74 else
75 y_cnt <= y_cnt + 10'd1;
76 end
77 end
78
79 ////////////////////////////// touch panel timing //////////////////
80 always@(posedge iCLK or negedge iRST_n) begin
81 if (!iRST_n)
82 mvd <= 1'b1;
83 else if (y_cnt == 10'd0)
84 mvd <= 1'b0;
85 else
86 mvd <= 1'b1;
87 end
88
89 always@(posedge iCLK or negedge iRST_n) begin
90 if (!iRST_n)
91 mden <= 1'b0;
92 else if (display_area)
93 mden <= 1'b1;
94 else
95 mden <= 1'b0;
96 end
97
98 always@(posedge iCLK or negedge iRST_n) begin
99 if (!iRST_n) begin
100 oHD <= 1'd0;
101 oVD <= 1'd0;
102 oDEN <= 1'd0;
103 oLCD_R <= 8'd0;
104 oLCD_G <= 8'd0;
105 oLCD_B <= 8'd0;
106 end
107 else begin
108 oHD <= mhd;
109 oVD <= mvd;
110 oDEN <= mden;
111
112 if (coord_x > 200 && coord_x < 320 &&
113 coord_y > 200 && coord_y < 240) begin
114 oLCD_R = 10'h000;
115 oLCD_G = 10'h000;
116 oLCD_B = 10'h000;
117 end
118 else begin
119 oLCD_R <= read_red;
120 oLCD_G <= read_green;
121 oLCD_B <= read_blue;
122 end
123 end
124 end
125
126 reg [9:0] coord_x;
127 reg [9:0] coord_y;
128
129 always@(posedge iCLK or negedge iRST_n) begin
130 if (!iRST_n) begin
131 coord_x <= 0;
132 coord_y <= 0;
133 end
134 else begin
135 if (display_area) begin
136 coord_x <= x_cnt - (Hsync_Blank-1);
137 coord_y <= y_cnt - (Vertical_Back_Porch-1);
138 end
139 end
140 end
141
142 endmodule
『重點是要能先產生x、y座標的reg,129行到144行就是在產生x、y座標。』
reg [9:0] coord_y;
always@(posedge iCLK or negedge iRST_n) begin
if (!iRST_n) begin
coord_x <= 0;
coord_y <= 0;
end
else begin
if (display_area) begin
coord_x <= x_cnt - (Hsync_Blank-1);
coord_y <= y_cnt - (Vertical_Back_Porch-1);
end
end
end
『看起來與VGA的改法不一樣耶,為什麼要這樣改呢?』用功的小美馬上看出兩者個差異。
『對,但原理是一樣的,根據DE2-70 CD的TRDB_LTM UserGuide,只有在Valid Data區才會顯示影像,首先必須判斷出哪些是valid data區,才能再求出x、y座標。』
『41行的display_area就是判斷是否在x_cnt與y_cnt是否在display區。』
assign display_area = ((x_cnt>(Hsync_Blank-1)&& //>215
(x_cnt<(H_LINE-Hsync_Front_Porch))&& //< 1016
(y_cnt>(Vertical_Back_Porch-1))&&
(y_cnt<(V_LINE - Vertical_Front_Porch))
)) ? 1'b1 : 1'b0;
『然後x_cnt必須減掉thbp,也就是Hync back porch,y_cnt必須減掉tvbp,也就是vertical back porch後,才是真正的x、y座標。』
『為什麼Hsync_Blank與Vertical_Back_Porch還要減掉1呢?』細心的小美馬上發現這個小問題。
『小美真是細心!!』無雙學長不禁誇耀起小美。『注意到thpw與tvpw嗎?這在VGA就是H-sync width與V-sync width,在TRDB-LTM很有趣,只有1而以,所以必須減1。』
『x、y座標出來後,接下來就簡單了,只要依你的需求去控制RGB顯示即可,112行到122行,依舊如VGA的範例一樣,控制顯示一個方形』
coord_y > 200 && coord_y < 240) begin
oLCD_R = 10'h000;
oLCD_G = 10'h000;
oLCD_B = 10'h000;
end
else begin
oLCD_R <= read_red;
oLCD_G <= read_green;
oLCD_B <= read_blue;
end
執行結果
『沒想到VGA與TRDB-D5M還是有些差異,不能將VGA的code直接貼過來就好。』阿帥恍然大悟。
『這當然了,blog上的資料是希望大家舉一反三,確實了解code的原理之後,自己能改到其他的周邊上,畢竟在實務裡,一個嵌入式系統常常因為需求不同而替換不同的周邊,如現在就有很多同學用的就是TRDB-D5M + DE2 + TRDB-LTM,而不是DE2-70,只要原理了解,一樣能套用在DE2上。』無雙學長最後作了以上的結論。
完整程式碼下載
DE2_70_D5M_LTM_xy.7z
See Also
(原創) 如何控制DE2 VGA輸出時某座標的顏色? (IC Design) (DE2) (Quartus II)
(原創) 如何產生VGA的Color Pattern Generator? (SOC) (Verilog) (DE2) (DE2-70)