AVR32: Displaying image on graphic LCD

Last weekend, I was dealing with the graphic LCD on EVK1105. I am happy to deal with output device. It is because they can interact with users and programmers. They can use for debugging, showing error and feedback. Another reason is the output devices are easier to debug when you have done something wrong.

The software driver of graphic LCD is provided by the Atmel Software Framework. It is also comes with a example that displays an AVR32 logo on the graphic LCD. The code is easy to understand, but the problem is to generate a 16-bits pixmap array that is compatible with the function provided by ASF.

After some research, I have found that GIMP (GNU Image Manipulation Program) is able to convert image file into a C-language array. The array can hold the RGB (or RGBA) value of each pixel. The pixel value are all represented by ASCII character, 8-bits for each color and 24-bits (or 32-bits) for each pixel. So, the only thing I need to do is translate the pixel format to 5R6G5B and send it to the Graphic LCD.

To get the C-source output from GIMP, go to File -> save as -> change the filename extension to “.c” -> save -> uncheck “Use GLib types” -> save. The output of the GIMP C-source array is shown at below.

/* GIMP RGBA C-Source image dump (aestelogo_150x50.c) */

static const struct {
  unsigned int 	 width;
  unsigned int 	 height;
  unsigned int 	 bytes_per_pixel; /* 3:RGB, 4:RGBA */ 
  unsigned char	 pixel_data[150 * 50 * 4 + 1];
} gimp_image = {
  150, 50, 4,
 "377377377377377377377377377377377377377377377377377377"
  "377377377377377377377377377377377377377377377377377377"
  "377377377377377377377377377377377377377377377377377377"
 "377343L1377337122377335%3377334363773343737733437"
  "3773343737733437377334373773343737733436377334"
  "!377336+13377340730377350jT377371331324377377377377377"
  "377377377377376376376377377377377377377377377377377377"

  ......
  ...

  "",
  };

Below is the loop that used for converting the pixel value to 16-bits format and output to graphic LCD. It is slow since it accesses the pixel directly rather than the buffer. I can see the image ‘flash’ everytime I refreshes the screen.

for( i = 0; i < height; i++ ){
    for( j = 0; j < width; j++ ){

        /* Get Red Channel. */
        R = bitmap[count];
        count++;

        /* Get Green Channel. */
        G = bitmap[count];
        count++;

        /* Get Blue Channel. */
        B = bitmap[count];
        count++;

        /* Get Alpha Channel. */
        if(colorChannel == 4){
            /* Alpha Channel. */
            count++;
        }

        /* Change the 8R8G8B format to 5R6G5B. */
        pixel = et024006_Color( R, G, B );

        /* Convert the endianness. */
        pixel = ( pixel >> 8 ) | ( pixel << 8 );

        /* Draw the pixel on GLCD screen. 
         * x, y is the offset.
         */			
        et024006_DrawPixel( x+j, y+i, pixel );

    }
}

The code doesn’t support the alpha channel right now, but I left a branch there for future enhancement. Before adding the alpha channel, I need to improve the frame-rate until it is more ‘comfortable’ to human eyes.

You may also like...

Leave a Reply