Discussion:
ubb-vga version 2, first impression
Werner Almesberger
2011-04-27 22:21:59 UTC
Permalink
The original ubb-vga used fancy semiconductors (diodes) to generate the
0.7 V analog color signals. I've now made a simpler version with only
resistors:

Loading Image...

This looks a bit more chaotic that it really has to be, because I've
also been experimenting with some other signals and there are still
some remains of those experiments in evidence, e.g., the 1 kOhm
resistor pointing straight up.

David Kuehling has suggested the use of the Ben's MMC controller to
generate the pixel data. One problem with MMC/SD/SDIO is that these
protocols require handshakes with the device. For example, a block
write looks like this:

1. host sends the command on CMD
2. device sends a reponse on CMD
3. host sends the block on DAT0-DAT3
4. device sends a handshake on DAT0
5. if sending multiple blocks, repeat steps 3 and 4

For further details, see
http://www.jedec.org/sites/default/files/docs/JESD84-A441.pdf
(requires registration but doesn't need a valid e-mail address)

The response has a start bit (0) followed by some data, and then a
stop bit (1). The handshake is pulling DAT0 low while busy.

Since we don't have a real MMC/SD/SDIO device, we need to fake these
responses. I'll leave faking the DAT0 handshake for later. In any
case, we need to fake the command response, or the transfer will
never start.

I found a simple way to do this: add a 330 Ohm pull-down to CMD, use
CMD for HSync, and switch CMD briefly from GPIO to the MMC controller
so that it can see the "response". Luckily, it doesn't try to
interpret the response code.

By aligning the response's start bit with (active-low) HSync pulse,
the whole kludgery is transparent to the VGA monitor.

Here is a first impression of what this looks like:
Loading Image...

The timing is more accurately VGA than what I had before. Note that
the whole display content now fits on the screen and all pixels
have the same width.

The timing also happens to be a bit more fragile in the sense that
the monitor sometimes gets very confused. Not sure yet what causes
this.

- Werner
David Kuehling
2011-04-28 09:42:11 UTC
Permalink
Hi Werner,
Post by Werner Almesberger
http://downloads.qi-hardware.com/people/werner/ubb/vga/ubb-vga2-first.jpg
wow this looks great. What kind of resolution is possible with this
approach? You're still using double-scan (sending every line twice)?
Guess we could use the extra pixels to do some dithing for showing more
colors. Maybe even some temporal dithering, if the flicker is
acceptable?
Post by Werner Almesberger
The timing is more accurately VGA than what I had before. Note that
the whole display content now fits on the screen and all pixels have
the same width.
When running the VGA port, any chance that other software can still
execute in parallel? Maybe we'd need a kernel driver processing an
interrupt once per line or once per frame, then locking the CPU for the
VGA data transfer. How much %CPU would that leave for programs to
consume?

Just speculating how your code could be reused as an mplayer vidix
video-out driver :)

David
--
GnuPG public key: http://user.cs.tu-berlin.de/~dvdkhlng/dk.gpg
Fingerprint: B17A DC95 D293 657B 4205 D016 7DEF 5323 C174 7D40
Werner Almesberger
2011-04-28 14:08:36 UTC
Permalink
Post by David Kuehling
wow this looks great. What kind of resolution is possible with this
approach?
I don't quite know yet. I've tried some higher resolutions but
didn't get stable images.

My old XEN-1510 monitor seems to be happy enough with the 1024x768
vertical timing (1024x768 is that monitor's maximum) but gets
confused with the horizontal timing.

At 800x600, things look better, there's still too much horizontal
flickering going on.

The MMC controller can go up to twice the clock rate I've used for
640x480, so 1024x768 with a similar pixel clock (about 20-30% slow)
might be feasible.

One general problem with the timing is that it's generally very
unstable and there appears to be a memory effect: once I find a
stable timing, it work basically all the time, but if I try some
different timing and then return to the know to be good timing, it
all of a sudden fails and I need to tweak parameters until I
"catch" another good timing.

Or I can just let it rest and it'll work fine on the first try
after I return from a nap.

I'm not sure yet what this is. Possible explanations would be some
aliasing, where some timing is actually far off, but we just happen
to synchronize on some other event that occurs at the right time,
or small timing variations that are modulated on the base timing
and that confuse the monitor's clock synchronization.

The monitor seems to use PLLs to track the signal timing, which
could be susceptible to modulation of their reference clock.

I suspect there's also a something the monitor's firmware remembers
about the signal it found. Maybe there's even a timeout after which
it tries a wider range of possible settings. (Just power cycling
doesn't do the trick.)
Post by David Kuehling
You're still using double-scan (sending every line twice)?
I still had the double-scan it at the beginning, but I now do real
VGA. When converting the Ben's frame buffer, I just put each pixel
four times.
Post by David Kuehling
Guess we could use the extra pixels to do some dithing for showing
more colors.
Yup, that would be possible. Now with the PPM input, one can also
precompute an image at the full VGA resolution and display that. I
should also add a raw mode where the color mapping gets bypassed.
Post by David Kuehling
Maybe even some temporal dithering, if the flicker is
acceptable?
Hmm, you could have multiple frame buffers, yes. Flicker would
depend on what vertical frequency the monitor is willing to accept.
At least at VGA resolution, we could send up to twice the current
pixel clock, so something like "100 Hz" should be possible.
Post by David Kuehling
When running the VGA port, any chance that other software can still
execute in parallel?
That would be nice, wouldn't it ? :-) So far, things don't look too
promising, though. Even turning on the LCD refresh throws off the
timing badly. I also think that I don't have much of a time budget
left in the periods before and after the pixel data, i.e., front and
back porch, and hsync pulse.

If I can get multi-block operations to work, I could use DMA, which
may make things easier. For the hsync pulse, I'd still need a
low-latency timer interrupt plus a delay loop for fine-tuning. (The
total time budget is about 25 us, so the timer would have to be set
to t0 + 25 us - maximum interrupt latency. Then, the driver would
have to busy-loop until the end of the line or the beginning of the
next line.)

Oh, something you could do right now is pre-compute a short video
sequence. One VGA frame is 150 kB, so you should be able to squeeze
at least 2 seconds of video at 50 fps into the Ben's little memory.
More if you pick a lower frame rate and do pixel/line duplication on
the fly.
Post by David Kuehling
Just speculating how your code could be reused as an mplayer vidix
video-out driver :)
Hehe, the Ben home entertainment system ;-) Would also be nice to be
able to run an X server with VGA output on it.

- Werner

Loading...