Jump to content

Custom Color Format RGB 3Bit


Recommended Posts

Posted (edited)

Hello,

I'm trying to port uGFX to a Sharp Memory Display with a framebuffer driver. Driver works OK so far, but i have a problem with the colorformat.
My display only supports 3bit (R1,B1,G1) with MSB first.

with

 gdispGDrawPixel(GDISP,1,0,0x07);

I expect my framebuffer to be 0xE0. 

I have 128x128 pixel and therefor 48bytes per line. I tried to modify the code to support this special format, but without success. I came across a few interesting functions and defines without documentation. gdispPackPixels for example. Any hints how to implement such a case?

 

kind regards

Michael

 

Edited by bubi_00
Posted

There are a couple of ways to do this...

1. Set up uGFX so that it supports your color format directly, or
2. Translate the color format in your driver.

To get uGFX to support your color format directly you need to look at src/gdisp/gdisp_colors.h

You will see that a color format is composed from a color system eg GDISP_COLORSYSTEM_RGB or GDISP_COLORSYSTEM_BGR and a mask of the necessary info.

eg. RGB565 is made from GDISP_COLORSYSTEM_RGB or'd with 0x565 indicating the number of bits in each color channel.

So, a definition for GDISP_PIXELFORMAT_RGB111 would be (GDISP_COLORSYSTEM_RGB | 0x0111). Adding that one define would enable uGFX to fully support that pixel format. That define could even just be in your gfxconf.h file.

Unfortunately only Grayscale and True color RGB and BGR color systems are supported. RBG is not a supported color system. Adding it would be possible - look around line 258 and make sure your new color system does not conflict with the existing color system values. The same change will also need to be reflected into gdisp_driver.h at around line 846.

The 2nd option relies on using an existing supported pixel format and translating in your driver. This is not unusual or difficult and occurs naturally in a dual display system where the displays have different internal pixel formats. If you look at just about any existing driver you will see that the driver makes use of a function gdispColor2Native(). This translates the user pixel format (as defined by GDISP_PIXELFORMAT) into the driver pixel format (as defined by GDISP_LLD_PIXELFORMAT). Whilst for single display systems these values are equal therefore making gdispColor2Native() effectively an empty function, there is no system requirement for this to be the case. For example, your user code may set GDISP_PIXELFORMAT to RGB888 but the display itself might actually run RGB565.

So putting this together, you could use a supported pixel format at the user level and then manually translate that pixel format in your driver to the format your display actually needs. Because framebuffer bit packing occurs at the driver level you don't need to worry about any of the uGFX packing functions (in fact those functions have never been used and will probably disappear in the future). Pixels are always fed to the driver "unpacked" in user pixel format.

I hope that helps.

Posted

Yes, that helps!

