Not bad, simple and compact. If you would take my recommendation, I would recommend these alterations, which may help alleviate you horizontal/vertical picture alignment bug. (maybe, the problem may be elsewhere which we can discover with another test...)
1. Make vga_visible (for H&V) = (VGA_X < H_VISIBLE) && (VGA_Y < V_VISIBLE)
Ahhhhh, now your outputs VGA_X and VGA_Y are your actual output visible X&Y coordinates. Now, for the X, you can use these to feed the address of your dual-port line buffer memory on the output side.
2. Make VGA_HS = (VGA_X >= H_VISIBLE + H_FRONT_PORCH ) && (VGA_X =< H_VISIBLE + H_FRONT_PORCH + H_SYNC_PULSE) ;
3. Do the same for VGA_VS.
2. Make VGA_HS = (VGA_X >= H_VISIBLE + H_FRONT_PORCH ) && (VGA_X =< H_VISIBLE + H_FRONT_PORCH + H_SYNC_PULSE) ;
If it is useful, here is a dump of all the registers o the TVP, starting from address 0x00.
02 69 80 A0 00 06 10 20 00 00 00 80 83 80 52 2E
5D 20 01 00 B5 04 11 02 00 00 C2 77 07 00 10 10
10 0D 08 12 6B 10 80 0C 53 08 07 00 50 00 80 8C
04 5A 18 60 03 10 00 00 20 69 00 07 00 03 04 00
2C 01 2C 06 05 05 1E 1E 00 00 E3 16 4F 02 CE 06
AB F3 00 10 55 FC 78 F1 88 FE 00 10.
Can you break this down into control names starting on page 26 of TI's datasheet?
69 8 = pll-divider = 1688 (This means you set the chip to sample 1688 pixels from H-sync to H-Sync)
1688 * 25Khz = 42200Khz, or, 42.2MHz. You said 108MHz, this isn't right.
ADR $03 = A0 = Oscillator = 10 = 70-135MHz, and, 100 = charge pump current just below default.
Change this from $A0 to $60 if you are indeed running at 42.2MHz.
06 = Clamp start - The point in the picture to DC clamp the input capacitor to black level reference. Make sure external clamp is disabled otherwise the video may clip to all 100% white or all 100% black.
10 = 16 = clamp width - The duration of this clamp.
Adr...0E = 52 = #01010010
HSPO: HSYNC polarity override 0 = Polarity determined by chip (default)
HSIP: HSYNC input polarity 1 = Indicates input HSYNC polarity active high (default)
HSOP: HSYNC output polarity 0 = Active low HSYNC output (default)
AHSO: Active HSYNC override 1 = Active HSYNC is manually selected via the AHSS control bit (bit 3 of register 0Eh). (default)
AHSS: Active HSYNC select. 0 = Active HSYNC is derived from the selected HSYNC input
VSOP: VSYNC output polarity 0 = Active low VSYNC output (default)
AVSO: Active VSYNC override 1 = Active VSYNC is manually selected via the AVSS control bit (bit 0 of register 0Eh). (default)
AVSS: Active VSYNC select. 0 = Active VSYNC is derived from the selected VSYNC input
Are the read-back of HS polarity and VS polarity true? Bit 6 for HS and Bit
Change ADR $10 from $5D to $58. No big difference here since you are not using Red and Blue.
Try switching:
ADR $22 to = 02.
ADR $26 to = 0. (Must be disabled for your scopes weird non-standard video format.)
Readback address $38 = 20, this is a semi-good sign, ADR$37 = 00 is a bad sign. The IC isn't counting the number of lines in a frame... If the IC working on the video V-sync and H-Sync, unless I misunderstood these 2 read only registers.
Readback address $39 and $40, = $069 = 105 = 27mhz / 105 = 257142.8571 hz, or, 257 Khz??? Is this correct, isn't your video around 25.7Khz? Or, if you are using the IC internal 6.3 MHz clock reference, we get 60KHz?
Readback ADR $3D = 0 - This is telling us your V-Sync is 0 lines long. This is obviously wrong. Again, it is a sign that the IC doesn't see the VS or HS properly....
Also, make sure that reset pin is held low during power-up for a bit of time before making it high.
_delay_ms(100); //(TVP must be held in reset for 5ms after power up)
DDRB = 0x45;
PORTB |= 0x05;
PORTB |= 0x40; //Bring TVP out of reset
_delay_ms(100); //No I2C traffic for 1us after reset is released
What are you reading on the green data port, all high, or all low. If you are getting all high, then the ADC may be working fine and all we need to do is debug the clamp position setting after you look at my above changes.
Probe pins 81 and 78 directly, see if your syncs are getting there.
Also, scope the video going into the TVP IC, tell me what the voltage offset is.
Must've forgotten to upload it, sorry.
#1 Short out cap C23.
#2 Short out cap C32.
#3 Short out R9.
#4 Remove C12.
Optional, if you want to exactly match TI's reference design...
#5 Add a 1nf cap to pin 1 of U3 and GND.
#6 Cut the V-Sync signal going to pin 1 of U3 and add a 330 ohm series resistor.
Is your scope video shot at the input pin side of the cap?
If adjusting black level moves the ADC reading, basically this moves the DC voltage of the input pins during the clamp period, but, you see no picture data, it is as if you have the wrong analog video input selected, or, that video signal just isn't reaching the TVP video input pin, but, the ADC still seems to sample that black level charge.
Just for crazy sake, probe the red and blue data ports just to see if they have any modulated data on them.
Also, disable the SOG detector in the I2C bits.
Also change ADR $26 to = 0. Without tri-level syncs, or by-level syncs the AGC / automatic contrast system will fail. PC RGB video doesn't have these sync levels to measure what the contrast should be.
At this point, you should be using the ADC clock for everything through the FPGA to drive your DAC clock (in your case it may just be IOs) output, and raster generator.
It looks like you have an input data latch setup-and-hold error.
Just invert the clock input to your FPGA, or if you are feeding the FPGA PLL to multiply your clock, change the input phase.
The clock out of the ADC may also have a programmable phase.
Also, try adjusting the sampling phase on the I2C commands. The ADC may be sampling right at the edge of a pixels.
Confirm ADC clock speeds and the PLL settings inside the ADC.
Same goes goes the FPGA PLL if you are using it to double the ADC's clock signal quality distributed inside the FPGA.
Also try lowering the ADC bandwidth / video input filter response.
At this point, you should be using the ADC clock for everything through the FPGA to drive your DAC clock (in your case it may just be IOs) output, and raster generator.
It shouldn't matter if I am using a different clock domain on the other side of the dual port BRAM - this is a perfectly acceptable way of doing it for now. The reason I am using a different clock for the TX side of the BRAM is that, due to an oversight on my part, the clock output of the TVP doesn't go to a clock input on my FPGA eval board so the routing is pretty bad (vivado keeps complaining about it) so I want to minimise the usage of that clock. When I design my own fpga board I will use the TVP clock as the main clock.
It looks like you have an input data latch setup-and-hold error.
Just invert the clock input to your FPGA, or if you are feeding the FPGA PLL to multiply your clock, change the input phase.
The clock out of the ADC may also have a programmable phase.
Also, try adjusting the sampling phase on the I2C commands. The ADC may be sampling right at the edge of a pixels.
Confirm ADC clock speeds and the PLL settings inside the ADC.
Same goes goes the FPGA PLL if you are using it to double the ADC's clock signal quality distributed inside the FPGA.
Also try lowering the ADC bandwidth / video input filter response.
It wasn't a setup-hold error in the FPGA. I have constrained all inputs based on the TVP datasheet and there are no complaints. I have mostly fixed the issue by changing the ADC clock phase so that the signals settle better before sampling.
I have also realised that the colours of the scope can be set to 100 different levels so i will need at least a 7-bit video DAC on the other side of the FPGA to make sure I can represent all 100 colours properly. Currently I only have a 4-bit DAC and I can produce a lot of noise on screen by setting the color level to be right on the boundary between one of these 16 colours. I'm thinking I will use the ADV7120 which is 8-bit.
I am planning to use linear interpolation, but it makes memory handling a bit more complex. Effectively for every pixel I will need to read make 3 memory accesses (pixel above, pixel below and the pixel to the right). The output operates at 48.875MHz which means I need to read at 3x that, all while also fitting in the write cycles for the RX. Any tips on doing this?