Shop OBEX P1 Docs P2 Docs Learn Events
Starting and stopping video: synchronizing the start to external events. — Parallax Forums

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

Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
edited 2009-04-29 17:22 in Propeller 1
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:

[b]CON[/b]

   [b]_clkmode[/b]       = [b]xtal1[/b] + [b]pll8x[/b]
   [b]_xinfreq[/b]       = 10_000_000

   CLKSPERPIXEL   = 1
  

[b]PUB[/b]  Start

  [b]cognew[/b](@synctest,0)

[b]DAT[/b]

              [b]org[/b]       0
synctest      [b]mov[/b]       [b]ctra[/b],[b]ctra[/b]0              'Set up ctra for video PLL.      
              [b]mov[/b]       [b]frqa[/b],[b]frqa[/b]0
              [b]mov[/b]       [b]vscl[/b],[b]vscl[/b]0              'Set up video scaling.
              [b]mov[/b]       [b]vcfg[/b],#0                 'Disable video output for now.
              [b]mov[/b]       [b]dira[/b],#1

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

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

              [b]jmp[/b]       #:testlp                'Loop-d-loop.
                   

[b]ctra[/b]0         [b]long[/b]      %00001 << 26 | (%011 + >| CLKSPERPIXEL) << 23
[b]frqa[/b]0         [b]long[/b]      $16e8_b9fd
[b]vscl[/b]0         [b]long[/b]      CLKSPERPIXEL << 12 | 16 * CLKSPERPIXEL
[b]vscl[/b]1         [b]long[/b]      CLKSPERPIXEL << 13 | 32 * CLKSPERPIXEL
[b]vcfg[/b]0         [b]long[/b]      %01 << 29 | 1 << 28 | %000 << 9 | %0001

colors        [b]long[/b]      $0101_0100
pixels        [b]long[/b]      $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:

········attachment.php?attachmentid=58118

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:

········attachment.php?attachmentid=58119

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.

-Phil

_
640 x 480 - 10K
640 x 480 - 11K

Comments

  • potatoheadpotatohead Posts: 10,261
    edited 2009-01-21 03:22
    Very cool!

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

    Thanks for posting this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
    Safety Tip: Life is as good as YOU think it is!
  • Andrew E MileskiAndrew E Mileski Posts: 77
    edited 2009-02-12 23:55
    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
  • ericballericball Posts: 774
    edited 2009-03-20 18:24
    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[noparse][[/noparse]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[noparse][[/noparse]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 EarlOle Man Earl Posts: 262
    edited 2009-04-29 17:08
    I would like to know what o'scope program you are showing data with ...
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-04-29 17:22
    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.

    -Phil
Sign In or Register to comment.