Nikolai Golovchenko says:
Sync detection is sure possible with a SX. I made a quick test on the evaluation board (50 MHz SX28), just for horizontal sync, using the comparator to catch the sync pulses. It works in most cases, but sometimes, when video is bad quality (noisy, but screen is stable) lines are missed with that setup.There are a few problems:
1) Comparator lowest input voltage level is 0.4V. With a 0 to 1V video, sync threshold is at about 0.15V. So it is out of specs, though seems to be working.
2) Noise. I wonder how screen remains stable even when signal is noisy. There must be some filtering in a TV. I'll try to dig the sync separator circuit from an old TV.
3) SX counts the pulse width in a loop like:
. . . measure_ov2 mov w, #5 mov dx, w measure3 mov w, #128-100 mov RTCC, w mov w, #compMode measure3a mov !RB, w mov temp, w snb temp.0 jmp measure_ok sb RTCC.7 ;or any other reg my be used for ;counting jmp measure3a decsz dx jmp measure3 ;too long - repeat pulse catch jmp wait_1 . . .The inner loop takes 8 cycles (without comparator that would be 6 cycles). So the comparator is sampled every 8 cycles, and maximum jitter in sync detection is 8 cycles. That can be visible if SX frequency is too low. Probably, it will be better to build an external circuit on a transistor and not use the comparator altogether.
Nikolai Golovchenko says:
Okay, synchronizing to horizontal pulses video in software works now. The trickiest part was to lock to sync pulses with the free running internal oscillator. Even the smallest errors (under 0.01 us per line) build up very quickly and synchronization fails...The program implements only horizontal sync locking, but vertical sync pulses detection should be a bit easier since they coincide with horizontal ones. Here is the details:
I used the built-in comparator and a DC level shifter to separate sync pulses. Here is the circuit in ascii 'art'.
-------*----------> +5V | | R2 | | 4k VT1 | --/\/\/-- n-p-n C\| | _ B|----*-/\/\/-* RB1| \ R1 C2 E/| | R3 -------|- \ RB0 1k 0.22u | | 30 RB2| >----o o--/\/\/--*--||-----*------|--------------|+ / Composite Video | | | |_/ sync out In --- C1 \ R5 --|>|---| --- 330p / 2.2M VD1 | Comparator | \ | === GND === === GNDThe resistors R2,R3 and diode VD1 set about a 60 mV threshold above the sync pulses lower level (sync pulses are negative going). Surprisingly, the comparator negative input reference should have been taken *above* the transistor base (as it is in the circuit). One would assume that BE voltage drop is about 0.6V and the negative input of comparator is already 0.6V above the sync 'floor'. But it is not so. The capacitor C2 has almost no way to discharge and consequently it is charged with very low current and the BE drop is about 0 V. Therefore, the sync floor potential is equal to the voltage set by divider at the transistor base. When the charging current rises, which happens when a new sync pulse arrives, so does the difference between comparator inputs, so the pulse at this moment is not missed.
The circuit takes 3 pins: 2 comparator inputs and 1 output. Comparator output could be checked by polling its configuration register, but it takes 3 instructions to check it this way:
waitHigh mov !RB, w ;exchange comparator conwfiguration ;with w (mode = $08) mov temp, w sb temp.0 jmp waitHigh ;6 cycles in loopwhile it takes just 1 instruction to check the port pin
waitHigh sb RB.0 jmp waitHigh ;4 cycles in loopSo I chose to sacrifice the pin as it is better to sample the comparator output a little faster (and smaller code size too).
Locking to the HSync frequency is the most difficult part here. As Simon Nield suggested I use two PLL modes:
- ) Crash PLL. It is used after chip reset and when too many sync pulses are missed. On each external pulse (longer than 2 us) SX resets RTCC and calculates error on the next pulse. Errors are summed up for 256 samples and the timer load value is corrected with the average error value. The timer load value is 16 bit, higher byte adds directly to RTCC and lower one to phase accumulator.
This mode works until average error goes low enough. After that the SX enters the fine PLL mode.
- ) Fine PLL. This is the hardest part. In this mode, the RTCC load value is not corrected (that is the line is assumed to have a fixed length), only RTCC is corrected. The correction value is produced by a low pass filter, which averages the errors. This works like an integral term in a PI regulator. I found out that proportional term (subtracting current error from RTCC) doesn't help really, because the error signal is so noisy that subtracting it from RTCC results in passing the noise further.
It works pretty well for a wide range of video sources, maybe just a bit worse than the TV circuit. Another possible issue may be that a line can have slightly different length for a different video source. That may result in a different position of overlaid image on the screen, because the clock is not adjusted, only its period is adjusted by PLL.
By the way, this was tested on SECAM, but I think NTSC and PAL are very close to SECAM in the horizontal sync parameters. In SECAM horisontal period is 64 us, sync pulse is 4.7 us, and equalizing pulses are 2.35 us.
Next step is vertical sync...
; PLL Syncronized signal over video (horizontal sync)
; SX28-52 demo board
;
; Crystal: 50 MHz
; Connections:
; RB3 - button (active low)
; RA0 - output --\/\/\---|>|--- to video
; R1 220 VD1
; RB0 - comparator output (sync active low)
;
; -------*----------> +5V
; | | R2
; | | 4k
; VT1 | --/\/\/--
; n-p-n C\| | _
; B|----*-/\/\/-* RB1| \
; R1 C2 E/| | R3 -------|- \ RB0
; 1k 0.22u | | 30 RB2| >----o
; o--/\/\/--*--||-----*------|--------------|+ / Composite
; Video | | | |_/ sync out
; In --- C1 \ R5 --|>|---|
; --- 330p / 2.2M VD1 | Comparator
; | \ |
; === GND === === GND
;
; The program locks to horizontal sync pulses and outputs
; two vertical lines when the button is pressed.
;
; RTCC is used without prescaler as a time base. A full line
; takes 64us*50=3200 cycles or 12.5 periods (overflows) of timer.
; At the start of each line a phase variable (default is 128) is
; added to RTCC, so RTCC overflows 13 times per line.
;
DEVICE SX28AC, BANKS8, PAGES4
DEVICE OSCHS3, TURBO, OPTIONX
RESET start
ORG 8
;global bank
ORG $10
;bank 0
temp DS 1
AVEHI DS 1 ;filter/averager output
AVELO DS 1 ;
counter DS 1 ;averaging counter
flags DS 1
missedPulses DS 1 ;missed pulses counter
phase DS 2 ;16 bit phase
RTCClow DS 1 ;phase accumulator
RTCCsample DS 1 ;error sample
ORG $30
;bank 1
ORG $50
;bank 2
ORG $70
;bank 3
ORG $90
;bank 4
ORG $B0
;bank 5
ORG $D0
;bank 6
ORG $F0
;bank 7
ledRun EQU RC.7
keyGo EQU RB.3
videoOut EQU RA.0
videoIn EQU RB.0 ;comparator output (sync is negative going)
initRTCC EQU 128 ;default RTCC initial value
crashPLL EQU flags.0
pulseBad EQU flags.1
compMode EQU %00000000
; ||\____/
;Comparator enabled _|| |
;Comp. RB0 out enabl._| |
;reserved bits __________|
ORG 1
start
; Set up pins (mode = $0F - port direction access)
clr RA
clr RB
clr RC
mov w, #$00
mov !RA, w ;RA - output
mov !RC, w ;RC - output
mov w, #$0E
mov !RB, w ;RB - output/input
;set up RTCC
mov w, #%11001000
; |||||\_/
; ||||| |
;Reg 0 is RTCC __||||| |
;RTCC int is dis__|||| |
;RTCC clock int.___||| |
;RTCC edge 0/1______|| |
;Prescaler to WDT ___| |
;Prescaler (WDT) 1:2 __|
mov !OPTION, w
;256 RTCC counts is 256/50=5.12 us
;set up comparator
mov M, #$08 ;comparator access
mov w, #compMode
mov !RB, w ;exchange comparator reg and w
mov M, #$0F ;restore mode
;Catch a 4us pulse
crashStart
mov w, #initRTCC ;initialize phase value
mov phase+1, w
clr phase
clr RTCClow ;clear phase accumulator
setb crashPLL ;enter 'crash' PLL mode
clr AVEHI ;clear averager
clr AVELO ;
clr counter ;
clr missedPulses ;clear missed pulses counter
waitHSync
sb videoIn ;wait for 1
jmp $-1
snb videoIn ;wait for 0
jmp $-1
clr RTCC ;reset timer
;input must be 0 for at least 4 us
;4us = 4 * 50 = 200 cycles
mov w, #33 ;33*6=198
mov temp, w
measureHSync
snb videoIn
jmp waitHSync ;pulse too short
decsz temp
jmp measureHSync ;6 cycles in a loop
;We don't detect if a pulse is too long since this would be a vertical
;sync which is synchronized to the horizontal pulses.
;By rejecting pulses less than 4 us we reject also equalizing pulses
;which appear at vertical sync at double rate of horizontal sync pulses.
;This is done to start crash PLL mode somewhere from a normal HSync
;to not get into the middle of lines. But in normal PLL mode the equalizing
;pulses are detected.
;At this point about 4 us passed since HSYNC pulse first front and RTCC reset
;4us = 200 cycles, so timer didn't overflow yet
snb RTCC.7 ;wait for timer overflow
jmp $-1
updateTimer
mov w, phase ;add phase to
add RTCClow, w ;phase accumulator
mov w, phase+1 ;
snc ;
mov w, ++phase+1 ;
add RTCC, w ;and timer
;Now we have about 128+-60 cycles before 2nd RTCC overflow
;Wait 4 overflows 4 * 256/50 = 20.48 us
mov w, #4
mov temp, w
wait5th
sb RTCC.7
jmp $-1
snb RTCC.7
jmp $-1
decsz temp
jmp wait5th
; Send a 5.12 us pulse (one RTCC overflow) over video if button pressed
snb keyGo ;don't set videoOut if no button pressed
setb videoOut
snb keyGo
setb ledRun
sb RTCC.7 ;wait for transition from 1 to 0 in RTCC.7
jmp $-1
snb RTCC.7
jmp $-1
;end pulse
clrb videoOut
clrb ledRun
;Wait 6 overflows (12 total so far)
mov w, #6
mov temp, w
wait12th
sb RTCC.7 ;wait for transition from 1 to 0 in RTCC.7
jmp $-1
snb RTCC.7
jmp $-1
decsz temp
jmp wait12th
; Send a 2.56 us pulse (half RTCC period) over video if button pressed
snb keyGo
setb videoOut
snb keyGo
setb ledRun
sb RTCC.7
jmp $-1
clrb videoOut ;end pulse
clrb ledRun
sb RTCC.5 ;wait until 96 counts just before 13th overflow,
jmp $-1 ;which should coincide with the next HSync pulse
;Start detecting HSync. Wait for positive to negative transition
;and measure the pulse width.
clrb pulseBad
mov w, #32 ;32*6=96*2 (+-96 cycles window)
mov temp, w
HSyncWaitHigh
snb videoIn
jmp HSyncWaitLow
decsz temp
jmp HSyncWaitHigh
setb pulseBad
jmp PulseNotCaught
HSyncWaitLow
sb videoIn
jmp PulseCaught
decsz temp
jmp HSyncWaitLow
setb pulseBad
jmp PulseNotCaught
PulseCaught
mov w, RTCC ;sample RTCC, which is a distance from
;pulse to overflow.
mov RTCCsample, w
;input must be 0 for at least 2 us
;2us = 2 * 50 = 100 cycles
mov w, #16 ;16*6=96
mov temp, w
PulseCaught1
snb videoIn
setb pulseBad ;pulse too short
decsz temp
jmp PulseCaught1 ;6 cycles in a loop
;At this point, 98 cycles after RTCC sample
;Don't check if the pulse is too long. VSync pulse coincides
;with HSync.
PulseNotCaught
;wait for overflow (RTCC=98+-96=2..194)
sb RTCC.7
jmp $-1
snb RTCC.7
jmp $-1
;now we have about 60 cycles here to do PLL (default RTCC increment
;is 128 and it can change about +-60 (+-2% variation in line length)
;and we have to catch timer's first overflow)
;now check pulse measurement results. If pulse bad, clock on
;RTCC and increment missed pulses counter
sb pulseBad
clr missedPulses ;clear missed pulses counter
sb pulseBad
jmp PLLstart
;pulse is missed.
;increment missed counter and resynchronize if too many missed.
inc missedPulses
snb missedPulses.5 ;threshold = 32 missed pulses
jmp crashStart
clr RTCCsample ;assume zero RTCC sample and
;run PLL anyway
PLLstart
snb crashPLL
jmp crashPLLbranch
;Fine PLL mode.
;Integral control:
; RTCC -= H(z)*error*gain
;
; H(z)=b0/(1-a1*1/z), or y = u*b0 + y[-1]*a1
;
; b0 = 1/256, a1 = 255/256
; gain = 1/256
;Run low-pass filter
mov w, AVEHI ;AVE *= 1-1/256
sub AVELO, w
snb AVEHI.7
inc AVEHI
sc
dec AVEHI
mov w, RTCCsample ;AVE += RTCCsample/256
add AVELO, w
snc
inc AVEHI
snb RTCCsample.7
dec AVEHI
;correct RTCC,
;RTCC -= AVE/256
mov w, AVEHI
sub RTCClow, w
clr temp
snb AVEHI.7
not temp
mov w, temp
sc
mov w, ++temp
sub RTCC, w
jmp updateTimer
crashPLLbranch
mov w, RTCCsample ;accumulate error to determine new phase
add AVELO, w
snc
inc AVEHI
snb RTCCsample.7
dec AVEHI
;reset RTCC (RTCC should be zero at HSync pulse)
sub RTCC, w
decsz counter
jmp updateTimer
;error is ready in AVE
;subtract it from RTCC load value
mov w, AVELO
sub phase, w
mov w, AVEHI
sc
mov w, ++AVEHI
sub phase+1, w
;if error is small
;end the crash PLL
mov w, AVEHI
snb AVEHI.7
xor w, #$FF
sz
jmp PLL_ErrorTooBig
mov w, --AVELO
xor w, #$FF
sb AVEHI.7
mov w, AVELO
and w, #$F0
snz
clrb crashPLL ;end crash PLL phase
PLL_ErrorTooBig
clr AVELO
clr AVEHI
jmp updateTimer
| file: /Techref/scenix/lib/io/dev/video/hsync-ng.htm, 15KB, , updated: 2002/7/9 17:28, local time: 2025/10/24 18:24,
216.73.216.188,10-3-157-36:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.ecomorder.com/Techref/scenix/lib/io/dev/video/hsync-ng.htm"> SX Video IO </A> |
| Did you find what you needed? |
Welcome to ecomorder.com! |
|
The Backwoods Guide to Computer Lingo |
.