View Full Version : Starting and stopping video: synchronizing the start to external events.

Phil Pilgrim (PhiPi)
01-21-2009, 06:15 AM
Here's a video gotcha I learned the hard way. I was wanting to start a video output sequence a certain amount of time after an external stimulus. It was also necessary for the video scale (vscl) to vary from event to event (think double-wide characters) but for the start time to remain invariant. In most apps, once the video hardware is started, it just keeps running, and you don't have to worry too much about any startup glitches or which of vcfg or vscl gets loaded first. The system quickly reaches a steady state, and you can just start feeding it pixels.

But I wanted to be able to turn the video on and off at precise times, so what happens at startup was of paramount importance. It seemed reasonable to assume that I could load vscl first with the scale factor I wanted, then load vcfg with the proper configuration data and that the video would start up with the scale factor I had selected. Then, once the video output was done, I could just set vcfg to zero and wait for the next event. I couldn't have been more wrong! The startup delays varied, and I couldn't figure out why.

What I learned and the take-home lesson from this thread is as follows: The video hardware does not load its internal scaling register from vscl when vcfg is initialized. The only time this register is loaded is during the execution of a waitvid. When you turn on the video by setting vcfg, it starts up using the scaling values extant internally, not the value in vscl. What this means is that you have to "prime the pump" with the next vscl value before the last waitvid. The last waitvid can, however, be a dummy. In other words, you can set vcfg to zero immediately following it, thus truncating the video output from it almost instantly.

Here's a program I wrote to illustrate what I'm talking about:


_clkmode = xtal1 + pll8x
_xinfreq = 10_000_000


PUB Start



org 0
synctest mov ctra,ctra0 'Set up ctra for video PLL.
mov frqa,frqa0
mov vscl,vscl0 'Set up video scaling.
mov vcfg,#0 'Disable video output for now.
mov dira,#1

:testlp or outa,#1 'Wide marker.
andn outa,#1
mov vscl,vscl0 'Setup fast video scale.
mov vcfg,vcfg0 'Enable video output.
waitvid colors,pixels 'Output video high.
waitvid colors,#0 'Output video low.
mov vcfg,#0 'Disable video output before low finishes.

or outa,#1 'Narrow marker.
andn outa,#1
mov vscl,vscl1 'Setup slow video scale.
mov vcfg,vcfg0 'Enable video output.
waitvid colors,pixels 'Output video high.
mov vscl,vscl0 '<------------EXTRA VSCL LOAD-------------<
waitvid colors,#0 'Output video low.
mov vcfg,#0 'Turn off video output.

jmp #:testlp 'Loop-d-loop.

ctra0 long %00001 << 26 | (%011 + >| CLKSPERPIXEL) << 23
frqa0 long $16e8_b9fd
vscl0 long CLKSPERPIXEL << 12 | 16 * CLKSPERPIXEL
vscl1 long CLKSPERPIXEL << 13 | 32 * CLKSPERPIXEL
vcfg0 long %01 << 29 | 1 << 28 | %000 << 9 | %0001

colors long $0101_0100
pixels long $ffff_ffff

It generates two video frames, one after each marker pulse: a narrow one, followed by a wide one. When the "extra vscl load" is commented out, this is what the output looks like:


Notice that the start time is one full video frame long, equal in length to the frame before the video was turned off.

Now, with the extra load included, here's the improved output:


Here, the start time is always one full narrow video frame, since this is the scaling written with the extra load. For an even faster startup, one could load vscl at the end of every line of video with an even smaller clocks-per-frame value.



01-21-2009, 10:22 AM
Very cool!

This is something that got in my way a coupla times. Thought it was me actually! Didn't have a scope either :)

Thanks for posting this.

Propeller Wiki: Share the coolness! (http://propeller.wikispaces.com/)
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net (http://propeller.wikispaces.com/Join+us+on+IRC%21/)
Safety Tip: Life is as good as YOU think it is!

Andrew E Mileski
02-13-2009, 06:55 AM
Is the internal frame counter auto-reloading from vscl, rather than counting to 0 and stopping? The internal pixel counter must be auto-reloading from vscl, so it seems logical the frame counter would be implemented similarly. However that would mean that the waitvid instruction doesn't force-load either counter, but just latches the next value to be loaded.

If the internal frame count is not known, like on start-up, waitcnt at least 212 PLL ticks to ensure reaching a 0 count before setting vscl, or of course just waitvid. Waiting on cnt is better when synchronizing multiple cogs. I believe VGA.spin uses the 2-3ms PLL locking time to also accomplish this.

Post Edited (Andrew E Mileski) : 2/13/2009 12:44:56 AM GMT

03-21-2009, 01:24 AM
It's not the WAITVID which latches VSCL/pixel data; the COG is released when the VSCL frame counter expires.

VSCL is really two entities - a COG accessible register, and a pair of PLLA driven counters. And the pixel data is also two entities - a latch loaded by WAITVID and a shifter. When the frame counter rolls over it triggers a load of the VSCL counters from the VSCL register, a load of the pixel data shifter from the latch, and releases the COG if it's halted on WAITVID.

I suspect (but haven't proven) the VSCL counter is free running and not dependent on VCFG. i.e. if you set VCFG[30..29] = %00 VSCL & the pixel shifter will continue to operate. Even if VCFG could be used to halt the VSCL counters, when you re-enabled it you have no way of controlling the phase of PLLA w.r.t. the CPU clock (or the phase of the frame counter for that matter).

(Update) I've now proven VCFG[30..29] = %00 does stop the VSCL counters.

Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114

Post Edited (ericball) : 4/29/2009 6:29:20 PM GMT

Ole Man Earl
04-30-2009, 12:08 AM
I would like to know what o'scope program you are showing data with ...

Phil Pilgrim (PhiPi)
04-30-2009, 12:22 AM
I use a Tektronix TDS3034 oscilloscope that outputs traces in TIFF format to a built-in floppy drive. From there, the files get converted to GIF using Corel PhotoPaint.