tft lcd with xilinx fpga

F

frozen001

Guest
I am attempting to interface a 4.3" tft LCD with a xilinx fpga. Is there
really comprehensive tutorial on doing this? I am quite new to all of thi
so the more detailed the better.



---------------------------------------
Posted through http://www.FPGARelated.com
 
RTFM is the universal answer for all of this. There may be some tutorials, but they likely won't cover the particular LCD you are using - that said, try Googling. The "M"'s in "RTFM" are the datasheets for the LCD and the FPGA.

Don't get overwhelmed by the size of the datasheets/manuals - odds are that you don't need 90% of what's in them - stick with the basics.

- First start electrically - what does the data sheet for the LCD say is the electrical format of the signals it accepts? (3.3V TTL? LVDS? 1.8V logic? etc.). Then see the FPGA data sheet to see if you can find an IO standard that matches. Hook the two up accordingly.

- Next, write some basic VHDL/verilog/UCF files for the FPGA to instantiate the signals to the LCD in your FPGA and set everything to the appropriate IO standard.

- Then dig into the LCD datasheet again and figure out what commands or data formating it needs and get cracking on a VHDL/verilog state machine or data formatter that accomplishes whatever it is that you want to do with the LCD. Depending on the application it was meant for, most LCDs are either command and buffer based (that is, you write some commands to it, then write to a frame buffer on the LCD controller), or they are video stream based (i..e. no commands necessary, just send raw RGB data continuously).

Hope that helps.

Chris
 
On Jan 25, 8:44 am, Chris Maryan <kmar...@gmail.com> wrote:
RTFM is the universal answer for all of this. There may be some tutorials, but they likely won't cover the particular LCD you are using - that said, try Googling. The "M"'s in "RTFM" are the datasheets for the LCD and the FPGA.

Don't get overwhelmed by the size of the datasheets/manuals - odds are that you don't need 90% of what's in them - stick with the basics.

- First start electrically - what does the data sheet for the LCD say is the electrical format of the signals it accepts? (3.3V TTL? LVDS? 1.8V logic? etc.). Then see the FPGA data sheet to see if you can find an IO standard that matches. Hook the two up accordingly.

- Next, write some basic VHDL/verilog/UCF files for the FPGA to instantiate the signals to the LCD in your FPGA and set everything to the appropriate IO standard.

- Then dig into the LCD datasheet again and figure out what commands or data formating it needs and get cracking on a VHDL/verilog state machine or data formatter that accomplishes whatever it is that you want to do with the LCD. Depending on the application it was meant for, most LCDs are either command and buffer based (that is, you write some commands to it, then write to a frame buffer on the LCD controller), or they are video stream based (i.e. no commands necessary, just send raw RGB data continuously).

Hope that helps.

Chris
OK posting directly here since I kept screwing it up on
FPGARelated.com

I think I have gotten it...well sort of. I found a good VHDL example
for driving a VGA monitor and have modified it to work with the LCD...
I got it working and changing the colors on the screen. I have
modified it further, but I keep getting the following errors now:

Line 32. The type of the element in aggregate does not correspond to
any array type.

Line 44. The type of the element in aggregate does not correspond to
any array type.

Line 32 is:

if (h_counter => "0111100010") and (h_counter <= "1000001011") then

Line 44 is:

if (v_counter => "0100010010") and (v_counter <= "0100011100") then

What am I doing wrong? I am still learning VHDL so bear with me...
 
On Jan 25, 12:39 pm, Lou <lciot...@gmail.com> wrote:
On Jan 25, 8:44 am, Chris Maryan <kmar...@gmail.com> wrote:

RTFM is the universal answer for all of this. There may be some tutorials, but they likely won't cover the particular LCD you are using - that said, try Googling. The "M"'s in "RTFM" are the datasheets for the LCD and the FPGA.

Don't get overwhelmed by the size of the datasheets/manuals - odds are that you don't need 90% of what's in them - stick with the basics.

- First start electrically - what does the data sheet for the LCD say is the electrical format of the signals it accepts? (3.3V TTL? LVDS? 1.8V logic? etc.). Then see the FPGA data sheet to see if you can find an IO standard that matches. Hook the two up accordingly.

- Next, write some basic VHDL/verilog/UCF files for the FPGA to instantiate the signals to the LCD in your FPGA and set everything to the appropriate IO standard.

