Close

Drawing (badly) to VGA Monitor!

A project log for RA8875 VGA

Let's use a LCD driver to drive a VGA monitor. It sounds fun.

dylan-brophyDylan Brophy 08/14/2024 at 04:010 Comments

So, my design idea WILL work!  I did have my doubts, but it turns out it will actually work.  Here is what it's drawing, which should be text, but clearly isn't:

There is this white strip, which is basically a rectangle where the text should be - like it's filling it.  I don't know exactly why it's doing this yet, but it probably has to do with my setPixel routine, which is used for drawing the font:

void RA8875::setPixel(int x, int y, uint16_t color) {
	// The actual pixel write code doesn't draw anything at all
	/*writeReg16(RA8875_CURH0, x);
	writeReg16(RA8875_CURV0, y);
	writeCommand(RA8875_MRWC);
	writeBytes((char*)&color, 2);*/

	// At least this draws *something*
	fillRect(x, y, x, y, color);
} 

The setPixel should write directly to the display memory, but for some reason the direct write to memory is not working.  So I decided I would try just drawing rectangles to temporarily solve this issue, which clearly didn't work either.  I'm still investigating it, but from the looks of it, the corner of the rectangle is probably always starting at coordinates 0, 0 for some reason.  Here's the related code:

void RA8875::fillRect(int x1, int y1, int x2, int y2, uint16_t color) {

	int x = min(x1, x2);
	int y = min(y1, y2);
	int w = abs(x2 - x1) + 1;
	int h = abs(y2 - y1) + 1;

	// I'm suspicious of 16-bit register numbers not divisible by zero...
	writeReg16(0x91, x);
	writeReg16(0x93, y);
	writeReg16(0x95, w);
	writeReg16(0x97, h);
	writeColor24(color);

	writeReg(RA8875_DCR, 0xB0); // Use 0x90 if you just want to draw the edges

	// Wait for the command to finish
	waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS);
} 

Really, none of this seems out of the ordinary other than the odd register numbers.   I'll need to study the datasheet a bit more.

The important part, is that the design fundamentally can work.

The main thing I was missing since last log, was that I didn't turn on the display in my code.  I thought this was just for the LCD backlight driver, but turns out there won't be any color without turning the display "on" either.  I guess that sorta makes sense, although it is strange that it would still send the sync signals without the color data.  Again, here is the relevant code:

writeReg(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPON);

This code was based on Adafruit's RA8875 library, which works great if you are using a SPI interface.  This code also seems related to this repository, and I am not sure how they are related, but it is another good repository to look at for RA8875 driver code, and really any LCD driver - there are a LOT of drivers supported: https://github.com/ZinggJM/GxTFT/blob/master/src/GxCTRL/GxCTRL_RA8875P/GxCTRL_RA8875P.cpp

I integrated ideas from both of these sources, as well as added/modified some of my own.  I felt they both deserve credit, and also are just good reference points for anyone else.  If you are interested in the driver I am writing, the source is here: https://git.nuclaer-servers.com/Nuclaer/ntios-2020/-/blob/cb48037977205ada23a78f7c474f36f2d2665fa2/drivers/graphics/ra8875.cpp

The commit, as of this log, is 14837b6.

Discussions