Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to generate VGA signal with micro-controller (like TI Tiva ARM which runs at 90/120Mhz speed).

I'm not sure how to make accurate timings with micro-controller. Which programming pattern I need to use?

Do I need any inline assembler code? How to wisely use interrupts?

Would be great if anybody show some pseudo code how to generate VGA signal.

I successfully generated VGA signal with FPGA. But I just can't figure out how to do it with MCU.

share|improve this question
    
There are VGA libraries for AVR. Different microcontroller, but you might get some inspiration from it. You might be able to utilize the DMA controller to offload the main CPU, because generating a video signal is pretty CPU intensive without these sort of tricks. – jippie yesterday
up vote 8 down vote accepted

This answer is all based on standard VGA screens, which are 640 x 480 since that was what you referenced in your answer. Timing for SVGA (super VGA, 800 x 600), XGA (1024 x 768) and so on is going to be different. This page has a good list of virtually all the resolutions in use. But the pixel timing for these bigger screens is going to be so fast I doubt you could generate it using a micro.

VGA Timing

So the standard VGA screen is 640 pixels horizontally and 480 lines vertically. To generate the timing, a 25.175 MHz pixel clock is used. (Theoretically, this means the micro would need to be able generate pulses that are exactly 39.72 ns long, which would be rather difficult, but it seems you can get by with 25 MHz and 40 ns clocks.

The format of VGA timing for each line dates back to CRT computer screens days and before that television sets. It looks like this for a 640x480 picture (just the horizontal shown here):

enter image description here

There are two synchronization pulses -- one per line (horizontal sync) and one per frame (vertical sync). The horizontal sync pulse is preceded by a "back porch interval, and followed by a "front porch" interval. In between these two is the active video (640 pixels). The total line though is 800 pixels wide.

Likewise, the vertical lines have a sync pulse at the bottom, surrounded by a vertical back porch and front porch and is 524 pixels high.

enter image description here

Back when video was done using CRT's instead of LCD screens, there was an electron beam that scanned across the screen for each line, which then moved down a bit, scanned the next line etc. At the bottom of the screen, it had to zip back to the top.

At the end of each line, the beam has to move back to the beginning of the next line -- this takes a little time. During this time the video was blanked. This is known as the horizontal refresh time, and is the sum of the back porch+sync+front porch timing. Likewise for the vertical refresh period. That's why there is a total of 800 pixels across the screen, and 524 lines vertically, even though you only see 640x480.

The timing then can be specified in terms of clock pulses:

enter image description here

where HPX are the 640 pixels, HFP is the horizontal back porch interval, HSP is the horizontal sync pulse, HBP is the horizontal back porch interval. Likewise for the vertical. This what you need to use for your timing in the microcontroller (assuming you have a 40 ns clock).

So each full line is 800 clocks, or 800 x 40 ns = 32 µs.

Note that the critical timing only occurs when writing pixels to the screen (12 bits every 40 ns). While writing out the pixels you're not going to have much time to do anything else. But during the front porch, sync pulse, and back porch you've got 635 ns, 3.81 µs, and 1.9 µs respectively for doing other stuff.

Note that if you don't have a processor fast enough to generate 40 ns pixels, you can divide everything in half (essentially running at 12.5 MHz, or a 80 ns clock) and you will have 320 x 240 resolution. So each pixel is repeated twice as far as the monitor is concerned. It still thinks you're sending VGA.

VGA Output

To generate the video signals for each pixel, you can make your own DAC (digital to analog converter) using resistors. If you allocate 4 bits per color (RGB) you will need 12 resistors in total, arranged so:

enter image description here

You could get by with less bits, for example 3 bits per color, or even 2, but the picture quality won't be as good.

Firmware

Assume we have a 100 MHz 32-bit processor (10 ns per instruction). Also assume we are using 12 bit pixels, stored two pixels to a 32-bit word (so we waste 8 bits unfortunately).

Before starting, assume r0 is loaded with the address of the starting 32-bit word containing pixels for this line, and r1 is loaded with address of a memory mapped I/O port, of which the lower 12 bits D0-D11 are brought out, and r2 is a temporary holding two pixels.

I'm using a made-up RISC-like instruction set, but it should be pretty obvious what is going on.

ld r2,[r0]      ; load indirect through register r0, 32 bits (2 pixels)
andi r2,0x3FF   ; and immediate, get lower 12 bits (not strictly necessary,
                ;   if the upper 16 bits of the port aren't being used) 
st r2,[r1]      ; store pixel to I/O port
nop             ; fill out remainder of 40 ns
rsh r2,16       ; right shift 16 bits to get upper pixel
addi r0,4       ; increment memory address (assume byte addressing)
st r2,[r1]      ; store pixel to I/O port
nop             ; fill out remainder of 40 ns

So we have to add a nop every three instructions to keep the timing right. That implies we could get by with a processor running at 76 MHz, which results in a 13.15 ns instruction time; so three instructions comes to 39.47 ns, which is as close to the ideal 39.7 ns as 40 ns is. One could achieve 76 MHz using a 19 MHz crystal and a 4x PLL if the micro has that capability. (Actually there are 18.9375 MHz crystals, 4x is 75.75 MHz, or 13.2 ns/instruction, times 3 is 39.6 ns, only 100 picoseconds off the correct VGA timing.)

So you repeat this sequence of eight (or six) instructions 320 times inline. At the end, set up an interrupt for 635 ns in the future (end of back porch) and return from the interrupt level (entered when you started sending you pixels) In the meantime you've got 63 instructions free for the base level.

At the interrupt (end of back porch), generate the beginning of the horizontal sync pulse (goes low) and set another interrupt this time 3.81 µs in the future (end of horizontal sync) and exit from the interrupt. You can execute about 380 instructions this time.

At the interrupt (end of horizontal sync), complete the horizontal sync (goes back high), set an interrupt for 1.9 µs in the future (end of front porch) and return from the interrupt. 190 or so more instructions available.

At the final interrupt (end of front porch), start outputting pixel data again (all in the interrupt routine).

Similar code to handle the end of the frame (vertical sync etc.).

share|improve this answer
    
Actually very helpful information. But can give more details about software side. I need timer with 25 Mhz frequency ? Thanks – kesrut yesterday
    
@kesrut Yes. You're going to need a very fast processor. A 200 MHz processor would be 5 ns per instruction (assuming one cycle/instruction), or 8 instructions per pixel clock. Not a lot of time. Note the multi-core Parallax Propeller has special timers so it can generate VGA output in one core, while you have 7 more cores for other stuff. You might want to consider that as a co-processor. Here's a demo and another. – tcrosley yesterday
    
@kesrut Actually a 100 MHz (or even 76 MHz) processor will do; see the update to my answer. – tcrosley yesterday
1  
People have done it with overclocked atmel microcontrollers: tinyvga.com/avr-vga – pjc50 yesterday
    
Theres no way you are going to do this with a timer, you are into the realm of writing cycle-counted assembler and your processor will spend most of it's time working on updating the screen. You can have your processor go and do other things during the parts of the display waveform where nothing is on screen and/or parts of the display where there is a large section of solid color. – Peter Green yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.