1

Good afternoon,

I'm trying to programmatically display an image to a 3.5 inch TFT display mounted on /dev/fb1 using the following code:

Using trial and error I determined the pixel width to be 16 bits. This would mean the color palette is either stored in a 565 or a 555+1 format

When I run the code below, I get a correct image, but it is very blue. If I swap around the colors, it still comes out very blue

And if I uncomment Red, Blue, and Green here:

 //red_in =  255;
 //blue_in = 0;
 //green_in = 0;

I get a very faint red or green color, almost black, but the blue is still many times more vivid.

I know it's not the display, because it shows vividly all colors on the Linux splash screen. It must be the formatting of the pixels.

Does anyone know specifically how the color palette is stored on the raspbian framebuffer?

Thanks,

const int display_width  = 480;
const int display_height  = 320;    
struct fb_var_screeninfo screen_info;
struct fb_fix_screeninfo fixed_info;
unsigned char *fbp_2 = NULL;
ssize_t buflen;
int fd = -1;
int r = 1;
fd = open("/dev/fb1", O_RDWR);
if (fd < 0)
{
    if (ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) || ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info))
        return 0;

    buflen = screen_info.yres_virtual * fixed_info.line_length;
    fbp_2 = reinterpret_cast<unsigned char*>(mmap(NULL, buflen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
} 

if (fbp_2 != NULL)
{
    int location_display;
    uint8_t red_in, blue_in, green_in;
    uint16_t color_out;
    for (float y = 0; y < display_height; y++)
    {
        for (float x = 0; x < display_width; x++)
        {
            int x_cam = (int)(x * x_scale); 
            int y_cam = (int)(y * y_scale);
            location_cam = (x_cam) * (3) + y_cam * cam_width * 3;
            location_display = x * 2 + y * display_width * 2;
            red_in =   *(fbp + location_cam);
            blue_in =  *(fbp + location_cam + 1);
            green_in = *(fbp + location_cam + 2);
            //red_in =  255;
            //blue_in = 0;
            //green_in = 0;
            color_out = ((red_in >> 3) << 10) | ((green_in >> 3) << 5) | ((blue_in >> 3));

            *(fbp_2 + location_display) = color_out;
        }
    }

}
1
  • The framebuffer format is defined by the LCD driver. Which one do you use? Oct 19, 2018 at 9:08

1 Answer 1

1

Looks like the unsigned char pointer was actually casting to unsigned char and thus truncating the data to only 8 bits, 5 of which were blue, and 3 were least significant bits of green.

Fixed by changing unsigned char *fbp_2 = NULL; to

uint16_t *fbp_2 = NULL;

and

color_out = ((red_in >> 3) << 10) | ((green_in >> 3) << 5) | ((blue_in >> 3));

to

color_out = ((red_in >> 3) << 11 ) | ((green_in >> 2) << 5 ) | ((blue_in >> 3));

new code below

const int display_width  = 480;
const int display_height  = 320;    
struct fb_var_screeninfo screen_info;
struct fb_fix_screeninfo fixed_info;
uint16_t *fbp_2 = NULL;
ssize_t buflen;
int fd = -1;
int r = 1;
fd = open("/dev/fb1", O_RDWR);
if (fd < 0)
{
    if (ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) || ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info))
        return 0;

    buflen = screen_info.yres_virtual * fixed_info.line_length;
    fbp_2 = reinterpret_cast<uint16_t*>(mmap(NULL, buflen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
} 

if (fbp_2 != NULL)
{
    int location_display;
    uint8_t red_in, blue_in, green_in;
    uint16_t color_out;
    for (float y = 0; y < display_height; y++)
    {
        for (float x = 0; x < display_width; x++)
        {
            int x_cam = (int)(x * x_scale); 
            int y_cam = (int)(y * y_scale);
            location_cam = (x_cam) * (3) + y_cam * cam_width * 3;
            location_display = x * 2 + y * display_width * 2;
            red_in =   *(fbp + location_cam);
            blue_in =  *(fbp + location_cam + 1);
            green_in = *(fbp + location_cam + 2);
            //red_in =  255;
            //blue_in = 0;
            //green_in = 0;
            color_out = ((red_in >> 3) << 11) | ((green_in >> 2) << 5) | ((blue_in >> 3));

            *(fbp_2 + location_display) = color_out;
        }
    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.