It may only want to support HDMI modes and not DVI modes. I have an old TV that has separate HDMI and DVI modes. Sometimes it only works on one of the settings. It will be a while before I can test that unit with the P2.
You could try changing the clock phase. It should be "correct" already. 10 sysclocks is 1 output cycle. The code from VonSzarvas generates what I consider the correct phase. We might get it if we generate a 720x480 signal. An easy thing to try would be to use 270MHz sysclock. Also, are you in an NTSC or PAL region?
Chip wrote the original code.
A two-cog 640x480x8pp soft HDMI display with palette of 256 out of a possible 4096 colours was worked out last November, however it has not been tested yet. Colour levels are equally spaced but TMDS data are mostly not balanced. 720x480x8pp and sprites should be possible, too. It's questionable how much time should be spent on this, but it would good to get something working now that people have HDMI boards.
Thanks, TonyB. Lots of good content in the first half of this thread. I started the other thread because people shouldn't have to search a 20 page thread to find code for their HDMI board. I re-read this thread and found the code on page 10.
Since the new silicon will generate proper signals, I though that using the 52 balanced codewords would be an acceptable trade-off for now. Generating a non-balanced signal may be an acceptable temporary trade-off as well.
Work on HDMI audio wouldn't be wasted. What we write now should work on production silicon with minor changes.
' HDMI framebuffer demo for P2-ES chips
'
' Framebuffer is 640x480 x 8 bit grayscale
' Output as 1280x720 24fps, you will see 6 copies of the image
'
' adds video preamble and null data island so it is detected as HDMI
'
' It uses only the 52 TMDS words that are naturally balanced.
' Pixel values with non-balanced words are assigned to their nearest balanced
' neighbor.
' Clock is generated by the smart pins
'
' http://forums.parallax.com/discussion/comment/1463078/#Comment_1463078
'
'
'
'
' HDMI display test for early P2 silicon with 20MHz crystal and
' P[7:0] connected to HDMI {R+, R-, G+, G-, B+, B-, CLK+, CLK-}
'
' The next version of silicon will have TMDS hardware to compose LVDS stream on the fly.
'
con
xtal = 20_000_000
dv = 20
mlt = 297
pdv = 1
clk = 1 << 24 | (dv-1) << 18 | (mlt-1) << 8 | (((pdv>>1)+15) & $F) << 4
sys_clk = xtal / dv * mlt / pdv
dat org
jmp #tablebypass
tmdstable ' This table uses only balanced TMDS words, the 8 bit input is quantized to the nearest value
long $1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0
' long $1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0,$1f0 actual first line
long $1f0,$10f,$10f,$10f,$10f,$10f,$10f,$10f,$10f,$10f,$11e,$11e,$11e,$11e,$11e,$11e ' there are 52
long $11e,$11e,$11e,$1e1,$1e1,$1e2,$1e2,$11d,$11d,$11d,$1e4,$1e4,$1e4,$11b,$11b,$11b ' unique values
long $11b,$11b,$247,$247,$247,$247,$247,$2b8,$1e8,$117,$117,$117,$117,$117,$117,$13c ' in this table
long $13c,$13c,$13c,$13c,$13c,$1c3,$1c3,$1c3,$1c6,$1c6,$1c6,$139,$139,$139,$139,$139
long $1cc,$1cc,$1cc,$1cc,$1cc,$133,$133,$133,$263,$263,$263,$29c,$29c,$29c,$29c,$29c
long $29c,$29c,$1d8,$1d8,$1d8,$1d8,$1d8,$1d8,$1d8,$127,$127,$271,$271,$28e,$28e,$28e
long $28e,$28e,$287,$287,$287,$287,$287,$278,$278,$278,$278,$278,$278,$278,$278,$278
long $178,$178,$178,$178,$178,$178,$178,$178,$178,$187,$187,$187,$187,$187,$18e,$18e
long $18e,$18e,$18e,$171,$171,$227,$227,$2d8,$2d8,$2d8,$2d8,$2d8,$2d8,$2d8,$19c,$19c
long $19c,$19c,$19c,$19c,$19c,$163,$163,$163,$233,$233,$233,$2cc,$2cc,$2cc,$2cc,$2cc
long $239,$239,$239,$239,$239,$2c6,$2c6,$2c6,$2c3,$2c3,$2c3,$23c,$23c,$23c,$23c,$23c
long $23c,$217,$217,$217,$217,$217,$217,$2e8,$1b8,$147,$147,$147,$147,$147,$21b,$21b
long $21b,$21b,$21b,$2e4,$2e4,$2e4,$21d,$21d,$21d,$2e2,$2e2,$2e1,$2e1,$21e,$21e,$21e
long $21e,$21e,$21e,$21e,$21e,$21e,$20f,$20f,$20f,$20f,$20f,$20f,$20f,$20f,$20f,$2f0
long $2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0,$2f0
tablebypass
mov 0,#$1f0 ' patch table
hubset ##clk | %0000_01_00 'enable crystal+PLL, stay in 20MHz+ mode
waitx ##20_000_000/100 'wait ~10ms for crystal+PLL to stabilize
hubset ##clk | %0000_01_11 'now switch to PLL running
mov active_adj,active_pix ' ##640-12-32 'active_pix
sub active_adj,#12+32
mov backporch_adj,backporch
sub backporch_adj,#10
setxfrq ##$80000000 'set streamer to output on every clock
mov dira,#$Fc 'P[7:0] = {R+, R-, G+, G-, B+, B-, CLK+, CLK-}
'wait to set 0,1 high, they active the smart pins
'
'
'
'
' Output screen data over and over
'
'grayfield
'
wrlut #%0101_0100,#0 ' 2+,2-,1+,1-,0+,0-,C+,C-
wrlut #%1010_1000,#1
wrlut #%0101_0100,#%10_0000 ' 2 bit immediate mode LUT for sync words
wrlut #%0101_1000,#%10_0001 ' bit 0 goes to channel 0
wrlut #%1010_0100,#%10_0010 ' bit 1 goes to channels 1,2
wrlut #%1010_1000,#%10_0011 ' clock bits stay low, they come from smart pins
wrlut #%0101_0100,#%100_0000 ' 2 bit immediate mode LUT for sync words
wrlut #%1001_1000,#%100_0001 ' bit 0 goes to channels 0,2
wrlut #%0110_0100,#%100_0010 ' bit 1 goes to channel 1
wrlut #%1010_1000,#%100_0011 ' clock bits stay low, they come from smart pins
wrlut #%0101_0100,#%110_0000 ' 4 bit immediate mode LUT for data island
wrlut #%0101_1000,#%110_0001 ' 4 bit immediate mode LUT for data island
wrlut #%0110_0100,#%110_0010 ' 4 bit immediate mode LUT for data island
wrlut #%0110_1000,#%110_0011 ' 4 bit immediate mode LUT for data island
wrlut #%1001_0100,#%110_0100 ' 4 bit immediate mode LUT for data island
wrlut #%1001_1000,#%110_0101 ' 4 bit immediate mode LUT for data island
wrlut #%1010_0100,#%110_0110 ' 4 bit immediate mode LUT for data island
wrlut #%1010_1000,#%110_0111 ' 4 bit immediate mode LUT for data island
mov x,nco_mode 'use 2 smart pins to generate the clock signal
wrpin x,#0
wrpin x,#1
mov x,##$5 'base period is 5 clocks
wxpin x,#0
wxpin x,#1
mov x,##$8000_0000 'Toggle every 1 base period
wypin x,#0
wypin x,#1
waitx #(15-4)
rdfast frame_cnt,##framebuffer 'ready to loop-read framebuffer
rfbyte thispix ' start reading pixel data
sets .vi,thispix '
dirh #0 ' Start the clock generation
waitx #(1) '
dirh #1 ' These 3 instructions have critical timing
waitx #(10-8) ' This delay adjust the clock phase relative to the data
' Curiously, it may not matter
.field mov x,active_lines 'ready for 480 visible lines
.vis
rep #1,#8
xcont pre_mod,imvidpre
xcont pre_mod,imvidguard
xcont pre_mod,imvidguard
'rep #1,#10
'xcont sync_mod,imsync0
rep #3,active_pix
.vi xcont pix_mod,0
rfbyte thispix ' Note: the first pixel of the frame was read at the end of
sets .vi,thispix ' the last frame. Might be an issue for video.
rep #1,frontporch
xcont sync_mod,imsync0
rep #1,hsyncwidth
xcont sync_mod,imsync1
rep #1,backporch_adj '-10
xcont sync_mod,imsync0
drvnot #16
djnz x,#.vis
rep #1,#10
xcont sync_mod,imsync0
mov x,pre_lines 'ready for 10 invisible lines
.pre
rep #1,active_pix
xcont sync_mod,imsync0
rep #1,frontporch
xcont sync_mod,imsync0
rep #1,hsyncwidth
xcont sync_mod,imsync1
rep #1,backporch
xcont sync_mod,imsync0
djnz x,#.pre
mov x,vsync_lines 'ready for 6 sync lines
.sync
rep #1,#8
xcont sync_mod,imdatpre
xcont sync_mod,imdatguard ' data guard band
xcont sync_mod,imdatguard
xcont raw_mod,di_head ' null data packet
xcont raw_mod,di_head+1
xcont raw_mod,di_head+2
xcont raw_mod,di_head+3
xcont raw_mod,di_head+4
rep #5,#7
xcont raw_mod,di_tail
xcont raw_mod,di_tail+1
xcont raw_mod,di_tail+2
xcont raw_mod,di_tail+3
xcont raw_mod,di_tail+4
xcont sync_mod,imdatguard
xcont sync_mod,imdatguard
rep #1,active_adj ' ##640-12-32 'active_pix
xcont sync_mod,imsync2
rep #1,#frontporch
xcont sync_mod,imsync2
rep #1,hsyncwidth
xcont sync_mod,imsync3
rep #1,backporch
xcont sync_mod,imsync2
djnz x,#.sync
mov x,post_lines 'ready for 31 invisible lines
.post
rep #1,active_pix
xcont sync_mod,imsync0
rep #1,frontporch
xcont sync_mod,imsync0
rep #1,hsyncwidth
xcont sync_mod,imsync1
rep #1,backporch
xcont sync_mod,imsync0
djnz x,#.post
rep #1,active_pix
xcont sync_mod,imsync0
rep #1,frontporch
xcont sync_mod,imsync0
rep #1,hsyncwidth
xcont sync_mod,imsync1
rep #1,backporch_adj ' -10
xcont sync_mod,imsync0
jmp #.field
'
'
' Data
'
sync0 long %11010_10100 '
sync1 long %00101_01011 ' hsync
sync2 long %01010_10100 'vsync
sync3 long %10101_01011 'vsync + hsync
imsync0 long %11_11_00_11_00__11_00_11_00_00 'even bits=sync0, odd=sync0
imsync1 long %10_10_01_10_01__10_01_10_01_01 'even bits=sync1, odd=sync0
imsync2 long %10_11_00_11_00__11_00_11_00_00 'even bits=sync2, odd=sync0
imsync3 long %11_10_01_10_01__10_01_10_01_01 'even bits=sync3, odd=sync0
imvidpre long %01_01_10_01_10__01_10_01_10_10 'even bits=sync0, odd=sync1
imvidguard long %01_10_01_01_10__10_01_01_10_10
imdatpre long %00_01_10_01_10__01_10_01_10_10 'even=ch0 odd=ch1,2
imdatguard long %00_11_00_01_11__10_00_00_11_11 'even=ch0 odd=ch1,2
'line_mod long $1080<<16 + linebytes 'RFBYTE streamer mode
frame_cnt long 640*480 / 64
'line_vis long base + linebytes*0 'visible line address
'line_inv long base + linebytes*1 'invisible line address
'line_syn long base + linebytes*2 'sync line address
'line_tail long base + linebytes*0 +512*10 'visible line address
'tail_mod long $1080<<16 + (linebytes-(512*10)) 'RFBYTE streamer mode
'tail_cnt long (linebytes-(512*10)) / 64
nco_mode long %0000_100000000_01_00110_0
pix_mod long $8<<28 + 0<<16 + 1<<23 + 10 ' 1 bit immediate LUT
sync_mod long $9<<28 + 1<<16 + 1<<23 + 10 ' 2 bit immediate LUT
pre_mod long $9<<28 + 2<<16 + 1<<23 + 10 ' 2 bit immediate LUT
raw_mod long $a<<28 + 3<<16 + 1<<23 + 8 ' 4 bit immediate LUT
frontporch long 100
hsyncwidth long 40
backporch long 220 ' must be > 10
active_pix long 1280 ' must be > 44
active_lines long 720
pre_lines long 5
vsync_lines long 5
post_lines long 19 ' +1 to this value
thispix long 0
active_adj long 0
backporch_adj long 0
' http://hamsterworks.co.nz/mediawiki/index.php/Minimal_HDMI
'full data island 160 bytes = 40 longs = 32 pixels
'minimum transmission unit 40 bytes = 5 longs = 4 pixels
'channel 210 210 210 210 210 210 210 210 210 210
di_head byte %000_0000,%110_0111,%001_0110,%111_0001,%111_0000 ' play once
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
di_tail byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001 ' play x7
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
byte %000_0000,%111_0111,%000_0111,%111_0000,%110_0001
'color res 1
'bal res 1
'bal_m res 1
'bal_sign res 1
'bal_r res 1
'bal_g res 1
'bal_b res 1
'color_r res 1
'color_g res 1
'color_b res 1
'rgb res 1
x res 1
y res 1
z res 1
t res 1
fit
DAT orgh
framebuffer file "rose.gray"
A computer monitor with HDMI input did not accept this signal. My TV handles it but seems somewhat buggy. It sometime flashes between the P2 signal and my computer signal that is probably still in the screens memory somewhere. It happens at startup and seems to settle down after a few minutes.
Comments
Chip wrote the original code.
A two-cog 640x480x8pp soft HDMI display with palette of 256 out of a possible 4096 colours was worked out last November, however it has not been tested yet. Colour levels are equally spaced but TMDS data are mostly not balanced. 720x480x8pp and sprites should be possible, too. It's questionable how much time should be spent on this, but it would good to get something working now that people have HDMI boards.
Since the new silicon will generate proper signals, I though that using the 52 balanced codewords would be an acceptable trade-off for now. Generating a non-balanced signal may be an acceptable temporary trade-off as well.
Work on HDMI audio wouldn't be wasted. What we write now should work on production silicon with minor changes.
If anyone wants to play with 720p24, here you go!
The rose.gray file used is available here: forums.parallax.com/discussion/comment/1463361/#Comment_1463361
A computer monitor with HDMI input did not accept this signal. My TV handles it but seems somewhat buggy. It sometime flashes between the P2 signal and my computer signal that is probably still in the screens memory somewhere. It happens at startup and seems to settle down after a few minutes.