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 === === GND
The 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 loop
while it takes just 1 instruction to check the port pinwaitHigh sb RB.0 jmp waitHigh ;4 cycles in loop
So 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 16:28, local time: 2023/2/1 12:05,
|©2023 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.org/Techref/scenix/lib/io/dev/video/hsync-ng.htm"> SX Video IO </A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to massmind.org!