P2 DVI/VGA driver

1356

Comments

  • rogloh wrote: »
    I think if you build a dedicated board you can design it right, but for people already using the direct P2-EVAL breakout using Parallax supplied Digital Video Out board without resistors, perhaps this float/1.5k setting is okay, OR if it varies from cable/setup we can try the BITDAC approach.

    I felt rather uneasy about having the direct 0V drive down and 3.3V drive up approach I'd been using myself in my driver (so I went and released it with the 1.5k drive coded in for high and low) but perhaps with the 50 ohm termination in the DVI/HDMI receiver it shouldn't ever be a dead short. This float up and 1.5k pull down seems safe(ish?) if it also works for other people. We sort of need people to try it out to see if it works.

    Alternatively the BITDAC level version might be a more universal/well constrained solution to be used with the Digital Video Out board.

    If the outputs are 3.3V/0V CMOS then an external 270 ohm series resistor at each output will emulate a CML transmitter, which is open-collector so floating high is not a problem. 1.5k seems a very large pull-down, compared to the 50 ohm pull-ups in the receiver. Is it possible to measure the voltage carefully across a differential pair somewhere in BITDAC mode when the receiver is switched on? This should eliminate the guesswork about internal and pin resistances.
  • roglohrogloh Posts: 1,927
    edited 2019-11-23 - 03:48:34
    A BITDAC mode may not need the resistor if the P2 is already internally using 123 ohms. I am assuming we can use the BITDAC to set the DC level output from 0-3.3V in 3.3V/15 increments. I would think this allows us the range to develop the 400mV to 600mV swing across the termination resistor in the receiver fairly accurately, however reflections might become an issue if the impedance doesn't match the transmission line when we switch between high and low. To get it to match you might have to have a parallel resistance too.

    A raw GPIO mode (~20 ohms in the P2) could use a series resistor to help limit the current, because it appears that simply grounding it via 20 ohms is too high a current for the swing we want, and this extra resistor it could help absorb any reflections if it matches the impedance. You should still be able to use the float high case I think (it looks like CML is designed with that in mind) but driving it up to 3.3V as well is probably ok if the impedance matches.

    I'm happy that float high and pull low via 1.5k works in my setup (it seems pretty safe) but this may only be because the LCD monitor's CML receiver is far more sensitive than the specs require.

  • Cross posted with TonyB_. Yes 1.5k is a large pull down and I don't think it would work in all cases.
  • TonyB_TonyB_ Posts: 1,415
    edited 2019-11-23 - 03:59:55
    On the face of things, BITDAC mode using 3.3V & 1.32V (steps 15 & 6) would give ~500mV at the receiver, with no external resistors, if that is safe to try.
  • TonyB_ wrote: »
    On the face of things, BITDAC mode using 3.3V & 1.32V (steps 15 & 6) would give ~500mV at the receiver, with no external resistors, if that is safe to try.

    Yes, I think that would be okay.

    I just tried it with BITDAC HHHH_LLLL set to 1111_0110 it looks okay, no sparkling pixels.

    Also tried with 1111_0111 and that was good too. They both should fall within the 400-600mV range I think (from a DC standpoint anyway).

  • roglohrogloh Posts: 1,927
    edited 2019-11-23 - 04:12:04
    For anyone using my driver these are the source code lines you would change to try these ideas out...

    Change this line in p2videodrv.spin2
    wrpin  ##%001001<<8, a          'uncomment for full drive output
    
    to this for float high pull low with 1.5k
    wrpin  ##%111001<<8, a          '1.5k pull down, float high
    
    or replace with this for BITDAC
    wrpin   ##%10110_1111_0110_10_00000_0, a  '123 ohm BITDAC for pins
    
  • All of them work on my current HDMI screen. Will test some others when I travel again after the holidays.

  • Great!
  • roglohrogloh Posts: 1,927
    edited 2020-01-11 - 04:34:23
    I just found a bug in my current video driver code affecting interlacing with region wrap in graphics modes.

    To fix it in your codebase just change this line in the "newregion" routine...
                if_z            incmod  rowscan, rowheight wz
    
    to this
                if_z_and_nc     incmod  rowscan, rowheight wz
    

    I will add the fix to the next release.

    I am also seeing some weirdness with region wrapping in the text mode, as it is meant to start a new text row at the wrapped scan line in the region but instead seems to continue on from the same scan line row offset in the font it left off with. The row number is also not being incremented correctly in all cases and this can affect the cursor size at the wrapping point on the screen. I know I did still have some issues with some tricky line doubling, interlacing and wrapping combinations and some of it may require wrapping on even scan line boundaries. Hopefully any fixes I decide to add there will fit in the remaining longs left free for my bug fixes... :worried:
  • roglohrogloh Posts: 1,927
    edited 2020-01-13 - 05:04:22
    I think I found a fix for the remaining text region wrap issues, and I'm testing it out. It looks like the fix needs to use up 3 more longs and after my last PAL CQ colour flip changes I put into the code I think there were only 2 longs left in the COG. Thankfully today I found a way to free up 4 more longs in the code (2 very quickly which I already did in order to test this fix, and a further 2 more are possible with a bit more work in rearranging some lookup table data).

    With any luck the solution I've found now solves the combinations of interlaced/line doubling with odd/even scan line wrap points in the text region, so there shouldn't be any restrictions. After the wrap point in the region the font starts at row offset 0 and the row number increments by one from the previous screen row, so the cursor looks good again. So far it seems okay in VGA but it's rather flickery in interlaced mode and I need to prove it out on a proper interlaced monitor to make sure it looks good there too.

    However when testing this fix I did find that for some reason none of my SD/HD TV video output modes are working - this could be a simple software setup/timing issue in the test code or I might have introduced a regression somewhere in the driver. :cold_sweat: Now need to figure that out too.

    Update: I posted too soon, there seems to still be an issue with line doubling enabled and wrapping on odd boundary offsets in text regions, which leaves a single pixel line before the end of the wrap point and at the start of the wrapped region if the wrap scan line count is an odd number. I can't easily fix this without breaking the mouse calculations or adding even more new code and state to adjust scan line counters. I think if we are line doubling we should just expect to have to set the wrap boundary on an even number of scanlines in a region for things to make sense visually. In most cases the wrap point in a text mode region would be setup at the end of a complete font row anyway, certainly if you are using wrapping to enable high speed vertical text scroll without block copying, which is probably one of its main benefits. Apart from split screen text region effects the only other purpose of supporting wrapping with text is to hide the last screen row if it doesn't fit the remaining scan lines on the screen because you can point that final excess portion to a different memory buffer just containing blanks.

    Update2: l found the issue with my other TV output modes. I had left a line controlling custom timing commented out in the driver setup code during a recent test. I restored that init code and my analog TV modes are working again.
  • I've been working on the driver fixes and think it is close to another release. I'm just tidying it up a fraction more and also updating the documentation to try to get things in sync. Once that is done soon I'll try to post it, perhaps also with my HyperRAM arbiter that allow it to work with this external memory (though that is a slightly separate effort).

    Here's the summary of the current driver changes for my next release.

    New features:
    - added proper PAL phase alternation for better SDTV PAL colour output
    - activate two mono text mode(s) when p2:pixel clock ratio is low (i.e. mono text only when 2 <= ratio < 5, colour text if ratio >= 5)

    Other changes:
    - made COG driver code memory position independent - useful for MicroPython
    - changed DVI mode pin output to use the P2 BIT DAC output
    - reduced hub data transfers in text mode by making it screen width dependent
    - optimized region init code to save more instructions
    - set default to VGA timing not SVGA when no timing passed
    - enabled optional extra front porch in interlaced TV modes
    - handled more odd clock count cases in analog TV mode timing computations
    - added external memory driver to the SPIN2 API
    - optimized CQ/CI/CY parameter order for PAL and added CQ flip xor parameter
    - added further comments to the code

    Bug fixes:
    - fixed pin group bug in setup code affecting pixel output
    - fixed rowscan offset after region wrap in text mode
    - fixed bug with interlacing after region wrap in gfx mode
    - fixed bug with external memory use affecting scan line buffer alternation
    - fixed bug with cursor1 and cursor2 register offsets in COGRAM
    - fixed bug in SPIN2 API for cursor initialization
  • Any chance you could point me to the old code/docs so I can get a jump on learning these things? I’m working my way through a stack of posts in several threads but I’m not seeing a recent code bundle.

    As an interim question: does your driver support some of the low-end modes such as 800x600x16 color analog VGA mode? Much of what I do needs analog VGA/Svga text-only output but not many colors for a basic textual HMI. I know this is sort of like driving a Ferrari in a crowded parking lot, but... :)
  • Hi JRoark. The first post in this thread contains a zip file containing the initial driver (beta) release and its documentation which is the last one I've posted.

    Yes the driver certainly supports this 800x600x16 colour resolution with analog VGA outputs. For graphics only you can probably run it as low as 2x pixel clock (so 80MHz for SVGA), but for a 16 colour text mode the P2 would need to be clocked higher. Currently for text you'd need 4-5x for SVGA I think, so setup a 200MHz P2 to be safe. Soon you'll be able to use mono text with the P2 down as low as a 2x pixel clock.

    If you wanted just transparent passthrough graphics frame buffer data read from HUB RAM (i.e. no mouse, text or pixel doubling features from the driver) you could probably get it to run with a P2 as low as 40MHz for typical SVGA timing.
  • Thank you! This is some awesome stuff @rogloh !
  • @rogloh I'm 8 hours in to playing with your video driver. This thing is a work of art. ROCK SOLID. Just... wow!
  • roglohrogloh Posts: 1,927
    edited 2020-01-19 - 22:28:17
    Thanks JRoark. Yeah I think the first beta is pretty solid. Haven't seem any real crashes in all my own tests, it's just a few minor bug fixes so far really. The only thing that can affect things is if you push it too hard by shrinking sync timing too far or trying to do too many things like enable a mouse, borders or pixel doubling in 24bpp mode while the P2 clock speed is too low to support that particular processing workload in the scan line time. At that point the video output can obviously be corrupted and/or a monitor can fail to sync but the code will still run, nothing typically locks up. If you go past what can reliably be output in any cycle budget, just drive the P2 clock higher or reduce the resolution if you can. It's nice and scalable in its abilities.

    If you like it so far you should see what is really possible with this driver and the external memory stuff coming next. That opens up some decent frame buffer sizes for the P2. :smile: Also this current driver architecture should enable sprite drivers tapping into it too - I plan to make something there at some point, but others could easily do so as well.
  • It is a darn-Skippy sweet bit of kit indeed!

    You’ll be repulsed, but I have a confession. I’m cannablizing it already, trying to make it a completely self-contained “engine” so I can use it from FlexBASIC. Right now it needs buffers, font files, and stuff like that declared externally and then passed to it so it can init and run. I want all of that stuff internal/local to the driver so the only interfaces to it are things like “print this string”, “put the cursor here”, etc.

    So far I’ve managed to break it rather spectacularly... but admittedly that’s half the fun. :) I’ve managed a few simple methods (clear screen, locate cursor @ x/y, set fg/bg colors, etc) but I really just need to print your code out and get away from the machine for a bit so I’m not tempted to tweak before I have a better understanding of your code.

    Well done, Rogloh!
  • Yeah each P2 environment sort of needs its own appropriate way to bundle/package the driver COG appropriately with an API etc. Right now it is all controlled via HUB data structures so it is very generic and language agnostic.

    I have only done a simple demo API so far for Fastspin's SPIN2, and tried some simple tests including it with MicroPython. It would be handy to put together something with a C interface at some point to enable that language and obviously something for official Parallax SPIN2 when that is available.

    I know Peter Jakacki was interested in using this with his Forth too, and now you with FlexBASIC. It should be possible for any P2 environment to make use of this COG in the end. I certainly don't plan to try to mandate any API, people can just add whatever they want on top to suit their needs. It's just the hub data structures this video driver uses in the end that control it. I'm planning to keep these mostly static but they still could extended from release to release as additional output interfaces are added, for example LCD's or CGA or HDMI etc. So if you ever pickup a new release you may still need to re-validate your code or check for changes there. I'm trying to get the new release out soon with the bug fixes (probably only bugs 1 and 5 in the list of changes posted above are the main ones that may affect you).

    Enjoy it.


  • One thing that is needed to make a standalone system, aside from a good video driver, is a FAT system for the 16MB flash chip. It would be really cool to be able to call routines to read and write files.
  • roglohrogloh Posts: 1,927
    edited 2020-01-20 - 05:20:32
    Yes a local FAT or other flash filesystem will be very handy. I think in some cases it might become extravagant to allocate a standalone COG to manage it like we need to with video, so longer term it could be coded in the language of choice and just called synchronously by the client, perhaps in a hub exec mode. That being said I'd be very happy to see and use a dedicated COG for hosting a filesystem from flash in the short term if someone developed one that was solid. The SD card is the other option for FAT but that comes with its own variabilities and is also removable which can be both good and bad.
  • To drive FAT32 on FLASH is not that difficult.

    Only the low level SD routines for Initialisation, plus Read and Write sector routines would need to change (and of course their lower level routines). The CSD/CID routine would need to be trapped as they are specific to SD IIRC.
    All the top level FAT routines would remain the same.

    IIRC there are a couple of locks that are read/written on the SD card. These could cause wear levelling problems.
  • check out littlefs. Its designed for just this kind of thing.
  • JRoarkJRoark Posts: 337
    edited 2020-01-20 - 19:02:47
    I'm turning into a serious @rogloh fanboy. This is 1920x1200 mode (DVI) into a 24 inch ASUS monitor. This is 240 characters by 75 lines. Crystal clear. Perfectly stable. Prop2 dev board for scale. (With a dangling DS3231 RTC off the side. Oops. You didn't see that)

    Just... WOW!

    EDIT: I thought it was maxxed-out at 240x75 text. Wrong. It will do 240 x 150 chars using the EGA14 font at 1920x1200 resolution.
    4032 x 3024 - 5M
  • Being able to display huge amounts of text makes programming very nice. Less to spool in your head.
  • Looks great!
    I've had 240x128 on 1920x1024 Acer 24" monitor on the RevA boards at 148.5MHz using VGA. Not a true terminal program, just the display of fixed characters using 8x8 font. Looed great after I got rid of the shimmering effect.
  • roglohrogloh Posts: 1,927
    edited 2020-01-20 - 23:18:56
    LOL. If you want the highest resolution text @JRoark , with the next release version you can do mono text with the P2 as low as a 2x pixel clock. This enables 240x200 with a 6 line font on 1920x1200 monitors at 60Hz. I posted these images earlier in my other discussion thread a little while ago if you've not seen it...

    https://forums.parallax.com/discussion/comment/1485247/#Comment_1485247

    This is probably about the practical readable limit the driver can hit, though you could always try shrinking the font height more if you only wanted to output non-alphabetic characters or other tiny symbols.

    Also with its HyperRAM external memory driver interface you'll eventually be able to do this sort of thing too if you've not seen this either...multiple COGs can access the same HyperRAM and draw graphics dynamically while the video COG uses it as a frame buffer.

    https://forums.parallax.com/discussion/comment/1485242/#Comment_1485242

    I need to get back to work on that again. It already somewhat works nicely at some resolutions but I need to tidy it up a bit and attempt the 4us fragment transfers to avoid refresh corruption issues that creep in when the memory is starved of refresh at higher resolutions.
  • @JRoark , just noticed something in your post above, you are using the DVI breakout board. Do you know what vertical refresh you had in the picture above and what P2 clock rate worked with that hires text output resolution? If you use DVI the driver requires the P2 to operate at a 10x pixel clock. So for 1920x1200 output the vertical refresh would have had to be very much less than 60Hz to allow it to work. What can your monitor achieve? My Dell 2405 only likes its VSYNC frequency to be > 50 Hz (though works down to around ~48Hz or so I think in practice IIRC). Yours would appear to work at something around 10-15Hz or so at this resolution, depending on your P2 clock rate and reduced blanking etc. What timing did you apply?
  • @rogloh I have to admit I am not manually setting any clock speeds! Your driver does it all. In that picture I am using your simple demo program and feeding it my own text file with just a couple of params (VGA/DVI, linebuffer, screensize, etc) tweaked.

    When I get back to my bench I’ll see what speed the Prop is running at. I’m curious too.

    That monitor has aptly handled every oddball mode I have thrown at it. Its 4 years old now, but was kind of expensive when I bought it. It wouldnt surprise me to find that its working down that low.
  • JRoarkJRoark Posts: 337
    edited 2020-01-21 - 15:27:06
    @rogloh Ok! We have data... and I lied... and an oddity!

    Data:
    The P2 clock speed for what the driver calls "1920x1200" in DVI mode is 308 mhz.

    I Lied:
    Turns out the monitor is a 28 inch, not a 24 inch. My bad. It's an ASUS PB287Q (4K UHD (3840 x 2160) display with 1ms response time and 60Hz refresh rate. I'm still looking for a specific list of the various modes/refresh capabilities, but the spec says "24 ~99 KHz (H) / 30 ~75 Hz (V)".

    The Oddity:
    By my math, 1920x1200 using the "font6" font file should give us 240 cols by 200 rows of text. But see the picture. :) I can fit *210* rows on-screen. It isn't scrolling. It all fits.

    The only parts of your DEMO.SPIN2 code that I'm manipulating are:
    	LINEBUFSIZE = 240*4 	' for VID#RES_1920x1200 
    	SCREENSIZE = 240*200	' for VID#RES_1920x1200  
     	timing := vid.getTiming(VID#RES_1920x1200)	
    	vid.initDisplay(@display, VID#DVI, VGA_BASE_PIN, VGA_VSYNC_PIN, VID#RGBHV, @lineBuffer1, LINEBUFSIZE, timing)
    fontvga16   file    "font6"	
    features	            file    "240x200.txt"
    

    Everything else is box-stock-Rogloh.

    EDIT: I went ahead and added the CPU speeds to a table I had been developing. In the process of this I discovered there seem to be multiple cases where the expected character row counts do not match what the driver actually produces. This only happens on the higher resolutions. See the table below:
    ' Display		Text													CPU	???
    'Resolution		Col/Row	Fontname	Mult		DVI	EGA	MHZ	Notes
    '---------------------------------------------------------------------------------
    '	640x350		80x22	fontvga16	16		YES	YES	252
    '	640x350		80x25	fontvga14	14		YES	YES	252
    '	640x350		80x43	fontcga8	8		YES	YES	252
    '	640x350		80x58	font6		6		YES	YES	252
    '
    '	640x480		80x30	fontvga16	16		YES	YES	252			
    '	640x480		80x34	fontvga14	14		YES	YES	252
    '	640x480		80x60	fontcga8	8		YES	YES	252
    '	640x480		80x80	font6		6		YES	YES	252
    '
    '	800x600		100x37	fontvga16	16		YES	NO	240		
    '	800x600		100x43	fontega14	14		YES	NO	240	
    '	800x600		100x75	fontcga8	8		YES	NO	240
    '	800x600		100x100	font6		6		YES	NO	240
    '
    '	1024x768	128x48	fontvga16	16		YES	YES	325			
    '	1024x768	128x55	fontega14	14		YES	YES	325		
    '	1024x768	128x96	fontcga8	8		YES	YES	325				
    '	1024x768	128x128	font6		6		YES	YES	325	
    '
    '	1280x1024	160x64	fontvga16	16		YES	NO	325
    '	1280x1024	160x73	fontega14	14		YES	NO	325
    '	1280x1024	160x128	fontcga8	8		YES	NO	325	
    '	1280x1024	160x160	font6		6		YES	NO	325	
    '
    '	1920x1080	240x67	fontvga16	16		YES	NO	297					
    '	1920x1080	240x77	fontega14	14		YES	NO	297			
    '	1920x1080	240x135	fontcga8	8		YES	NO	297	*145 rows					
    '	1920x1080	240x180	font6		6		YES	NO	297	*190 rows		
    '
    '	1920x1200	240x75	fontvga16	16		YES	NO	308				
    '	1920x1200	240x85	fontega14	14		YES	NO	308	*96 rows			
    '	1920x1200	240x150	fontcga8	8		YES	NO	308	*160 rows					
    '	1920x1200	240x200	font6		6		YES	NO	308	*210 rows				
    '---------------------------------------------------------------------------------
    

    See the 2 pictures attached. I included the pic of the left screen margin so you can see I'm not cheating on the numbering. Sharpie for scale.
    4032 x 3024 - 5M
    3024 x 4032 - 5M
  • Man, that's like microfiche. If you can get 200 rows in landscape, you could get 320 rows in portrait mode. Seeing lots of code at once is like high-def for your programming mind.
Sign In or Register to comment.