65Org16.x Dev. Board V1.1 using a Spartan 6 XC6SLX9-3TQG144
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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.
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.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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.
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.
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.
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.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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!
Edit: glad to be wrong in this case!
Last edited by BigEd on Mon Mar 12, 2012 6:13 pm, edited 1 time in total.
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:
Detail:
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:
6502.org wrote:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/colorbars1.jpg
6502.org wrote:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/colorbars2.jpg
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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.
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.
If you want to experiment with I2C, you can have my GPIO based solution. gpio.v
ucf lines for SCL/SDA
And my 6502 I2C code. It only supports writing, no clock stretching, and it doesn't look for ACK responses.
ucf lines for SCL/SDA
Code: Select all
NET "SCL" LOC = P88 | IOSTANDARD = LVCMOS33;
NET "SDA" LOC = P87 | IOSTANDARD = LVCMOS33;
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
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Some FPGA generated vertical bars in black/white:
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.
6502.org wrote:
Image no longer available: http://ladybug.xs4all.nl/arlet/fpga/bars.jpg
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.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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!
EDIT: wrong pins!
Last edited by ElEctric_EyE on Mon Mar 12, 2012 6:28 pm, edited 1 time in total.
This is what I have:
Right now, I'm only using HSYNC to reset the horizontal pixel counter, and using that counter to generate the Y outputs.
Code: Select all
NET "HSYNC" LOC = P58 | IOSTANDARD = LVCMOS33;
NET "VSYNC" LOC = P57 | IOSTANDARD = LVCMOS33;
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.
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.