mbed Component-less VGA
Well, ok, it's got three resistors.
Updates
Date Update
========= ==================================================================
29-Oct-07 Now uses PWM for H and V sync generation for true 31.48kHz x 60Hz
Now providing 128x128 pixels from 8kB using RGB per nibble
Now utilising approximately 384x384 pixels of VGA 640x480
Now remaining in interrupt context for entire of visible region
Still have issues with heavy thread activity causing wobbliness
30-Oct-07 This looks useful http://www.xfree86.org/3.3.6/Config7.html
6-Nov-07 Hurrah! Full VGA text mode has been achieved; 720x400 pixels
producing 80x25 characters of 9x16 pixels. It may be in
monochrome, but mbed is achieving 30 million pixels per
second!
What Does it Do?
Drives a standard monitor using GPIO by emulating a 640x480 VGA signal.
The Circuit
MBED-DIP64 Pin VGA D-15 Pin
1 / GND ------------> 4, 5, 6, 7, 8, 10, 11 / Signal, sync and shield grounds
10 / GPIO 0.16 ------------> 14 / Vertical-Sync
8 / GPIO 0.17 ------------> 13 / Horizontal-Sync
____
7 / GPIO 0.18 ---|____|---> 1 / Red-Signal via 240R
____
6 / GPIO 0.19 ---|____|---> 2 / Green-Signal via 240R
____
5 / GPIO 0.20 ---|____|---> 3 / Blue-Signal via 240R
240 ohm resistors chosen on the basis that full brightness signal is meant to be about 0.7v into 75ohm and IO is approximately 3.3v; thus (3.3v / (75R + 240R)) * 75R = 0.78v; hope the IO can sustain 10mA :-) Sync signals are meant to be 5v, but straight 3.3v appears to work fine.
The Strategy
Hammer the IO as fast as possible and hope everything works out ok (after all, we're only trying to emulate having a 25MHz pixel clock - how hard can it be? :-)
Use interrupts and timers to try and get reasonably clean sync signals and to stop everything wobbling too much.
The Reality
Well, on a good day we might manage a 7.5MHz pixel clock and 100ns of jitter :-)
Does it Work?
Oh yes; see it running
Hex counter is frames rendered so far; decimal counter is frames/60, i.e. wall-clock seconds. One coloured square is being rendered per frame, though there are sufficient spare cycles to render many-many more, though 7's LDM/STM behaviour means that sync jitter becomes a serious issue if you do :-)
Circuit constructed board-less using six IDC patch leads connected to three resistors and four resistor-legs soldered to a 15-pin plug; all strategically bent to reduce the chance of too many shorts.
Current Specs
MBED running with 60MHz core clock, 48MHz USB (rather irrelevant), and 15MHz IO / peripherals.
96 x 96 pixels with 3-bpp colour (that'll be black, red, green, blue, cyan, yellow, magenta and white, but unfortunately no traditional flashing colours); fully frame-buffered in 9kB of precious RAM for drawing at ones leisure.
Rather stuck to the left hand side of the screen (the right side of the screen is currently consumed by exiting the VGA interrupt service routine and getting back in again -- to be fixed with the potential to upgrade to maybe 200 pixels across the screen!).
Semi-nasty piece of code for blitting lines generated via some macro language in the embedded assembler.
What's Next?
The Graphical Route
Increase resolution via:
- Packing multiple pixels per byte
- Using USB and ethernet RAM for heap/stack freeing up fast RAM for a bigger framebuffer
- Staying in interrupt routine from top to bottom of visible screen (don't exit at end of each scanline)
- May be speed blit by copying blit code to RAM (unlikely to make any difference)
The Textual Route
Emulate SAA5050, and in doing so artifitially increase the resolution. Bring back Teletext and Viewdata!
Has the added advantage of only requiring 1kB of RAM for framebuffer.
Alternatively emulate a Wyse terminal.
6/Nov/2007 - Ok, after trawling the user guide for an appropriate victim, the I2S has been seriously knobbled to produce full VGA text mode (albeit in monochrome);
The Purist Route
Ditch the assembly and find the C-function that produces the same results :-)
Goals
Maybe a canned "VGA SAA5050" or "VGA display" C++ object.
enjoy!
Simon.
