Sample code/C/SamsungLCD
From GumstixDocsWiki
This page presents a simple code for the Samsung LCD sold by Gumstix.
The source
This is a code made for the Gumstix Verdex with the ConsoleLCD-Vx, and the Samsung™ 4.3" LCD panel. It is a modification from the code at The Homebrew Mobile Phone Club. The code simply goes through all of the colors know to the LCD. This code uses 18bpp color so if you are having problems with it you may need to update your SVN. It was tested with version 1580. You can download a .zip with all of the files here. A more detailed description and a video of what should be seen is at Coilgunpower.com
If you download the .zip, first transfer the files, RGB and LCDcolortest, over to your Gumstix computer.
rz -y rz -y
Then run RGB not LCDcolortest. The RGB script will remove the cursor, run the program, and once it is done put it back.
./RGB
The source code:
/* Macro Definitions */
/* File Inclusions */
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <linux/fb.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <asm/param.h>
#include <string.h>
#include <sys/time.h>
/* Typedefs, Structs, Unions, Enums, Etc. */
typedef enum {
FBT_E_NOERR = 0,
FBT_E_USAGE,
FBT_E_NULL,
FBT_E_MALLOC,
FBT_E_FILE,
FBT_E_SCREENO,
FBT_E_SCREENM
} FBTErr;
typedef struct {
char *device;
int screen_fd;
unsigned char *screen_ptr;
unsigned int size;
int width;
int height;
int bpp;
int left_margin;
int right_margin;
int top_margin;
int bottom_margin;
} App;
/* Static Function Prototypes */
static FBTErr fbt_init( App **app, int argc, char *argv[] );
static FBTErr fbt_cleanup( App *app );
static FBTErr fbt_rainbow( App *app );
/* Global Variable Declarations */
/* Function Definitions */
int main( int argc, char *argv[] ) {
FBTErr err = FBT_E_NOERR;
App *app = NULL;
do {
/* initialize the app structure */
if( ( FBT_E_NOERR != ( err = fbt_init( &app, argc, argv ) ) ) ) {
break;
}
/* draw the rainbow */
if( ( FBT_E_NOERR != ( err = fbt_rainbow( app ) ) ) ) {
break;
}
} while( 0 );
if( ( FBT_E_FILE == err ) || ( FBT_E_SCREENO == err ) ||
( FBT_E_SCREENM == err ) ) {
perror( NULL );
}
fbt_cleanup( app );
return( err & 0xFF );
}
/* fbt_init() - initialize the app structure
** if *app is null, the function will allocate a new app structure for you.
** otherwise it assumes you've done it yourself. If app is null... well, that's
** an error.
*/
FBTErr fbt_init( App **app, int argc, char *argv[] ) {
FBTErr err = FBT_E_NOERR;
unsigned int unalloc = 0;
struct fb_var_screeninfo screeninfo;
unsigned int bpp;
do {
if( NULL == app ) {
err = FBT_E_NULL;
break;
}
if( NULL == *app ) {
*app = (App *) malloc( sizeof( App ) );
unalloc = 1;
if( NULL == *app ) {
unalloc = 0;
err = FBT_E_MALLOC;
break;
}
}
memset( *app, 0, sizeof( App ) );
(*app)->screen_fd = -1;
(*app)->device = "/dev/fb0";
printf( "opening %s\n", (*app)->device );
if( ( (*app)->screen_fd = open( (*app)->device, O_RDWR ) ) < 0 ) {
err = FBT_E_FILE;
break;
}
printf( "device %s is file descriptor %d\n", (*app)->device, (*app)->screen_fd );
if( ( ioctl( (*app)->screen_fd, FBIOGET_VSCREENINFO, &screeninfo ) ) > 0 ) {
err = FBT_E_SCREENO;
break;
}
if( screeninfo.bits_per_pixel > 24 ) {
bpp = 32;
} else if( screeninfo.bits_per_pixel > 16 ) {
bpp = 24;
} else if( screeninfo.bits_per_pixel > 8 ) {
bpp = 16;
} else {
bpp = 8;
}
(*app)->width = screeninfo.xres_virtual;
(*app)->height = screeninfo.yres_virtual;
(*app)->bpp = screeninfo.bits_per_pixel;
(*app)->size = (*app)->height * (*app)->width * ( bpp / 8 );
(*app)->left_margin = screeninfo.left_margin;
(*app)->right_margin = screeninfo.right_margin;
(*app)->top_margin = screeninfo.upper_margin;
(*app)->bottom_margin = screeninfo.lower_margin;
printf( "got device info: %d x %d (%d bits per pixels)\nmargin is (%d,%d,%d,%d)\n",
(*app)->width, (*app)->height, (*app)->bpp, (*app)->left_margin,
(*app)->right_margin, (*app)->top_margin, (*app)->bottom_margin );
(*app)->screen_ptr = (unsigned char *) mmap( 0, (*app)->size,
( PROT_READ | PROT_WRITE ), MAP_SHARED, (*app)->screen_fd, 0);
if( MAP_FAILED == (*app)->screen_ptr ) {
err = FBT_E_SCREENM;
break;
}
printf( "screen pointer is %d bytes at %08X\n", (*app)->size, (*app)->screen_ptr );
unalloc = 0;
} while( 0 );
if( 0 != unalloc ) {
free( *app );
*app = NULL;
}
return( err );
}
static FBTErr fbt_rainbow( App *app ) {
FBTErr err = FBT_E_NOERR;
unsigned int i, size,col,b1,b2,b3,r,g,b,line,ct; //set up variables needed
do {
if( NULL == app ) {
err = FBT_E_NULL;
break;
}
line=0;
while (1){
r=0;
g=0;
b=0;
for (ct=0;ct < 1440*line; ct+=3){ //go through each line not to be displayed
++b;
if (b>0x3F){
b=0;
g++;
}
if (g>0x3F){
g=0;
r++;
}
}
for( i = 0; i < app->size; i+=3 ) { //update display
//since the bit pattern is
//GGBBBBBB RRRRGGGG xxxxxxRR
//21654321 43216543 xxxxxx65
//1=LSB 6=MSB x=don't care
//we need to change the r,g, and b variables to fit it.
b1=0;
b2=0;
b3=0;
b3=((r&0x30)>>4);
b2|=((r&0x0f)<<4);
b2|=((g&0x3c)>>2);
b1|=((g&0x03)<<6);
b1|=b;
app->screen_ptr[i] = b1; //display the pixel
app->screen_ptr[i+1] = b2;
app->screen_ptr[i+2] = b3 ;
++b; //change the rgb value for each pixel
if (b>0x3F){
b=0;
g++;
}
if (g>0x3F){
g=0;
r++;
}
}
usleep (100000);//delay
if (r>0x3F) break;//if the pixel is full red then all colors have been displayed so leave the loop
++line; //set the line to be displayed 1 lower each time
}
} while( 0 );
return( err );
}
static FBTErr fbt_cleanup( App *app ) {
FBTErr err = FBT_E_NOERR;
do {
if( NULL == app ) {
err = FBT_E_NULL;
break;
}
if( ( NULL != app->screen_ptr ) && ( MAP_FAILED != app->screen_ptr ) ) {
munmap( app->screen_ptr, app->size );
}
if( app->screen_fd >= 0 ) {
close( app->screen_fd );
}
} while( 0 );
return( err );
}