Sorry, its RGB...just a typo :(

I tried already adding my own custom format with RGB111, but I had no success with it. The bitshift was wrong, I got 0x07 (with Pixel at 0,0 with color 0x07)  into my framebuffer, the pixel offset seemed to be wrong. 
I will have a more detailed look into it...but that seems to be the right way for me...thank you!

 

 

Posted

With RGB111 the colors fed to your driver will be 0x00 to 0x07 regardless of its position. I would imagine that you will need to shift that value in your driver depending on its position in the resultant packed framebuffer byte.

ie for (0, 0) packed MSB into the frame buffer that will turn into buf[0] = (buf[0] & 0xE0) | (color << 5)

For (1, 0) it would be buf[0] = (buf[0] & 0x1C) | (color << 2) etc

A lot also depends on if your framebuffer packs across byte boundaries or if it always byte aligns ie 2 pixels per byte and 2 unused bits.

Posted

Yes! That's my problem...
I thought uGFX could handle right pixel position within a byte. I can shift with my custom driver before writing a line to the display, but well...isn't a good solutions in my memory constraint system. 

But to get it right...minimum requirement in uGFX (with RGB) is 1 pixel = 1 byte?

Kind regards
Michael

Posted

No. Framebuffers can be packed however your driver wants to do it. The generic uGFX framebuffer driver however only supports 8, 16 and 32 bit pixels. As an example, many of the monochrome drivers implement their own 1bpp framebuffer.

In your case (assuming a fully packed framebuffer) 8 pixels will get packed into 3 bytes. So...

#define BYTES_PER_LINE		42

ncolor = gdispColor2Native(color);

pos = y * BYTES_PER_LINE + ((x / 8) * 3);
switch(x & 0x07) {
case 0:
	buf[pos+0] = (buf[pos+0] & ~0xE0) | (ncolor << 5);
	break;
case 1:
	buf[pos+0] = (buf[pos+0] & ~0x1C) | (ncolor << 2);
	break;
case 2:
	buf[pos+0] = (buf[pos+0] & ~0x03) | (ncolor >> 1);
	buf[pos+1] = (buf[pos+1] & ~0x80) | ((ncolor & 0x01) << 7)
	break;
....
case 7:
	buf[pos+3] = (buf[pos+3] & ~0x07) | ncolor;
	break;
}

I am sure you can work out the rest of the switch statement or what happens if your display controller only partially packs the framebuffer.

Posted

When you have your driver working please contribute it to the community as that will save the next person having to redevelop it.

Also, from time to time we buy reference hardware so that we can maintain the drivers so if you would like to send us details (model #'s etc) on your display device (or even better an actual display), we can ensure that the driver is maintained into the future. 

Posted

Ok thanks for your help! I will implement a working prototype driver...but I don't think it will be very useful nor in a good shape. I'm hardware developer and no software guru :) 
I will release the code here as soon as I can.
 

Posted (edited)

I modified the framebuffer driver to support this special case as you suggested.

		#if GDISP_DRIVER_3BIT_MSB
			color = gdispColor2Native(g->p.color);
			fb = ((fbPriv *)g->priv)->fbi.pixels;
			
			x = g->p.x;
			y = g->p.y;
			pos = y * (((fbPriv *)g->priv)->fbi.linelen) + ((x * 3) / 8) ;

			switch (g->p.x & 0x07){
				case 0: 
					fb[pos] = ((fb[pos] & ~0xE0) | color << 5);
					break;
				case 1:
					fb[pos] = ((fb[pos] & ~0x1C) | color << 2);
					break;
				case 2:
					fb[pos]   = ((fb[pos] & ~0x03) | color >> 1);
					fb[pos+1] = ((fb[pos+1] & ~0x80) | (color & 0x01) << 7);
					break;
				case 3: 
					fb[pos] = ((fb[pos] & ~0x70) | color << 4);
					break;
				case 4:
					fb[pos] = ((fb[pos] & ~0x0E) | color << 1);
					break;
				case 5:
					fb[pos]   = ((fb[pos] & ~0x01) | color >> 2);
					fb[pos+1] = ((fb[pos+1] & ~0xC0) | (color & 0x03) << 6);
					break;
				case 6:
					fb[pos] = ((fb[pos] & ~0x30) | color << 3);
					break;
				case 7:
					fb[pos] = ((fb[pos] & ~0x7) | color );
					break;		
			}		
		#else

 

Well...close one :)

 

gdispGDrawPixel works all over the screen...

gdispGDrawBox(GDISP,20,20,80,80,0x07); --- works
gdispGDrawBox(GDISP,10,10,100,100,0x07); --- small errors
gdispGDrawBox(GDISP,1,1,50,50,0x07); --- big errors
gdispGFillArea(GDISP,20,20,100,50,0x07); ---- complete fail :)

I'm not quiet sure what's happening here...maybe you have an idea?!

PS: added the uGFX logo 

 

 

 

 

 

20161128_195340.jpg

20161128_195407.jpg

20161128_195426.jpg

20161128_195551.jpg

20161128_201130.jpg

Edited by bubi_00
Posted (edited)

Ok...I should stop doing things after a hard working day...Made an mistake in my spi init sequence...typo..-.-
well..works now :)

Thanks for your help...

I could constribute a framebuffer driver whent it's ready for a Sharp  LS013B7DH06  on a TI 430-BOOST96 Board... (ok..it's close to your code anyway :) 
Now, I will start to play around with uGFX ;) keep up your work..

 

Edited by bubi_00

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...