• 首页
  • 中国
  • S3C2440之Camera驱动代码模板(RealView MDK)

S3C2440之Camera驱动代码模板(RealView MDK)

2023-11-01 111浏览
百检网是一家专业的第三方检测平台,汇聚众多拥有权威资质的第三方检测机构为你提供一站式的检测服务,做检测就上百检网。百检网让检测从此检测,一份报告全国通用,专业值得信赖。

好记心不如烂笔头,为方便以后查看代码及代码重复利用,这里贴出S3C2440 Camera驱动代码。使用友善MINI2440开发板,开发环境为RealView MDK 4.22。

原始工程下载地址:点击打开链接

*初,本人在网上下载了许多mini2440 camera驱动的代码,但结果都不尽人意,因为这些代码看起来都比较晦涩难懂,都是直接对寄存器进行位与位或操作,且有的代码排版布局很乱,对初学者来说难度较大。由于本人接触了STM32开发后,觉得STM32的库函数给初学者提供了很大帮助,仅仅通过函数名及变量名就能知道当前操作的是哪个寄存器,这样在阅读代码时就能很容易明白代码的含义了,增强了程序的可读性。由此启发,本人也仿照STM32库函数的风格,写了一个基于S3C2440 CAMIF的库函数,这样当以后自己回过头来再看自己写的代码时就能很快理解代码的含义,也能帮助其他学习2440 camera的初学者,让他们能更容易理解代码的思路。

结构体定义:

typedefstruct

{

//SOURCEFORMATREGISTER

u32ITU601_656n;

u32UVOffset;

u32SourceHsize;

u32Order422;

u32SourceVsize;

//WINDOWOPTIONREGISTER

u32WinOfsEn;

u32WinHorOfst;

u32WinVerOfst;

//GLOBALCONTROLREGISTER

u32TestPattern;

u32InvPolCAMPCLK;

u32InvPolCAMVSYNC;

u32InvPolCAMHREF;

}CAMIF_InitTypeDef;

typedefstruct

{

//YSTARTADDRESSREGISTER

u32YStartAddr1;

u32YStartAddr2;

u32YStartAddr3;

u32YStartAddr4;

//CbSTARTADDRESSREGISTER

u32CbStartAddr1;

u32CbStartAddr2;

u32CbStartAddr3;

u32CbStartAddr4;

//CrSTARTADDRESSREGISTER

u32CrStartAddr1;

u32CrStartAddr2;

u32CrStartAddr3;

u32CrStartAddr4;

//CODECTARGETFORMATREGISTER

u32In422_Co;

u32Out422_Co;

u32TargetHsize_Co;

u32FlipMd_Co;

u32TargetVsize_Co;

//CODECDMACONTROLREGISTER

u32Yburst1_Co;

u32Yburst2_Co;

u32Cburst1_Co;

u32Cburst2_Co;

//CODECPRE-SCALERCONTROLREGISTER

u32SHfactor_Co;

u32PreHorRatio_Co;

u32PreVerRatio_Co;

u32PreDstWidth_Co;

u32PreDstHeight_Co;

//CODECMAIN-SCALERCONTROLREGISTER

u32ScalerBypass_Co;

u32ScaleUpDown_Co;

u32MainHorRatio_Co;

u32MainVerRatio_Co;

//CODECDMATARGETAREAREGISTER

u32TargetArea_Co;

}CAMIF_CodecInitTypeDef;

typedefstruct

{

//RGBSTARTADDRESSREGISTER

u32RGBStartAddr1;

u32RGBStartAddr2;

u32RGBStartAddr3;

u32RGBStartAddr4;

//PREVIEWTARGETFORMATREGISTER

u32TargetHsize_Pr;

u32FlipMd_Pr;

u32TargetVsize_Pr;

//PREVIEWDMACONTROLREGISTER

u32RGBburst1_Pr;

u32RGBburst2_Pr;

//PREVIEWPRE-SCALERCONTROLREGISTER

u32SHfactor_Pr;

u32PreHorRatio_Pr;

u32PreVerRatio_Pr;

u32PreDstWidth_Pr;

u32PreDstHeight_Pr;

//PREVIEWMAIN-SCALERCONTROLREGISTER

u32RGBformat_Pr;

u32ScaleUpDown_Pr;

u32MainHorRatio_Pr;

u32MainVerRatio_Pr;

//PREVIEWDMATARGETAREAREGISTER

u32TargetArea_Pr;

}CAMIF_PreviewInitTypeDef;

CAMIF接口的配置(主要寄存器的配置):

voidCAMIF_Config(unsignedintHorOfst,unsignedintVerOfst)

