bubi_00 Posted November 27, 2016 Report Posted November 27, 2016 (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 November 27, 2016 by bubi_00
inmarket Posted November 28, 2016 Report Posted November 28, 2016 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.
bubi_00 Posted November 28, 2016 Author Report Posted November 28, 2016 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!
inmarket Posted November 28, 2016 Report Posted November 28, 2016 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.
bubi_00 Posted November 28, 2016 Author Report Posted November 28, 2016 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
inmarket Posted November 28, 2016 Report Posted November 28, 2016 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.
inmarket Posted November 28, 2016 Report Posted November 28, 2016 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.
bubi_00 Posted November 28, 2016 Author Report Posted November 28, 2016 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.
bubi_00 Posted November 28, 2016 Author Report Posted November 28, 2016 (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 Edited November 28, 2016 by bubi_00
bubi_00 Posted November 28, 2016 Author Report Posted November 28, 2016 (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 November 28, 2016 by bubi_00
inmarket Posted November 29, 2016 Report Posted November 29, 2016 To contribute your driver just attach the driver source files in a zip file to this forum thread. Well done on getting it working
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now