- Then dig into the LCD datasheet again and figure out what commands or data formating it needs and get cracking on a VHDL/verilog state machine or data formatter that accomplishes whatever it is that you want to do with the LCD. Depending on the application it was meant for, most LCDs are either command and buffer based (that is, you write some commands to it, then write to a frame buffer on the LCD controller), or they are video stream based (i.e. no commands necessary, just send raw RGB data continuously).

Hope that helps.

Chris

OK posting directly here since I kept screwing it up on
FPGARelated.com

I think I have gotten it...well sort of.  I found a good VHDL example
for driving a VGA monitor and have modified it to work with the LCD...
I got it working and changing the colors on the screen.   I have
modified it further, but I keep getting the following errors now:

Line 32. The type of the element in aggregate does not correspond to
any array type.

Line 44. The type of the element in aggregate does not correspond to
any array type.

Line 32 is:

if (h_counter => "0111100010") and (h_counter <= "1000001011") then

Line 44 is:

if (v_counter => "0100010010") and (v_counter <= "0100011100") then

What am I doing wrong? I am still learning VHDL so bear with me...
VHDL does not understand ">=" for vectors - vectors are just a pile of
bits to VHDL - it doesn't know if the left or right bit is the most
significant bit.

You need to convert them to numbers to test for larger or smaller.
There are standard packages to do this.

Try looking here: <http://www.cs.umbc.edu/portal/help/VHDL/
stdpkg.html>

RK
 
On Tue, 25 Jan 2011 13:31:46 -0800 (PST), d_s_klein <d_s_klein@yahoo.com> wrote:

On Jan 25, 12:39 pm, Lou <lciot...@gmail.com> wrote:
On Jan 25, 8:44 am, Chris Maryan <kmar...@gmail.com> wrote:

RTFM is the universal answer for all of this. There may be some tutorials, but they likely won't cover the particular LCD you are using - that said, try Googling. The "M"'s in "RTFM" are the datasheets for the LCD and the FPGA.

Don't get overwhelmed by the size of the datasheets/manuals - odds are that you don't need 90% of what's in them - stick with the basics.

- First start electrically - what does the data sheet for the LCD say is the electrical format of the signals it accepts? (3.3V TTL? LVDS? 1.8V logic? etc.). Then see the FPGA data sheet to see if you can find an IO standard that matches. Hook the two up accordingly.

- Next, write some basic VHDL/verilog/UCF files for the FPGA to instantiate the signals to the LCD in your FPGA and set everything to the appropriate IO standard.

- Then dig into the LCD datasheet again and figure out what commands or data formating it needs and get cracking on a VHDL/verilog state machine or data formatter that accomplishes whatever it is that you want to do with the LCD. Depending on the application it was meant for, most LCDs are either command and buffer based (that is, you write some commands to it, then write to a frame buffer on the LCD controller), or they are video stream based (i.e. no commands necessary, just send raw RGB data continuously).

Hope that helps.

Chris

OK posting directly here since I kept screwing it up on
FPGARelated.com

I think I have gotten it...well sort of.  I found a good VHDL example
for driving a VGA monitor and have modified it to work with the LCD...
I got it working and changing the colors on the screen.   I have
modified it further, but I keep getting the following errors now:

Line 32. The type of the element in aggregate does not correspond to
any array type.

Line 44. The type of the element in aggregate does not correspond to
any array type.

Line 32 is:

if (h_counter => "0111100010") and (h_counter <= "1000001011") then
if h_counter>=482 and h_counter<=523...

Although probably more efficient to generate a latched signal that is set on the values than do a
greater/less than comparison :

if h_counter=482 then window<='1'; elsif h_counter=523 then window<='0'; end if;

>RK
 
I am using the following standard libraries:

use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

I tried going from binary to decimal, and still get the same error....
 
On Jan 26, 8:05 am, Lou <lciot...@gmail.com> wrote:
I am using the following standard libraries:

use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

I tried going from binary to decimal, and still get the same error....
I changed the => to <= and it worked... stupid error...

Of course now I get nothing dispaying again...

Part of my problem is I cannot locate the datasheet for this display.
It is a TFT plug in module from HUINS (www.huins.com). Website does
not contain any datasheets. Tried to e-mail them and got no response.
 
OK. I finally got the display working. WOOO HOOO...

