|Home > Electronics > Video2||Last Updated: 07/08/2004|
HardwareMicrocontroller: Microchip PICLF4220
Program Memory: 4K bytes (2K instructions)
RAM: 512 bytes
EEPROM: 256 bytes
Address lines: 15
Data lnes: 8
PIC microcontroller integrated with SRAM
The primary motivation in moving video RAM out of the PIC microcontroller
is to increase the potential screen resolution.
Since each pixel comes from SRAM, computation in the microcontroller
simply becomes a memory address increment.
This approach yields one byte per pixel. I will initially just use one bit per color for testing - which is 8 colors (23). Since a full byte is available, I hope to expand this to 256 colors. The odd thing is that 8 is an even number and doesn't divide by 3 "nicely". What I am hoping will work out is to divide the bits up into XYRRGGBB. "XY" will be prepended to each color pixel - giving XYRR for red, XYGG for green, and XYBB for blue.
The SRAM, being 32K in size, has an address bus of 15 bits. Using 8 bits for horizontal resolution leaves 7 bits, or 128 lines, for vertical resolution.
The ultimate goal: achieve approximately 250 x 120 pixels.
The PIC pinouts are as follows:
App. Note TB011
v1 - 20031007 - Memory Test
Never having worked with SRAM, I decided the best approach was to simply try to read and write memory. Fortunately, Microchip has an article that describes how to work with SRAM and a PIC16 microcontroller. This application first turns on two leds and then turns off one of them to indicate status. There is a commented block of code that should also force the memory test to fail. The intention is to have it succeed, re-program the microcontroller, and then re-run the test and have it fail.
v1b - Include video routines
I initialy tried to tack the video routines directly in with the test. This didn't work at all, of course. No video signal what-so-ever, so my timing must have been really out of whack. I didn't keep any code or anything!
VGA timing information
v2 - 20031011 - Stripe Test
Not being sure what went wrong, I removed the SRAM from the equation. The memory increment was changed from the address lines to the databus, which created the pattern seen in the picture. By simplifying the equation, I was able to solve my timing and programming issues.
As usual, I measured the Hsync pulse with a borrowed multimeter. It measured 31.44 - so I was within range!
The last piece of this test was to check horizontal resolution - and it appears that 240 pixels across is possible!
v3 - 20031014 - Vertical height check
As usual, somebody else pointed out the obvious: The VGA spec includes a 640x480 mode which would allow me to achieve 120 lines of resolution instead of 100. After some quick code switches, I generated this picture to "prove" that 120 vertical lines are possible. (Note that vertical timing really isn't the issue - horizontal timing is the driver.)
v4 - 20031021 - First working version with SRAM?
Wow. I think this thing is working! I copied (literally) the setup code from the memory test, made a few modifications in the form of setting an error LED, and the memory tests ran just fine. I then made the quick modifications to the VGA video driver, and it appeared to work! The first version had a vertical pattern - and I didn't quite believe it.
I then modified the setup to write the line (Y coordinate) instead of the column (X coordinate) to generate a straight line pattern. When I stuck the chip in, I think the memory test failed. The wrong LED went on, but the lack of activity with Hsync and Vsync was quite apparante. I didn't even bother to check frequency of Hsync.
So, what's a good hack to do? Why, remove the memory test and see if it works anyway. And, it did!
There are some items to fix up:
VGA timing information
v5 - 20031028 - SRAM controlled video
It most definately works! In general terms, the design works well as designed. I achieved my goal and a bit better - 255x120 pixels. I think the "extra" pixels are actually stolen from the front and/or back porch area (see the VGA timing information resource for more information). Additionally, I found better ways to optimize the code... actually, this code is pretty messy, so I'll clean it up in a later version.
The first design issue that I realized during this phase: I need to be able to disconnect the databus from the RGB lines leading into the monitor. Why? That will either leave random dots on the screen if the monitor is drawing in a visible section of the monitor. Or something funky will happen - for instance, I had some issues with the timing of what I was drawing. It appeared that pixels begin drawn outside of the active video area would cause the monitor to actually *not* draw pieces of the image. It certainly could have been something else, but it did appear that if drawing pixels went too far to the left, colors would drop out - for instance, the purple lines would disappear. Same code setting up the drawing but they didn't appear. As I commented out one line at a time, I would get to a point where everything came back to where it shoudl be. Weird, but once I figured that out, it all came together quickly.
The second design issue is more of a software issue. My code to steal the high address bit and slap it onto a different pin appears to be incorrect. The memory tests wouldn't catch a non-functioning address line. I settled on using 7 pins from PORTC - which removed any possibility of connecting serially. The PIC chips multiplex MSSP/SPI/I2C and the UART on this one port and they cannot be reassigned. I need to revisit this soon!
An early application experimenting serial communication and sprites
It's time to try a (somewhat) practical application! I think I've taken this particular design to its conclusion without adding more components. Check the video future section if you're curious about other thoughts I have.
Contrary to what it appears - my ultimate goal is to use the video within a homebuilt 65xx computer. I don't quite think I'm where I want to be for the computer, and yet I'd really like to have something to show for the work done thus far. I guess I'm a bit impatient.
I've included a simplified circuit diagram indicating design. This is still microcontroller-based, so I'm using another PIC chip. I'll use this second PIC chip as the real-world interface. The joystick is a spare arcade joystick (4-way, not analog) I happen to have along with two spare buttons. Both PIC chips sport a USART - so I'll use this as the communication mechanism. I don't really know what impact this will have on the video controller itself, but I hope it's not too painful!
The sample applications that I have chosen are:
What does this accomplish? Quite a number of things, actually:
Status as of 2004
Project was terminated around December 2003. I was unable to resolve some basic communication issues and then Christmas intervened. We needed the dining room table for Christmas dinner and I needed to pickup. )c:
I have no pictures... the code is somewhere in CVS, so it's not lost. As I remember, my impression was that my serial communication was interfering with the timing of my video interrupts. I'm sure someone more experienced could have resolved it - given enough time and will-power, I could have too, I imagine.
The good news - I have my new laptop, a workspace in the basement (yup, just me and the mice that hide down there), and there is a design for Video3 laying around somewhere!
For those that don't use source code control: I was missing it sorely and finally realized that I had it right under my nose. I use Eclipse for my Java development and have a Linux server that acts as my CVS repository. I started using TortoiseCVS for managing the files, and I find it works very nicely. Since it's integrated into Explorer, it is always available. Works beautifully with MPLAB and Eclipse can pull in the archives too, so I can exchange between tools without them getting into some sort of fistfight.