Video timing; New discoveries, improved synchronisation code.
Hi!
I've been venturing into the murky depths of video generator timing, and discovered some new glitches and previously undocumented behaviour. The upshot is that I managed to write a 100% reliable PLL synchronisation routine. (The technique used in Chip Gracey's multi-cog video drivers is 99.94% reliable.)
Here's the code, and all the juicy details:
http://www.linusakesson.net/programming/propeller/pllsync.php
I've been venturing into the murky depths of video generator timing, and discovered some new glitches and previously undocumented behaviour. The upshot is that I managed to write a 100% reliable PLL synchronisation routine. (The technique used in Chip Gracey's multi-cog video drivers is 99.94% reliable.)
Here's the code, and all the juicy details:
http://www.linusakesson.net/programming/propeller/pllsync.php
Comments
I have a driver for 3-cog 6-bit color photos on VGA that I could never get the pixels exactly on top of each other with...
Maybe your ideas will help with that...
Awesome writeup! It really explained a number of things!
Great Job!
KK
OBC
Ross.
Linus, what else can plasma do? Share library routines? other?
Yes, I've got some code that doesn't work too. Can't wait to bang on this.
Thanks Linus!
Re: jazzed- Linus created a Propeller assembler called "plasma"
plasma Info Here:
http://www.linusakesson.net/software/plasma/index.php
The power of having two PLLs interleave the pixels on different cogs is awesome - better pictures, high resolutions, more colors.
' Synchronise cog PLLs. Here there be dragons. ' http://www.linusakesson.net/programming/propeller/pllsync.php waitcnt sync_cnt, =$30000 ' 3 ms mov VCFG, =%0_01_0_00_000_00000000000_010_0_11111111 movi FRQA, #$10000000 >> 23 mov VSCL, #1 ' Reload on every pixel movi CTRA, #%0_00001_111_00000000_000000_000_000000 >> 23 waitcnt sync_cnt, #0 ' Wait for PLL to settle mov VSCL, #65 ' Any power of two, plus one ' The next instruction must not be a waitvid, and should ' probably not be an assignment to VSCL either.
Some idle thoughts. To be fair, as far as video related programming is concerned I guess I can let the name PLL sync pass (5 out of 8 isn't bad). OTOH it simply doesn't work for clock dividers 32, 64 and 128 (only the NCO feeding the PLL is in fact sync'd). Not too serious really.The other thing I don't quite get is the reload on every pixel. That's like self-inflicted damage and then complaining that it doesn't work properly. And changing only a single bit doesn't help. If you step back for a moment and look at it you'll realise that you change a register value the moment it's sampled. Single bit change or not you'll have a ~50% chance that it catches up one cycle later (than the other cog(s)). I checked and this'll happen more often than you think. Which may be OK for a particular use case but can (and should) be avoided.
DAT org 0 entry rdlong delay, #0 ' clkfreq shr delay, #10 ' ~1ms (%%) rdlong cref, par ' initial sync target waitcnt cref, delay ' sync cogs movi ctra, #%0_00001_111 ' PLL, VCO/1 movi frqa, #%0001_00000 ' 5MHz * 16 / 1 = 80MHz mov vscl, #vref ' 32 rather than the default 4K movd vcfg, #2 ' pin group movs vcfg, #%0_11111111 ' pins movi vcfg, #%0_01_0_00_000 ' VGA, 32 pixels [COLOR="blue"]waitcnt cref, #vref*3[/COLOR] ' PLL settled (%%) [COLOR="red"]waitvid zero, #0[/COLOR] ' dummy to play it safe [COLOR="red"]waitvid zero, #0[/COLOR] [COLOR="red"]sub cref, cnt[/COLOR] [COLOR="red"]mov vscl, cref[/COLOR] ' transfer adjustment [COLOR="red"]waitvid zero, #0[/COLOR] ' latch adjustment [COLOR="red"]mov vscl, #user[/COLOR] ' transfer user value [COLOR="red"]waitvid zero, #0[/COLOR] ' latch user value ...
waitvid zero, #0 ' [COLOR="red"]dummy to play it safe[/COLOR] waitvid zero, #0 ...
Admittedly this comment makes it sound like you could get away without it. Wrong. Reason being that there are 4 cycle waitvids and 4 cycle waitvids. The former is your ordinary/official (and useless) 4 cycle version. The latter - also useless - happens during frame stretches where a minimal waitvid is pushed back by one cycle and makes the frame look longer. However, the next hand-off stays locked to the grid (vscl[11..0]*n) which means it happens one cycle earlier in reference to the waitvid which would throw off all timing. Anyway, I just thought I should share this (after finding out the hard way).The solution listed suffers from jitter (frqa <> po2) given the right circumstances. A more solid version is listed in my [thread=126874]waitvid thread[/thread] (20110409 update).