Now my understanding is that to get characters on the display I have
to create a character rom, and a frame buffer. The character rom I
understand. I plan on making a rom that bisically contains 1's where
ever a pixel is on for each character. I plan on a 8x8 font. This
should give me 34 lines with 60 characters.

I am a little confused on the frame buffer portion. Any pointers on
where to look for information on this?
 
On Wed, 26 Jan 2011 12:40:54 -0800 (PST), Lou <lciotti1@gmail.com> wrote:

OK. I finally got the display working. WOOO HOOO...

Now my understanding is that to get characters on the display I have
to create a character rom, and a frame buffer. The character rom I
understand. I plan on making a rom that bisically contains 1's where
ever a pixel is on for each character. I plan on a 8x8 font. This
should give me 34 lines with 60 characters.

I am a little confused on the frame buffer portion. Any pointers on
where to look for information on this?
Your frame buffer holds the character for each display position. Typically using dual port BlockRAM
- a read port feeding data to the display and a write port to update the display contents. Use
initialisation data to put something in it to start with so you can get the display part working
before worrying about the writing to it.

The buffer read address is derived from your X/Y character position counts, and the output goes to
the address input of your character ROM to select the character displayed at each position. The
lower-order addresses of X/Y determine the address within each character definition.
..
 
On Jan 27, 4:18 am, Mike Harrison <m...@whitewing.co.uk> wrote:
On Wed, 26 Jan 2011 12:40:54 -0800 (PST), Lou <lciot...@gmail.com> wrote:
OK.  I finally got the display working.  WOOO HOOO...

Now my understanding is that to get characters on the display I have
to create a character rom, and a frame buffer.  The character rom I
understand.  I plan on making a rom that bisically contains 1's where
ever a pixel is on for each character.  I plan on a 8x8 font.  This
should give me 34 lines with 60 characters.

I am a little confused on the frame buffer portion.  Any pointers on
where to look for information on this?

Your frame buffer holds the character for each display position. Typically using dual port BlockRAM
- a read port feeding data to the display and a write port to update the display contents. Use
initialisation data to put something in it to start with so you can get the display part working
before worrying about the writing to it.

The buffer read address is derived from your X/Y character position counts, and the output goes to
the address input of your character ROM to select the character displayed at each position. The
lower-order addresses of X/Y determine the address within each character definition.
.
Hmmm...I am still lost. All this digital stuff is new to me, and I am
trying to learn this as fast as possible. (BTW I am not a student,
this is just my hobby, if you can call this a hobby... lol, so I am
not looking for homework answers lol... Only been playing with FPGAs
for about 1 month)

So lets see... I dicided to go with a 6x8 font.. that will give me 80
characters across rather than the 60. (Tell me if this complicates
things)

My understanding is that the frame buffer will contain all the data
for each pixel. So with 480x272 TFT, that is a total of 130560 pixels
or bits I have to somehow load into memory.

I have a working block for the Character Rom, basically organized as
an array of std_logic_vector values for each character, accessed by an
address value corresponding to 1 row of pixels (6 bits).

Now to get this into the FrameBuffer, I need the following to somehow
map these rows of pixels to the correct location. I just can't
picture how to store this in RAM, and be easily addressable.
 
Lou <lciotti1@gmail.com> wrote:
(snip)

So lets see... I dicided to go with a 6x8 font.. that will give me 80
characters across rather than the 60. (Tell me if this complicates
things)

My understanding is that the frame buffer will contain all the data
for each pixel. So with 480x272 TFT, that is a total of 130560 pixels
or bits I have to somehow load into memory.
Tradition, going back many years now, is to do the character ROM
lookup on the fly, storing the character codes in RAM. When your
PC starts up it will usually be in a character display mode that
works that way.

I have a working block for the Character Rom, basically organized as
an array of std_logic_vector values for each character, accessed by an
address value corresponding to 1 row of pixels (6 bits).
If you need both characters and graphics on the screen at the same
time, though, it is usual to store the character pixels in display RAM.

Now to get this into the FrameBuffer, I need the following to somehow
map these rows of pixels to the correct location. I just can't
picture how to store this in RAM, and be easily addressable.
-- glen
 
On Thu, 27 Jan 2011 11:57:18 -0800 (PST), Lou <lciotti1@gmail.com> wrote:

