Hi all,
I would like to test an LCD display with a non-standard resolution which is attached to a Mistral 3530 EVM board.
I use ti-dvsdk_omap3530-evm_4_01_00_09.
Guided by http://processors.wiki.ti.com/index.php/UserGuideDisplayDrivers_PSP_03.00.00.05, I wrote a little program which opens the FB device, reads some values, programs the new frequencies and timing (using ioctl) and writes data into the mmapped FB.
At the first run, I see the previous value (from kernel startup). The display does not change (as far as I can see). At the second run I expect to see get the changed values but I see changes only for xres, yres, but not the timings.
Can someone please explain what is going wrong? Is there a complete example (demo code) to do something similar ?
Thanks in advance, Thomas.
PS:
The display is a Evervision 480x272 display with
Pixclock 9MHz
hres 480
h-front porch 2
h back porch 2
h sync 41
vres 272
v front porch 2
v back porch 2
v sync 10
This is the test code:
#include <stdio.h>
#include <stddef.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "include/linux/fb.h"
int getFbFixScreeninfo(int fd)
{
int ret;
/* Getting fix screen information */
struct fb_fix_screeninfo fix;
ret = ioctl(fd, FBIOGET_FSCREENINFO, &fix);
if(ret < 0) {
printf("Cannot get fix screen information\n");
return ret;
}
printf("ID = %s\n",fix.id);
printf("Line length = %d\n",fix.line_length);
printf("Physical Address = %x\n",fix.smem_start);
printf("Buffer Length = %d\n",fix.smem_len);
printf("MMIO Length = %d\n",fix.mmio_len);
printf("MMIO start = %x\n",fix.mmio_start);
printf("type = %d\n",fix.type);
printf("type_aux = %x\n",fix.type_aux);
printf("visual = %d\n",fix.visual);
return ret;
}
void printBitfield(struct fb_bitfield bf)
{
printf("Offset:%d, Length:%d, Msb:%d\n",bf.offset,bf.length,bf.msb_right);
}
int getFbVarScreeninfo(int fd)
{
int ret;
/* Getting fix screen information */
struct fb_var_screeninfo var;
ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
if(ret < 0) {
printf("Cannot get var screen information\n");
return ret;
}
printf("RES = (%d,%d) VRES = (%d,%d)\n", var.xres, var.yres, var.xres_virtual, var.yres_virtual);
printf("OFFSET = (%d,%d)\n", var.xoffset, var.yoffset);
printf("BitsPerPixel = %d\n", var.bits_per_pixel);
printf("Nonstd: %d\n", var.nonstd);
printf("Bitfield Red:");
printBitfield(var.red);
printf("Bitfield Green:");
printBitfield(var.green);
printf("Bitfield Blue:");
printBitfield(var.blue);
printf("Activate: %d\n", var.activate);
printf("Pixclock: %d\n", var.pixclock);
printf("lp,rp,hs: %d,%d,%d\n", var.left_margin, var.right_margin, var.hsync_len);
printf("tp,bp,vs: %d,%d,%d\n", var.upper_margin, var.lower_margin, var.vsync_len);
printf("sync: HorHi:%d,VerHi:%d,Ext:%d,CompHi:%d,BC:%d,oG:%d\n", var.sync&FB_SYNC_HOR_HIGH_ACT?1:0,
var.sync&FB_SYNC_VERT_HIGH_ACT?1:0, var.sync&FB_SYNC_EXT?1:0, var.sync&FB_SYNC_COMP_HIGH_ACT?1:0,
var.sync&FB_SYNC_BROADCAST?1:0, var.sync&FB_SYNC_ON_GREEN?1:0 );
printf("VMode: %d\n", var.vmode);
printf("Rotate: %d\n", var.rotate);
return ret;
}
int setFbVarScreeeninfo(int fd, int xres,int yres,int bpp, int pixcl, int lep,int rp,int hs, int up, int lop, int vs, int sync, int rot)
{
int ret;
struct fb_var_screeninfo var;
ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
if(ret < 0) {
printf("Cannot get var screen information\n");
return ret;
}
var.xres = xres;
var.xres_virtual = xres;
var.xoffset = 0;
var.yres = yres;
var.yres_virtual = yres;
var.yoffset = 0;
var.bits_per_pixel = bpp;
var.pixclock = pixcl;
var.left_margin = lep;
var.right_margin = rp;
var.hsync_len = hs;
var.upper_margin = up;
var.lower_margin = lop;
var.vsync_len = vs;
var.sync = sync;
var.rotate = rot;
ret = ioctl(fd, FBIOPUT_VSCREENINFO, &var);
if(ret < 0) {
printf("Cannot put var screen information\n");
return ret;
}
return ret;
}
void mapAndDraw(int fd, int xres,int yres,int bytes)
{
short * addr = NULL;
addr = mmap(NULL,xres*yres*bytes,PROT_READ+PROT_WRITE,MAP_SHARED,fd,0);
if(addr!=0)
{
int i;
for(i=0;i<272;i++)
{
int j;
for(j=0;j<480;j++)
{
addr[i*480+j] = ((i&4)^(j&4))?0:0xffff;
}
}
}
munmap(addr,xres*yres*bytes);
}
int main()
{
int fd;
int ret = 0;
/* Open a graphics Display logical channel in blocking mode */
fd = open ("/dev/fb0", O_RDWR);
if (fd == -1) {
perror("failed to open display device\n");
return -1;
}
if (fd>0 && ret==0)
{
ret = getFbFixScreeninfo(fd);
}
if (fd>0 && ret==0)
{
ret = getFbVarScreeninfo(fd);
}
if (fd>0 && ret==0)
{
ret = setFbVarScreeeninfo(fd, 480,272,16,111111,2,2,41,2,2,10,0,0);
}
if (fd>0 && ret==0)
{
mapAndDraw(fd,480,272,2);
}
/* Closing of channels */
close (fd);
}