{

CAMIF_InitTypeDefCAMIF_InitStruct;

CAMIF_CodecInitTypeDefCAMIF_CoInitStruct;

CAMIF_PreviewInitTypeDefCAMIF_PrInitStruct;

unsignedintmainburst,remainburst;

unsignedintH_Shift,V_Shift;

unsignedintPreHorRatio,PreVerRatio;

unsignedintMainHorRatio,MainVerRatio;

unsignedintSRC_Width,SRC_Height;

unsignedintDST_Width,DST_Height;

/***********************globalparameters****************************/

CAMIF_InitStruct.ITU601_656n=ITU_601;

CAMIF_InitStruct.UVOffset=UVOffest_0;

CAMIF_InitStruct.Order422=Order_YCbYCr;

CAMIF_InitStruct.SourceHsize=CAM_XSIZE;

CAMIF_InitStruct.SourceVsize=CAM_YSIZE;

CAMIF_InitStruct.WinOfsEn=(HorOfst||VerOfst)?1:0;

CAMIF_InitStruct.WinHorOfst=HorOfst;

CAMIF_InitStruct.WinVerOfst=VerOfst;

CAMIF_InitStruct.TestPattern=Pattern_Normal;

CAMIF_InitStruct.InvPolCAMPCLK=ENABLE;

CAMIF_InitStruct.InvPolCAMHREF=DISABLE;

CAMIF_InitStruct.InvPolCAMVSYNC=DISABLE;

CAMIF_Init(&CAMIF_InitStruct);

/***********************previewscalerparameters********************/

CAMIF_PrInitStruct.RGBStartAddr1=(u32)LCD_BUFFER;

CAMIF_PrInitStruct.RGBStartAddr2=(u32)LCD_BUFFER;

CAMIF_PrInitStruct.RGBStartAddr3=(u32)LCD_BUFFER;

CAMIF_PrInitStruct.RGBStartAddr4=(u32)LCD_BUFFER;

CAMIF_PrInitStruct.RGBformat_Pr=RGBformat_16;

CAMIF_PrInitStruct.FlipMd_Pr=FlipMode_Xmirror;

CAMIF_PrInitStruct.TargetHsize_Pr=LCD_XSIZE;

CAMIF_PrInitStruct.TargetVsize_Pr=LCD_YSIZE;

CAMIF_PrInitStruct.TargetArea_Pr=LCD_XSIZE*LCD_YSIZE;

CalcBurstSize(LCD_XSIZE*2,&mainburst,&remainburst);

CAMIF_PrInitStruct.RGBburst1_Pr=mainburst;

CAMIF_PrInitStruct.RGBburst2_Pr=remainburst;

SRC_Width=CAM_XSIZE-(2*HorOfst);

SRC_Height=CAM_YSIZE-(2*VerOfst);

DST_Width=LCD_XSIZE;

DST_Height=LCD_YSIZE;

CalcPrescaleParam(SRC_Width,DST_Width,&PreHorRatio,&H_Shift);

CalcPrescaleParam(SRC_Height,DST_Height,&PreVerRatio,&V_Shift);

CAMIF_PrInitStruct.SHfactor_Pr=10-H_Shift-V_Shift;

CAMIF_PrInitStruct.PreHorRatio_Pr=PreHorRatio;

CAMIF_PrInitStruct.PreVerRatio_Pr=PreVerRatio;

CAMIF_PrInitStruct.PreDstWidth_Pr=SRC_Width/PreHorRatio;

CAMIF_PrInitStruct.PreDstHeight_Pr=SRC_Height/PreVerRatio;

MainHorRatio=(SRC_Width<<8)/(DST_Width<

MainVerRatio=(SRC_Height<<8)/(DST_Height<

CAMIF_PrInitStruct.MainHorRatio_Pr=MainHorRatio;

CAMIF_PrInitStruct.MainVerRatio_Pr=MainVerRatio;

CAMIF_PrInitStruct.ScaleUpDown_Pr=(SRC_Width<=DST_Width)?ScaleUp:ScaleDown;

CAMIF_PreviewInit(&CAMIF_PrInitStruct);

/*******************codecscalerparameters**************************/

CAMIF_CoInitStruct.YStartAddr1=(u32)CaptureY_Buf;

CAMIF_CoInitStruct.YStartAddr2=(u32)CaptureY_Buf;

CAMIF_CoInitStruct.YStartAddr3=(u32)CaptureY_Buf;

CAMIF_CoInitStruct.YStartAddr4=(u32)CaptureY_Buf;

CAMIF_CoInitStruct.CbStartAddr1=(u32)CaptureCb_Buf;

CAMIF_CoInitStruct.CbStartAddr2=(u32)CaptureCb_Buf;

CAMIF_CoInitStruct.CbStartAddr3=(u32)CaptureCb_Buf;

CAMIF_CoInitStruct.CbStartAddr4=(u32)CaptureCb_Buf;

CAMIF_CoInitStruct.CrStartAddr1=(u32)CaptureCr_Buf;

CAMIF_CoInitStruct.CrStartAddr2=(u32)CaptureCr_Buf;

CAMIF_CoInitStruct.CrStartAddr3=(u32)CaptureCr_Buf;

CAMIF_CoInitStruct.CrStartAddr4=(u32)CaptureCr_Buf;

CAMIF_CoInitStruct.In422_Co=YCbCr_422;

CAMIF_CoInitStruct.Out422_Co=YCbCr_422;

CAMIF_CoInitStruct.FlipMd_Co=FlipMode_Xmirror;

CAMIF_CoInitStruct.TargetHsize_Co=LCD_XSIZE;

CAMIF_CoInitStruct.TargetVsize_Co=LCD_YSIZE;

CAMIF_CoInitStruct.TargetArea_Co=LCD_XSIZE*LCD_YSIZE;

CalcBurstSize(LCD_XSIZE,&mainburst,&remainburst);

CAMIF_CoInitStruct.Yburst1_Co=mainburst;

CAMIF_CoInitStruct.Yburst2_Co=remainburst;

CalcBurstSize(LCD_YSIZE/2,&mainburst,&remainburst);

CAMIF_CoInitStruct.Cburst1_Co=mainburst;

CAMIF_CoInitStruct.Cburst2_Co=remainburst;

SRC_Width=CAM_XSIZE-(2*HorOfst);

SRC_Height=CAM_YSIZE-(2*VerOfst);

DST_Width=LCD_XSIZE;

DST_Height=LCD_YSIZE;

CalcPrescaleParam(SRC_Width,DST_Width,&PreHorRatio,&H_Shift);

CalcPrescaleParam(SRC_Height,DST_Height,&PreVerRatio,&V_Shift);

CAMIF_CoInitStruct.SHfactor_Co=10-H_Shift-V_Shift;

CAMIF_CoInitStruct.PreHorRatio_Co=PreHorRatio;

CAMIF_CoInitStruct.PreVerRatio_Co=PreVerRatio;

CAMIF_CoInitStruct.PreDstWidth_Co=SRC_Width/PreHorRatio;

CAMIF_CoInitStruct.PreDstHeight_Co=SRC_Height/PreVerRatio;

MainHorRatio=(SRC_Width<<8)/(DST_Width<

MainVerRatio=(SRC_Height<<8)/(DST_Height<

CAMIF_CoInitStruct.MainHorRatio_Co=MainHorRatio;

CAMIF_CoInitStruct.MainVerRatio_Co=MainVerRatio;

CAMIF_CoInitStruct.ScaleUpDown_Co=(SRC_Width<=DST_Width)?ScaleUp:ScaleDown;

CAMIF_CoInitStruct.ScalerBypass_Co=DISABLE;

CAMIF_CodecInit(&CAMIF_CoInitStruct);

}

CAMIF_Init函数,实现对全局参数寄存器的配置:

voidCAMIF_Init(CAMIF_InitTypeDef*pInitStruct)

{

//SOURCEFORMATREGISTER

rCISRCFMT&=~(0x1FFF<<0);

rCISRCFMT|=(pInitStruct->SourceVsize<<0);

rCISRCFMT&=~(3<<14);

rCISRCFMT|=(pInitStruct->Order422<<14);

rCISRCFMT&=~(0x1FFF<<16);

rCISRCFMT|=(pInitStruct->SourceHsize<<16);

rCISRCFMT&=~(1<<30);

rCISRCFMT|=(pInitStruct->UVOffset<<30);

rCISRCFMT&=~(1<<31);

rCISRCFMT|=(pInitStruct->ITU601_656n<<31);

//WINDOWOPTIONREGISTER

rCIWDOFST&=~(0x7FF<<0);

rCIWDOFST|=(pInitStruct->WinVerOfst<<0);

rCIWDOFST&=~(0x7FF<<16);

rCIWDOFST|=(pInitStruct->WinHorOfst<<16);

rCIWDOFST&=~(1<<31);

rCIWDOFST|=(pInitStruct->WinOfsEn<<31);

//GLOBALCONTROLREGISTER

rCIGCTRL&=~(1<<24);

rCIGCTRL|=(pInitStruct->InvPolCAMVSYNC<<24);

rCIGCTRL&=~(1<<25);

rCIGCTRL|=(pInitStruct->InvPolCAMHREF<<25);

rCIGCTRL&=~(1<<26);

rCIGCTRL|=(pInitStruct->InvPolCAMPCLK<<26);

rCIGCTRL&=~(3<<27);

rCIGCTRL|=(pInitStruct->TestPattern<<27);

rCIGCTRL|=(1<<29);

}

CAMIF_PreviewInit函数,实现对Preview参数寄存器的配置:

voidCAMIF_PreviewInit(CAMIF_PreviewInitTypeDef*pPreInitStruct)

{

//RGBSTARTADDRESSREGISTER

rCIPRCLRSA1=pPreInitStruct->RGBStartAddr1;

rCIPRCLRSA2=pPreInitStruct->RGBStartAddr2;

rCIPRCLRSA3=pPreInitStruct->RGBStartAddr3;

rCIPRCLRSA4=pPreInitStruct->RGBStartAddr4;

//PREVIEWTARGETFORMATREGISTER

rCIPRTRGFMT&=~(0x1FFF<<0);

rCIPRTRGFMT|=(pPreInitStruct->TargetVsize_Pr<<0);

rCIPRTRGFMT&=~(3<<14);

rCIPRTRGFMT|=(pPreInitStruct->FlipMd_Pr<<14);

rCIPRTRGFMT&=~(0x1FFF<<16);

rCIPRTRGFMT|=(pPreInitStruct->TargetHsize_Pr<<16);

//PREVIEWDMACONTROLREGISTER

rCIPRCTRL&=~(1<<2);

rCIPRCTRL&=~(0x1F<<14);

rCIPRCTRL|=(pPreInitStruct->RGBburst2_Pr<<14);

rCIPRCTRL&=~(0x1F<<19);

rCIPRCTRL|=(pPreInitStruct->RGBburst1_Pr<<19);

//PREVIEWPRE-SCALERCONTROLREGISTER

rCIPRSCPRERATIO&=~(0x7F<<0);

rCIPRSCPRERATIO|=(pPreInitStruct->PreVerRatio_Pr<<0);

rCIPRSCPRERATIO&=~(0x7F<<16);

rCIPRSCPRERATIO|=(pPreInitStruct->PreHorRatio_Pr<<16);

rCIPRSCPRERATIO&=~(0xF<<28);

rCIPRSCPRERATIO|=(pPreInitStruct->SHfactor_Pr<<28);

rCIPRSCPREDST&=~(0xFFF<<0);

rCIPRSCPREDST|=(pPreInitStruct->PreDstHeight_Pr<<0);

rCIPRSCPREDST&=~(0xFFF<<16);

rCIPRSCPREDST|=(pPreInitStruct->PreDstWidth_Pr<<16);

//PREVIEWMAIN-SCALERCONTROLREGISTER

rCIPRSCCTRL&=~(0x1FF<<0);

rCIPRSCCTRL|=(pPreInitStruct->MainVerRatio_Pr<<0);

rCIPRSCCTRL&=~(1<<15);

rCIPRSCCTRL&=~(0x1FF<<16);

rCIPRSCCTRL|=(pPreInitStruct->MainHorRatio_Pr<<16);

rCIPRSCCTRL&=~(3<<28);

rCIPRSCCTRL|=(pPreInitStruct->ScaleUpDown_Pr<<28);

rCIPRSCCTRL&=~(1<<30);

rCIPRSCCTRL|=(pPreInitStruct->RGBformat_Pr<<30);

rCIPRSCCTRL|=(1<<31);

//PREVIEWDMATARGETAREAREGISTER

rCIPRTAREA=pPreInitStruct->TargetArea_Pr;

}

CAMIF_CodecInit函数,实现对Codec参数寄存器的配置:

voidCAMIF_CodecInit(CAMIF_CodecInitTypeDef*pCoInitStruct)

{

//YSTARTADDRESSREGISTER

rCICOYSA1=(u32)pCoInitStruct->YStartAddr1;

rCICOYSA2=(u32)pCoInitStruct->YStartAddr2;

rCICOYSA3=(u32)pCoInitStruct->YStartAddr3;

rCICOYSA4=(u32)pCoInitStruct->YStartAddr4;

//CBSTARTADDRESSREGISTER

rCICOCBSA1=(u32)pCoInitStruct->CbStartAddr1;

rCICOCBSA2=(u32)pCoInitStruct->CbStartAddr2;

rCICOCBSA3=(u32)pCoInitStruct->CbStartAddr3;

rCICOCBSA4=(u32)pCoInitStruct->CbStartAddr4;

//CRSTARTADDRESSREGISTER

rCICOCRSA1=(u32)pCoInitStruct->CrStartAddr1;

rCICOCRSA2=(u32)pCoInitStruct->CrStartAddr2;

rCICOCRSA3=(u32)pCoInitStruct->CrStartAddr3;

rCICOCRSA4=(u32)pCoInitStruct->CrStartAddr4;

//CODECTARGETFORMATREGISTER

rCICOTRGFMT&=~(0x1FFF<<0);

rCICOTRGFMT|=(pCoInitStruct->TargetVsize_Co<<0);

rCICOTRGFMT&=~(3<<14);

rCICOTRGFMT|=(pCoInitStruct->FlipMd_Co<<14);

rCICOTRGFMT&=~(0x1FFF<<16);

rCICOTRGFMT|=(pCoInitStruct->TargetHsize_Co<<16);

rCICOTRGFMT&=~(1<<30);

rCICOTRGFMT|=(pCoInitStruct->Out422_Co<<30);

rCICOTRGFMT&=~(1<<31);

rCICOTRGFMT|=(pCoInitStruct->In422_Co<<31);

//CODECDMACONTROLREGISTER

rCICOCTRL&=~(1<<2);

rCICOCTRL&=~(0x1F<<4);

rCICOCTRL|=(pCoInitStruct->Cburst2_Co<<4);

rCICOCTRL&=~(0x1F<<9);

rCICOCTRL|=(pCoInitStruct->Cburst1_Co<<9);

rCICOCTRL&=~(0x1F<<14);

rCICOCTRL|=(pCoInitStruct->Yburst2_Co<<14);

rCICOCTRL&=~(0x1F<<19);

rCICOCTRL|=(pCoInitStruct->Yburst1_Co<<19);

//CODECPRE-SCALERCONTROLREGISTER

rCICOSCPRERATIO&=~(0x7F<<0);

rCICOSCPRERATIO|=(pCoInitStruct->PreVerRatio_Co<<0);

rCICOSCPRERATIO&=~(0x7F<<16);

rCICOSCPRERATIO|=(pCoInitStruct->PreHorRatio_Co<<16);

rCICOSCPRERATIO&=~(0xF<<28);

rCICOSCPRERATIO|=(pCoInitStruct->SHfactor_Co<<28);

rCICOSCPREDST&=~(0xFFF<<0);

rCICOSCPREDST|=(pCoInitStruct->PreDstHeight_Co<<0);

rCICOSCPREDST&=~(0xFFF<<16);

rCICOSCPREDST|=(pCoInitStruct->PreDstWidth_Co<<16);

//CODECMAIN-SCALERCONTROLREGISTER

rCICOSCCTRL&=~(0x1FF<<0);

rCICOSCCTRL|=(pCoInitStruct->MainVerRatio_Co<<0);

rCICOSCCTRL&=~(1<<15);

rCICOSCCTRL&=~(0x1FF<<16);

rCICOSCCTRL|=(pCoInitStruct->MainHorRatio_Co<<16);

rCICOSCCTRL&=~(3<<29);

rCICOSCCTRL|=(pCoInitStruct->ScaleUpDown_Co<<29);

rCICOSCCTRL&=~(1<<31);

rCICOSCCTRL|=(pCoInitStruct->ScalerBypass_Co<<31);

//CODECDMATARGETAREAREGISTER

rCICOTAREA=pCoInitStruct->TargetArea_Co;

}

开启Preview:

voidCAMIF_StartPreview(void)

{

rCIPRSCCTRL|=(1<<15);

rCIIMGCPT|=(1<<29);

rCIIMGCPT|=(1<<31);

}

开启Codec:

voidCAMIF_StartCapture(void)

{

rCICOSCCTRL|=(1<<15);

rCIIMGCPT|=(1<<30);

rCIIMGCPT|=(1<<31);

}

Camera sensor模块初始化时调用顺序:

voidOV9650_Init(void)

{

CAMIF_Clock_Init();

CAMIF_GPIO_Config();

CAMIF_ResetIF();

CAMIF_ResetMoudle();

CAMIF_Config(0,0);

SCCB_Init();

OV9650_CheckPID();

OV9650_Config();

CAMIF_StartPreview();

CAMIF_StartCapture();

}

执行到这里,你的LCD上就能显示预览的图像了。关于更详细的代码,请下载源码工程自行研究。


百检网秉承“客户至上,服务为先,精诚合作,以人为本”的经营理念,始终站在用户的角度解决问题,为客户提供“一站购物式”的新奇检测体验,打开网站,像挑选商品一样简单,方便。打破行业信息壁垒,建构消费和检测机构之间高效的沟通平台