On Jan 27, 4:18 am, Mike Harrison <m...@whitewing.co.uk> wrote:
On Wed, 26 Jan 2011 12:40:54 -0800 (PST), Lou <lciot...@gmail.com> wrote:
OK.  I finally got the display working.  WOOO HOOO...

Now my understanding is that to get characters on the display I have
to create a character rom, and a frame buffer.  The character rom I
understand.  I plan on making a rom that bisically contains 1's where
ever a pixel is on for each character.  I plan on a 8x8 font.  This
should give me 34 lines with 60 characters.

I am a little confused on the frame buffer portion.  Any pointers on
where to look for information on this?

Your frame buffer holds the character for each display position. Typically using dual port BlockRAM
- a read port feeding data to the display and a write port to update the display contents. Use
initialisation data to put something in it to start with so you can get the display part working
before worrying about the writing to it.

The buffer read address is derived from your X/Y character position counts, and the output goes to
the address input of your character ROM to select the character displayed at each position. The
lower-order addresses of X/Y determine the address within each character definition.
.

Hmmm...I am still lost. All this digital stuff is new to me, and I am
trying to learn this as fast as possible. (BTW I am not a student,
this is just my hobby, if you can call this a hobby... lol, so I am
not looking for homework answers lol... Only been playing with FPGAs
for about 1 month)

So lets see... I dicided to go with a 6x8 font.. that will give me 80
characters across rather than the 60. (Tell me if this complicates
things)

My understanding is that the frame buffer will contain all the data
for each pixel. So with 480x272 TFT, that is a total of 130560 pixels
or bits I have to somehow load into memory.

I have a working block for the Character Rom, basically organized as
an array of std_logic_vector values for each character, accessed by an
address value corresponding to 1 row of pixels (6 bits).

Now to get this into the FrameBuffer, I need the following to somehow
map these rows of pixels to the correct location. I just can't
picture how to store this in RAM, and be easily addressable.
You need to decide if you just want a text display, or text+graphics. The latter needs much more
buffer RAM, possibly more than you have in the FPGA, so I suggest starting with the former.

For text only, the RAM buffer would be 34x60 bytes. It will make things easier if you round this up
to binary multiples, e.g. 64x64 and have some unused areas.
Similarly if your font data is stored as 8x8 it will simplify addressing, as you can split the
address bus between character number and row/pixel within the character.

Most FPGA Blockram/ROM can be configured as different widths on each port - configuring the output
port as 1 bit wide means it does the pixel serialisation for you.

Assuming your character ROM has 256 8x8 characters, that needs a 256x8x8 x1 bit ROM, which will
have 14 address inputs. These would be allocated as follows

A0..2 : from horizontal counter bits 0..2
A3..5 : from row counter bits 0..2
A6..13 character number from display RAM data out
Data out is your pixel data

Assuming a 64x64 x8 bit character RAM buffer, this has 12 address lines
A0-5 from horizontal counter bits 3..8
A6..11 from row counter bits 3..8

Note this assumes row,column counters start at 0,0 for first pixel - this makes things easier, so
it's worth juggling the sync generation to make it work like that.
Alternatively use seperate counters for addressing and sync generation
 
Thank you for the information.

So this is what I have for the Character ROM (Contains each character
pixel information)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;


entity CharacterRom is
port (clk : in std_logic;
address : in std_logic_vector(10 downto 0);
data: out std_logic_vector (7 downto 0));
end CharacterRom;

architecture Behavioral of CharacterRom is
signal addr_reg: std_logic_vector(10 downto 0);

type rom_type is array (0 to 2047)
of std_logic_vector(7 downto 0);


constant ROM : rom_type := ( X"00", X"00", X"00", X"00",
X"00", X"00", X"00", X"00", -- Char 000

------------------------------------- BIG SNIP
---------------------------------------------------------------------------------------------------------

X"00", X"00",
X"00", X"3C", X"3C", X"3C", X"3C", X"00", -- Char 254
X"00", X"00", X"00", X"00", X"00", X"00", X"00", X"00"); --
Char 255

begin
process (clk)
begin
if (clk'event and clk = '1') then
addr_reg <= address;
end if;
end process;

data <= ROM(to_integer(unsigned(addr_reg)));
end Behavioral;

Am I on the right track?
 

Welcome to EDABoard.com

Sponsor

Back
Top