各位大侠,小弟是第一次发帖,还请各位多多指教!最近在linux2.6下开发基于S3C2440的camera驱动,视频数据通过lcd显示,现在的问题是camera数据无法显示到lcd上面,可以确定lcd驱动是正常的;现贴出一些相关程序:
#define VIDEOMEMSIZE (2*320*240) // 1 MB ,lcd 一屏的数据字节数
unsigned int pVideoBuffer; //写入lcdaddr的那个值
static unsigned char*videomemory;
static u_long videomemorysize = VIDEOMEMSIZE;
int DEMO_init_module(void)
{
int result;
dev_t dev = 0;
dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);
result = register_chrdev_region(dev, 1, "DEMO");
if (result < 0)
{
printk(KERN_WARNING "DEMO: can't get major %d\n", DEMO_MAJOR);
return result;
}
DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);
if (!DEMO_devices)
{
result = -ENOMEM;
goto fail;
}
memset(DEMO_devices, 0, sizeof(struct DEMO_dev));
cdev_init(&DEMO_devices->cdev, &DEMO_fops);
DEMO_devices->cdev.owner = THIS_MODULE;
DEMO_devices->cdev.ops = &DEMO_fops;
result = cdev_add (&DEMO_devices->cdev, dev, 1);
if(result)
{
printk(KERN_NOTICE "Error %d adding DEMO\n", result);
goto fail;
}
gf_base_int = ioremap(0x4a000000,0x20);
gf_base_gpio_b= ioremap(0x56000010, 0x0c);
gf_base_gpio_c = ioremap(0x56000020,0x0c);
gf_base_gpio_d= ioremap(0x56000030, 0x0c);
gf_base_gpio_e = ioremap(0x56000040,0x0c);
gf_base_gpio_f= ioremap(0x56000050, 0x0c);
gf_base_gpio_g = ioremap(0x56000060,0x0c);
gf_base_gpio_j= ioremap(0x560000d0, 0x0c);
gf_base_lcd_con1= ioremap(0x4d000000, 0x60);
gf_base_clk_power = ioremap(0x4c000000,0x20);
gf_base_camera = ioremap(0x4f000000,0xa4);
request_dma(1,"DEMO");
videomemorysize=PAGE_ALIGN(videomemorysize+PAGE_SIZE);
videomemory=dma_alloc_writecombine(NULL,videomemorysize,&pVideoBuffer,GFP_KERNEL);
memset(videomemory, 10, videomemorysize); //这里可以使lcd全屏显示某一种颜色
}
static void Lcd_Init(void)
{
rLCDCON1=(7<<8)|(3<<5)|(12<<1);
rLCDCON2=(2<<24)|(319<<14)|(2<<6)|4;
rLCDCON3=(8<<19)|(239<<8)|8;
rLCDCON4=(13<<8)|6;
rLCDCON5=(1<<11)|(0<<9)|(0<<8)|(0<<6)|(1);
rLCDSADDR1=(((U32)pVideoBuffer>>22)<<21)|M5D((U32)pVideoBuffer>>1);
rLCDSADDR2=M5D( ((U32)pVideoBuffer+(SCR_XSIZE_TFT_240320*LCD_YSIZE_TFT_240320*2))>>1 );
rLCDSADDR3=(((SCR_XSIZE_TFT_240320-LCD_XSIZE_TFT_240320)/1)<<11)|(LCD_XSIZE_TFT_240320/1);
rLCDINTMSK=0x3;
rTPAL=0x0;
rTCONSEL=0;
}
void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 PrDstWidth, U32 PrDstHeight, U32 WinHorOffset, U32 WinVerOffset, U32 CoFrameBuffer, U32 pVideoBuffer)
{
U32 WinOfsEn;
U32 multiplier;
U32 MainBurstSizeRGB, RemainedBurstSizeRGB;
U32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
U32 SrcWidth, SrcHeight;
U32 ScaleUp_H_Pr, ScaleUp_V_Pr;
//constant for calculating preview dma address
if(CAM_PVIEW_OUTPUT) //相当与CAM_RGB16B=0
multiplier=4;
else
multiplier=2;
if(WinHorOffset==0 && WinVerOffset==0)
WinOfsEn=0; //不允许有偏移
else
WinOfsEn=1;
SrcWidth=CAM_SRC_HSIZE-WinHorOffset*2; //CAM_SRC_HSIZE=640
SrcHeight=CAM_SRC_VSIZE-WinVerOffset*2;//CAM_SRC_VSIZE=480
if(SrcWidth>=PrDstWidth) ScaleUp_H_Pr=0; //down
else ScaleUp_H_Pr=1; //up
if(SrcHeight>=PrDstHeight) ScaleUp_V_Pr=0; // edited 040225
else ScaleUp_V_Pr=1;
// common control setting
rCIGCTRL |= (1<<26)|(0<<27); // inverse PCLK, test pattern
rCIWDOFST = (1<<30)|(0xf<<12); // clear overflow
rCIWDOFST = 0;
rCIWDOFST=(WinOfsEn<<31)|(WinHorOffset<<16)|(WinVerOffset);
rCISRCFMT=(CAM_ITU601<<31)|(0<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_YCBYCR<<14)|(CAM_SRC_VSIZE);
//(0<<30)代表ycbycr格式
// preview port setting
if (CAM_PVIEW_4PP) // codec view mode #define CAM_PVIEW_4PP (0)
{
rCIPRCLRSA1=pVideoBuffer;
rCIPRCLRSA2=rCIPRCLRSA1+PrDstWidth*PrDstHeight*multiplier;
rCIPRCLRSA3=rCIPRCLRSA2+PrDstWidth*PrDstHeight*multiplier;
rCIPRCLRSA4=rCIPRCLRSA3+PrDstWidth*PrDstHeight*multiplier;
}
else // direct preview mode
{
rCIPRCLRSA1 = (U32)(pVideoBuffer);
rCIPRCLRSA2 = (U32)(pVideoBuffer);
rCIPRCLRSA3 = (U32)(pVideoBuffer);
rCIPRCLRSA4 = (U32)(pVideoBuffer);
}
rCIPRTRGFMT=(PrDstWidth<<16)|(0<<14)|(PrDstHeight); //可以旋转图像
if (CAM_PVIEW_OUTPUT==CAM_RGB24B)
CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
else // RGB16B
CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
rCIPRCTRL=(MainBurstSizeRGB<<19)|(RemainedBurstSizeRGB<<14);
CalculatePrescalerRatioShift(SrcWidth, PrDstWidth, &PreHorRatio, &H_Shift);
CalculatePrescalerRatioShift(SrcHeight, PrDstHeight, &PreVerRatio, &V_Shift);
MainHorRatio=(SrcWidth<<8)/(PrDstWidth<
MainVerRatio=(SrcHeight<<8)/(PrDstHeight<
rCIPRSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
rCIPRSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
rCIPRSCCTRL=(1<<31)|(CAM_PVIEW_OUTPUT<<30)|(ScaleUp_H_Pr<<29)|(ScaleUp_V_Pr<<28)|(MainHorRatio<<16)|(MainVerRatio);
rCIPRTAREA= PrDstWidth*PrDstHeight;
}
基本就是这样了 ,问题应该就在这里:
rCIPRCLRSA1 = (U32)(pVideoBuffer);
rCIPRCLRSA2 = (U32)(pVideoBuffer);
rCIPRCLRSA3 = (U32)(pVideoBuffer);
rCIPRCLRSA4 = (U32)(pVideoBuffer);
感觉开辟的内存区域没有数据,不知为何?是不是思路就不正确阿?请大家多多指教,急!