Greyscale bitmap TV driver
ericball
Posts: 774
As I indicated in my blog, I've been working on a 8bpp greyscale bitmap TV driver. It uses PWM to generate output so only 1 pin (and one cog) are required. Horizontal resolution is clockspeed limited, vertical resolution is scaled to fit a specified number of lines. The bigger limitation is HUB RAM.
This is the beta release. It works fine, but the image isn't rock solid for some reason. I'm not sure if it's because I'm not filtering the output or if I have a code error. I have also only tested NTSC.
This is the beta release. It works fine, but the image isn't rock solid for some reason. I'm not sure if it's because I'm not filtering the output or if I have a code error. I have also only tested NTSC.
Comments
PS. The chick in the demo sure is easy on the eyes. I probably would have picked Jessica Alba though, haha
Could it work on VGA - either one pin or multipin?
PS Thanks for reminding me to update the link in the code.
SD card support would be external. From a timing perspective the bitmap must be stored in HUB RAM. It might be possible to load the bitmap ahead of the driver, but that's a challenge for someone else.
The lady in the picture has historical significance, follow the link in the code.
Great work ericball, as always!
Ok, brainstorming here, many of the boards I am using have 8 pins committed to VGA. I note the link above for the minimum number of pins for B&W VGA. I wonder if there is a compromise solution as well - eg instead of 8 bit resolution, use 6 bit, and then the two other pins are for the synch pins.
I read somewhere that the input impedance of a VGA monitor is about 100 ohms. The video signals carried in VGA connector are designed to be matched to 75 ohm load and use coaxial cable. But does anyone know the impedance of a 15-pin VGA connector? I can assure you it is NOT exactly 75 ohms, nor is it coaxial. In reality the impedance of the VGA connection is about 100 ohms and it would be more suitable for carrying differential twisted pair signals than coaxial video signals. from http://www.epanorama.net/faq/vga2rgb/basics.html
Some options that might be possible:
1) 6 resistors, carefully calculated to do a D to A and to match the 100R impedance and driving, say, the green pin only.
2) A R/2R network, also matched, and driving the green pin.
3) The above 1 or 2, with an op amp buffer. At unity gain, I think a 741 has the required bandwidth, but it would need a negative supply to swing to zero volts. A CA3140 might be a better option as it can swing rail to rail.
4) The above, 1,2 or 3, and driving R G and B, so as to provide black and white rather than black and green.
I'm thinking that if something like this was working, one could switch between color lo res and grayscale hi res using a jumper. Or even under software control (using another pin or, my preference, using one of multiple spare output pins from generic I/O latches).
Thoughts would be most appreciated.
My little project at the moment is to move the entire program into external memory, freeing up the bottom 2k of hub ram as a buffer for loading cogs, and the rest of hub ram for a video buffer. Boot up into high res text vga white on blue, wipe those cogs and load in the full color palette driver, wipe those cogs then load in this grayscale driver. I don't think Spin can do that, but I'm pretty sure Catalina can.
@Ahle2, Are you sure? I mean, you are from Sweden, and Lenna is from.... Sweden??
Okey, so I lied. .... but Sweden is a small country and she is "only" five years younger than my mother.
Hey, nice driver and nice avatar!
Re: Aspect ratio. If it were me, I would just use some nice graphics program. GIMP will do this nicely enough, resizing, and using filtering / blending to average out the pixellation. I like to do a even multiple of the original resolution, then crop to size, choosing the best part of the image.
If a different multiplier is desired, be sure and use a program that has advanced pixel blending. A simple linear interpolate will look kind of crappy.
As far as taking a picture and converting it, you first want to covert it to greyscale, then resize it (130x480 at 80MHz is approximately 4:3), and save it as ASCII PGM. ASCII PGM is a simple format with the P2 header followed by the number of colulmns, rows, and levels followed by a list of pixels all in decimal format separated by spaces and newlines. Lines starting with # are comments.
thanks for this very nice driver, nearly a sneak peek on prop II video DACs :-)
I've tried to hack it to get 16 cycle pixels, 256x192 at 4bpp.
It's not kosher since I'm bypassing the level LUT, But it seems to work on my TV.
Also, the image require a little massaging to be displayed.
Ciao
Alessandro
Very interesting and well done. Yes, you would need to rescale the data so 4 or 5 is black and F is white, so effectively only 12 or 13 levels of grey. But that's not a bad compromise since with my driver even with 8bpp you're not getting 256 levels anyway as there's only 32 clocks for the PWM.
I fired both of these up and am very impressed. Great work, thanks.
tubular
Tubular, thanks but I'm not even remotely able to write a video driver... so 99.999% of the credit goes to The Master: you need a 8bpp chunky pixel first, before you can split it in two :-D
In case anyone is interested:
I'm converting the pics using photoshop: resize to 256x192, transform to indexed color and select a custom gradient grayscale palette, add some dithering, and at last save as bmp and check "flip row order" option.
If you want to create a raw pic for direct inclusion into spin, just shave off the header from the bmp: this can be done in linux with "tail --bytes 24576 infile.bmp >outfile.raw", or with some similar tool for windows (e.g. if you have cygwin environment installed).
Obviously the same is applicable for 130x192-8bpp images, just use the full grayscale gradient.
@Eric
just added SD loading to the hacked variant: I'd be more inclined to keep it here since the mod is marginal, but I don't want to hijack the thread... do you want me to start another one?
Regards
Alessandro
And it's not a marginal modification, you had to do some significant fiddling to get the clocks to line up correctly.
meanwhile I added back 8bpp, and the demo is now a slideshow with RAW and BMP support.
Size options are a bit limited, but having images prescaled to final size helps to bring in the dithering, to a better final effect.
Sorry if I didn't add proper comments, and no error management, but I'm in a hurry to pack my bags for holydays :-)
Regards
Alessandro
PS: to anybody trying the demos, I'm using a 1nF cap on the output, if you're using the OBC style "reversable" (or similar) TV-adapter, I strongly suggest to add it! (experiment with value, 100pF to 1nF should be good and not adding too much blur)