Page 10 of 19
Posted: Mon Mar 12, 2012 10:47 am
by ElEctric_EyE
Could be those impedance matching 75 or 300 ohm resistors, as shown on pg. 55 of the CS4954 datasheet? I forgot to send those, now I realize. Wasn't sure which ones to use... You using composite out or s-video out?
Posted: Mon Mar 12, 2012 10:58 am
by Arlet
At first I tried it without the resistor, and then I added a 75 Ohm one. It made no real difference, except in brightness.
According to the data sheet, black/white image can occur if the 27MHz clock has too much jitter. So I changed it from DCM to PLL, which is supposed to reduce jitter, but that also made no visible difference.
I'm using composite out.
Posted: Mon Mar 12, 2012 12:31 pm
by ElEctric_EyE
The only 2 places I deviated from the datasheet was I used a 3.9K resistor instead of 4K as I coudn't find any 4K. And they're 5% tolerance, not the 1% as spec'd, although I don't think this would be the problem. Also, there is no low pass filter on VCC, I just used a .1uF (I may have erroneously used a .01uF).
Maybe it needs to be set up for PAL? Table 4 on Pg. 23 shows the registers for each standard. Not sure what the default is.
Posted: Mon Mar 12, 2012 12:51 pm
by Arlet
I also tried master mode. In that mode, the CS4954 generates its own HSYNC/VSYNC pulses, eliminating a source of error. In this mode, all you need to generate video is a few I2C register writes and the 27 MHz clock.
I've replaced the 3.9 k resistor by 4 k, and replaced C37. Also tried filtering the DAC output. No visible change to the image.
The CS4954 has an option to use an external color burst crystal, but that's very tricky to patch on the existing board.
Posted: Mon Mar 12, 2012 1:14 pm
by ElEctric_EyE
I double checked my layout and it is correct. I did notice there was 2 110ohm input resistors for the SDA SCL lines I did not use...
(I shouldn't say 'double checked'. That's probably the 10th time I checked)
Posted: Mon Mar 12, 2012 1:33 pm
by BigEd
My guess would be first that NTSC is not acceptable for your setup (so try PAL) and if that's not it, it's probably too much jitter on the 27MHz. Can you think of any way to measure that? The data sheet says 3ppm required.
Edit: glad to be wrong in this case!
Posted: Mon Mar 12, 2012 1:48 pm
by Arlet
I just found a mistake in my code. My program was based on an old bootloader program that was located between $0080 and $0180, using part of zero page, and part of the stack. Because the program had grown bigger, it was overlapping the entire stack, and that caused it to crash halfway updating the I2C registers.
I've moved my test code to $0200, and now it works. All registers are programmed, and the TV shows reasonable looking color bars.
Picture from TV:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/colorbars1.jpg
Detail:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/colorbars2.jpg
Posted: Mon Mar 12, 2012 2:04 pm
by ElEctric_EyE
Awesome!!!
How do you intend to send the pixel data? YCbCr or YUV?
Posted: Mon Mar 12, 2012 2:35 pm
by Arlet
I hadn't considered that part yet, but since the chip seems to use YUV internally (it mentions in 4.2 there's an optional conversion from YCbCr to YUV), using YUV would seem preferable.
In any case, I was planning to use RGB internally, and perform the RGB -> YUV conversion as the last step in the video pipeline. Switching between YUV and YCbCr is then just a matter of using different coefficients.
A straightforward converter uses 3 DSP48 blocks, operating at 27 MHz pixel clock. It's also possible to put to conversion earlier in the pipeline, and spread out the conversion over multiple cycles. With a 81+ MHz clock, you could do all the calculations with a single DSP48 block.
Posted: Mon Mar 12, 2012 2:57 pm
by Arlet
If you want to experiment with I2C, you can have my GPIO based solution.
gpio.v
ucf lines for SCL/SDA
Code: Select all
NET "SCL" LOC = P88 | IOSTANDARD = LVCMOS33;
NET "SDA" LOC = P87 | IOSTANDARD = LVCMOS33;
And my 6502 I2C code. It only supports writing, no clock stretching, and it doesn't look for ACK responses.
Code: Select all
sda_low:
and #$fe ; clear SDA bit
i2c_write:
sta $b010 ; write to I2C
jsr i2c_delay ;
jmp i2c_delay ;
sda_high:
ora #$01 ; set SDA bit
bne i2c_write ;
scl_low:
and #$fd ; clear SCL bit
sta $b010 ;
jmp i2c_delay ;
scl_high:
ora #$02 ; set SCL bit
sta $b010
jsr i2c_delay
i2c_delay:
ldx #10 ; adjust based on clock speed
@1: dex
bne @1
rts
i2c_start:
lda #2
jsr sda_low
jmp scl_low
i2c_stop:
jsr i2c_delay
jsr sda_low
jsr scl_high
jmp sda_high
i2c_rdbit:
sec
i2c_wrbit:
lda #0
adc #0
jsr scl_low
jsr scl_high
jmp scl_low
i2c_wrbyte:
sta data
ldy #9
@1: sec
rol data
jsr i2c_wrbit
dey
bne @1
rts
;; X contains register
;; A contains value
video_write_reg:
stx addr
sta val
jsr i2c_delay
jsr i2c_delay
jsr i2c_start
lda #0
jsr i2c_wrbyte
lda addr
jsr i2c_wrbyte
lda val
jsr i2c_wrbyte
jmp i2c_stop
Posted: Mon Mar 12, 2012 5:13 pm
by ElEctric_EyE
Been working on the .b core so much I've hardly touched the hardware recently.
I'll fix that short you spotted and try what I have just for giggles. If it doesn't work still, I'll try what you've done. Thanks alot!
Posted: Mon Mar 12, 2012 5:27 pm
by Arlet
Some FPGA generated vertical bars in black/white:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/bars.jpg
I don't count vertical lines, just horizontal pixels. Based on the horizontal pixel count, either a black or white pixel is sent to Y port. The CS4954 is still used in master mode, and responsible for generating HSYNC/VSYNC signals. The FPGA starts a new line at the HSYNC pulse, without any regard for blanking period. That's okay, because the CS4954 takes care of the timing, and provides the right blanking.
Next step is to count lines as well, and delay the first pixel by a programmable number of rows and colums, so it ends up in the top left corner of the visible area.
Posted: Mon Mar 12, 2012 5:42 pm
by ElEctric_EyE
Are you using pin 58 of the Spartan6 to sample HSYNC from the CS4954? pin 57 is VSYNC. I forgot to include these in the .ucf file.
EDIT: wrong pins!
Posted: Mon Mar 12, 2012 6:05 pm
by Arlet
This is what I have:
Code: Select all
NET "HSYNC" LOC = P58 | IOSTANDARD = LVCMOS33;
NET "VSYNC" LOC = P57 | IOSTANDARD = LVCMOS33;
Right now, I'm only using HSYNC to reset the horizontal pixel counter, and using that counter to generate the Y outputs.
Posted: Mon Mar 12, 2012 8:15 pm
by Arlet
For easy testing, I've put a .bit file on my web server that you can load directly into the FPGA without having to build the project yourself.
main.bit
I've modified the registers for NTSC-M. Let me know if that works for you. The USB port uses 115200 baud. The video shows a black/white test pattern, with a blue edge on the left. Using the '+' and '-' characters on the USB/serial port, you can move the edge back and forth. The program will respond with a hex value of the horizontal start register.