📄 camera.c
字号:
if (oCim.m_eInputPath==FIFO && oCim.m_eOutputPath==DMA)
{
if (uSrcCroppingHSz==oCim.m_uDstHsz && uSrcCroppingVSz==oCim.m_uDstVsz)
{
if (oCim.m_eDstFmt==RGB16 || oCim.m_eDstFmt==RGB18 || oCim.m_eDstFmt==RGB24)
oCim.m_bIsScalerBypass = false;
else
oCim.m_bIsScalerBypass = true;
}
else
oCim.m_bIsScalerBypass = false;
}
else
oCim.m_bIsScalerBypass = false;
// 8. Check whether oCim.m_bIsScalerBypass, oCim.m_eOutRotDeg and destination size meet the limitation
//================================================================
if (oCim.m_bIsScalerBypass)
{
Assert(oCim.m_eOutRotDeg == ROT_0); // When ScalerBypass, can not support rotator!
}
if (oCim.m_eInputPath==DMA)
{
Assert(oCim.m_bIsScalerBypass!=true); // Memory input can not support ScalerBypass!
}
if (oCim.m_eProcessPath==P_PATH) // The max horizontal size.-----page 3.
{
if (oCim.m_eOutRotDeg==ROT_0 )
{
if (oCim.m_bIsScalerBypass)
{
Assert(oCim.m_uDstHsz <= SCALER_BYPASS_MAX_HSIZE); //In Pre-view Path, if scaler bypass, the DstHsize should <4096!
}
else
{
Assert(oCim.m_uDstHsz <= SCALER_MAX_HSIZE_P); //In Pre-view Path, if scaler is used, the DstHsize should <640!
}
}
else if (oCim.m_eOutRotDeg==ROT_90 )
{
// In Pre-view Path, if rotation & output is RGB format, the DstHsize should <320!
// if rotation & output is not RGB format, the DstHsize should <160!
if (oCim.m_eDstFmt==RGB16||oCim.m_eDstFmt==RGB18||oCim.m_eDstFmt==RGB24)
{
Assert(oCim.m_uDstHsz <= OUTPUT_MAX_HSIZE_ROT_RGB_P);
}
else
{
Assert(oCim.m_uDstHsz <= OUTPUT_MAX_HSIZE_ROT_RGB_P/2);
}
}
else
{
Assert(0);
}
if (oCim.m_eInRotDeg==ROT_90 )
{
Assert(uSrcCropHsz<=INPUT_MAX_HSIZE_ROT_P&& uSrcCropVsz<=INPUT_MAX_VSIZE_ROT_P);
}
if (oCim.m_bIsScalerBypass)//In Pre-view Path, if scaler bypass, the scaler input horizontal size should <4096!
{
Assert(uSrcCroppingHSz <= SCALER_BYPASS_MAX_HSIZE);
}
}
else // oCim.m_eProcessPath == C_PATH
{
if (oCim.m_eOutRotDeg==ROT_0 )
{
if (oCim.m_bIsScalerBypass)
{
Assert(oCim.m_uDstHsz <= SCALER_BYPASS_MAX_HSIZE); //In Codec Path, if scaler bypass, the DstHsize should <4096!
}
else
{
Assert(oCim.m_uDstHsz <= SCALER_MAX_HSIZE_C); // In Codec Path, if scaler is used, the DstHsize should <1600!
}
}
else if (oCim.m_eOutRotDeg==ROT_90 )
{
//In Codec Path, if rotation & output is RGB format, the DstHsize should <800!
// if rotation & output is not RGB format, the DstHsize should <400!
if (oCim.m_eDstFmt==RGB16 || oCim.m_eDstFmt==RGB18 || oCim.m_eDstFmt==RGB24)
{
Assert(oCim.m_uDstHsz <= OUTPUT_MAX_HSIZE_ROT_RGB_C);
}
else
{
Assert(oCim.m_uDstHsz <= OUTPUT_MAX_HSIZE_ROT_RGB_C/2);
}
}
else
{
Assert(0);
}
if (oCim.m_eInRotDeg==ROT_90 )
{
Assert(uSrcCropHsz<=INPUT_MAX_HSIZE_ROT_C && uSrcCropVsz<=INPUT_MAX_VSIZE_ROT_C);
}
if (oCim.m_bIsScalerBypass) //In Codec Path, if scaler bypass, the scaler input horizontal size should <4096!
{
Assert(uSrcCroppingHSz <= SCALER_BYPASS_MAX_HSIZE);
}
}
// 9. Compute the burst size
//======================================
if ( oCim.m_eDstFmt == RGB16 || oCim.m_eDstFmt==RGB18 || oCim.m_eDstFmt == RGB24)
CAMERA_CalcRgbBurstSize(&oCim.m_uMainBurstSz, &uRemainBurstLen);
else// YCbCr format
CAMERA_CalcYCbCrBurstSize( BURST16, &oCim.m_uMainBurstSz, &uRemainBurstLen, &uCMainBurstLen, &uCRemainBurstLen);
// 10. Calculate the pre-scaler ratio and shift factor
//=======================================
if (!oCim.m_bIsScalerBypass)
{
CAMERA_CalcRatioAndShift(uSrcCroppingHSz, oCim.m_uDstHsz, &uPreHRatio, &uHShift);
CAMERA_CalcRatioAndShift(uSrcCroppingVSz, oCim.m_uDstVsz, &uPreVRatio, &uVShift);
uShiftFactor = 10 - (uHShift + uVShift);
uPreDstHSz = uSrcCroppingHSz/uPreHRatio;
uPreDstVSz = uSrcCroppingVSz/uPreVRatio;
if (oCim.m_eProcessPath==P_PATH)
{
Assert(uPreDstHSz <= SCALER_MAX_HSIZE_P); //In Pre-view Path, if use scaler, the scaler input horizontal size should <640!
}
else
{
Assert(uPreDstHSz <= SCALER_MAX_HSIZE_C); //In Codec Path, if use scaler, the scaler input horizontal size should <1600!
}
uMainHRatio = (uSrcCroppingHSz<<8)/(oCim.m_uDstHsz<<uHShift);
uMainVRatio = (uSrcCroppingVSz<<8)/(oCim.m_uDstVsz<<uVShift);
uLimitHsz = (oCim.m_eProcessPath==P_PATH) ? SCALER_MAX_HSIZE_P: SCALER_MAX_HSIZE_C;
Assert((int)(uSrcHOffset1+uSrcHOffset2) >= (int)(oCim.m_uSrcHsz - uLimitHsz*uPreHRatio)); // Unsupported horizontal offset size
Assert((uSrcCroppingHSz % (4*uPreHRatio) == 0)); //Unsupported horizontal size of cropped window
if (!bIsHScaleUp) // Scaler down
{
Assert(uSrcCroppingVSz % (2*uPreVRatio) == 0); //Unsupported vertical size of cropped window
}
if (oCim.m_eDstFmt==YC420)
{
Assert(uSrcCroppingVSz%2==0 && uSrcCroppingVSz >= 8); // Crop Vsize must be an even number and minimum 8!
}
}
else
{
uPreHRatio = 1, uPreVRatio = 1, uMainHRatio=1, uMainVRatio=1;
uShiftFactor = 10, uPreDstHSz =uSrcCroppingHSz, uPreDstVSz=uSrcCroppingVSz;
}
// 11. Set the register of the source
//====================================
oCim.m_uCigCtrl = ((oCim.m_bHighRst ? 0 : 1)<<30) // Camera A reset
|(1<<29) // Select Camera - 1: Cam A, 0: Cam B
|(BY_PASS<<27) // Test Pattern - 00: BY_PASS 01: COLOR_BAR 10: HORIZONTAL INCR 11: VERTICAL INCR
|((oCim.m_bInvPclk ? 1: 0)<<26) // 1:inverse PCLK
|((oCim.m_bInvVsync ? 1: 0)<<25) // 1:inverse VSYNC
|((oCim.m_bInvHref ? 1: 0)<<24) // 1:inverse HREF
|(0<<22) // Overflow Interrupt - 1: Enable, 0: Disalbe
|(1<<20) // Level Interrupt Enable
|(1<<21); // Href Mask - 1: Mask Out Href during Vsync High, 0: No Mask
Outp32(&CAMERAR->rCIGCTRL, oCim.m_uCigCtrl);
if (oCim.m_eInputPath==FIFO) //Camera input
{
if (oCim.m_uIfBits == 8)
{
uInputIntlvOrder =
(oCim.m_eCamSrcFmt == YCBYCR) ? 0 :
(oCim.m_eCamSrcFmt == YCRYCB) ? 1 :
(oCim.m_eCamSrcFmt == CBYCRY) ? 2 :
(oCim.m_eCamSrcFmt == CRYCBY) ? 3 : 0;
}
else // oCim.m_uIfBits == 16
{
uInputIntlvOrder = (oCim.m_eCamSrcFmt== YCBYCR) ? 0 : (oCim.m_eCamSrcFmt == YCRYCB) ? 1 : 0xffffffff;
if (uInputIntlvOrder == 0xffffffff)
{
Assert(0); // Unsupported YCbYCr 422 order in CCIR601 16 bit mode
}
}
Outp32(&CAMERAR->rCISRCFMT, // Set source format reg.
((oCim.m_eCcir == CCIR601 ? 1 : 0)<<31) // 0: CCIR656, 1: CCIR601
|(0<<30) // UVOffset - 1: +128, 0:+0 (normally used)
|((oCim.m_uIfBits == 16 ? 1 : 0)<<29) // CCIR601 Bits - 1: 16bits, 0: 8bits
|(oCim.m_uSrcHsz<<16)
|(uInputIntlvOrder<<14)
|(oCim.m_uSrcVsz<<0));
uWinOfsEn = ((uSrcHOffset1==0)&&(uSrcHOffset2==0))? 0: 1 ;
Outp32(&CAMERAR->rCIWDOFST, // Set window offset register
(uWinOfsEn<<31) // window offset - 1: Enable, 0: No Offset
|(uSrcHOffset1<<16) // Window horizontal offset1
|(uSrcVOffset1<<0)); // Window Vertical offset1
Outp32(&CAMERAR->rCIDOWFST2, (uSrcHOffset2<<16)|uSrcVOffset2<<0); // window horizontal offset2 and window vertical offset4
Outp32(&CAMERAR->rCIIMGCPT, 0); // Image Cqtpure enable
Outp32(&CAMERAR->rCICPTSEQ, 0xffffffff); // set capture sequence reg.
if (oCim.m_eProcessPath==P_PATH)
{
Outp32(&CAMERAR->rCIMSCTRL, 0);
}
if (oCim.m_eProcessPath==C_PATH)
{
Outp32(&CAMERAR->rMSCOCTRL, 0);
}
}
else // When input come from memory, the address can be computed by the starty_addr, startcr_addr, endy_addr....
{
Outp32(&CAMERAR->rCIIMGCPT, 0); // Image Cqtpure enable
nSrcYCbCrOrder = (oCim.m_eMemSrcFmt ==YCBYCR) ? 3 :
(oCim.m_eMemSrcFmt ==YCRYCB) ? 1 :
(oCim.m_eMemSrcFmt ==CBYCRY) ? 2 : 0;
if (oCim.m_eMemSrcFmt == RGB16||oCim.m_eMemSrcFmt == RGB18||oCim.m_eMemSrcFmt == RGB24)
nSrcFmt = 3;
else if (oCim.m_eMemSrcFmt == YC420)
nSrcFmt = 0;
else if (oCim.m_eMemSrcFmt == YC422)
nSrcFmt = 1;
else
nSrcFmt = 2;
oCim.m_uMSDMACtrl = (nSrcYCbCrOrder<<4)|(1<<3)|(nSrcFmt<<1); // Set MSDMA controller
if (oCim.m_eProcessPath==P_PATH)
Outp32(&CAMERAR->rCIMSCTRL, oCim.m_uMSDMACtrl);
else
Outp32(&CAMERAR->rMSCOCTRL, oCim.m_uMSDMACtrl);
}
// 12. Set the register of the output
//===============================================
nOutFormatPr = (oCim.m_eDstFmt== YC420) ? 0 :(oCim.m_eDstFmt== YC422) ? 1 :
((oCim.m_eDstFmt==RGB16)||(oCim.m_eDstFmt==RGB18)||(oCim.m_eDstFmt == RGB24)) ? 3 : 2;
if (oCim.m_eOutputPath==DMA)
{
if (nOutFormatPr==3)
nOutRGBFMTPr =
(oCim.m_eDstFmt ==RGB16) ? 0 :
(oCim.m_eDstFmt ==RGB18) ? 1 :
(oCim.m_eDstFmt ==RGB24) ? 2 : 3;
else if (nOutFormatPr==2)
nOutputIntlvOrder =
(oCim.m_eDstFmt == YCBYCR) ? 0 :
(oCim.m_eDstFmt == YCRYCB) ? 1 :
(oCim.m_eDstFmt == CBYCRY) ? 2 : 3;
else
{}
}
uOutYSz = (oCim.m_uDstHsz*oCim.m_uDstVsz);
if (oCim.m_eDstFmt == YC422)
uOutCbCrSz = (oCim.m_uDstHsz/2*oCim.m_uDstVsz)*1;
else if (oCim.m_eDstFmt == YC420)
uOutCbCrSz = (oCim.m_uDstHsz/2*oCim.m_uDstVsz/2)*1;
else
uOutCbCrSz = 0;
uTargetFmt = ((oCim.m_eInRotDeg==ROT_90? 1 : 0)<<31) // 1: Input Rotate clockwize 90. 0: Input Rotator bypass.
|(nOutFormatPr<<29)
|((oCim.m_uDstHsz&0x1fff)<<16) // Horizontal size of destination
|(uFlip<<14) // 0: Normal, 1: X-axis mirror, 2: Y-axis mirror, 3: XY-axis(180 degrees) mirror
|((oCim.m_eOutRotDeg==ROT_90 ? 1 : 0)<<13) // 1: Output Rotate clockwize 90. 0: Output Rotator bypass.
|((oCim.m_uDstVsz&0x1fff)<<0); // veritcal size of destination
uDMAControl = (oCim.m_uMainBurstSz<<19) // Main burst of Y length
|(uRemainBurstLen<<14) // Remain burst of Y length
|(uCMainBurstLen<<9) // Main burst of Cb/Cr length
|(uCRemainBurstLen<<4) // Remain burst of Cb/Cr length
|(0<<2) // 1: Enable last IRQ at the end of frame capture, 0: normal
|(nOutputIntlvOrder<<0); // YCbYCr_interleave order
uPreScalerCtrl1 = (uShiftFactor<<28) // shift factor for preview
|(uPreHRatio<<16) // Horizontal ratio of preview pre-scaler
|(uPreVRatio<<0); // Vertical ratio of preview pre-scaler
uPreScalerCtrl2 = (uPreDstHSz<<16) // Destination width for preview pre-scaler
|(uPreDstVSz<<0); // Destination height for preview pre-scaler
oCim.m_uMainScalerCtrl = ((oCim.m_bIsScalerBypass?1:0)<<31) // Pre-view scaler bypass
|(bIsHScaleUp<<30) // Horizontal salce Up/Down flag - 1: Up, 0: Down
|(bIsVScaleUp<<29) // Vertical salce Up/Down flag - 1: Up, 0: Down
|(1U<<28) // YCbCr data dynamic range selection for csc(RGB2YCBCR)
|(1U<<27) // YCbCr data dynamic range selection for csc(YCBCR2RGB)
|(uMainHRatio<<16)
|(3<<13)
|(nOutRGBFMTPr<<11)
|(uMainVRatio<<0);
if (oCim.m_eProcessPath==P_PATH)
{
if (oCim.m_bIsScalerBypass != true)
{
Outp32(&CAMERAR->rCIPRSCPRERATIO, uPreScalerCtrl1); // set preview pre-scaler control reg. 1
Outp32(&CAMERAR->rCIPRSCPREDST, uPreScalerCtrl2); // set preview pre-scaler control reg. 2
}
Outp32(&CAMERAR->rCIPRTRGFMT, uTargetFmt); // Set target format reg
// Outp32(&CAMERAR->rCIPRCTRL, uDMAControl|(1<<2)); // set DMA control reg, enable LastIRQEn
if ((oCim.m_eOutputPath==DMA)) // Pre-view and DMAInput path
{
Outp32(&CAMERAR->rCIPRSCCTRL, oCim.m_uMainScalerCtrl); // set preview main-scaler control reg.
Outp32(&CAMERAR->rCIPRTAREA, oCim.m_uDstVsz*oCim.m_uDstHsz); // set preview DMA target area reg.
switch(oCim.m_eDstFmt)
{
case RGB24:
case RGB18:
case RGB16:
case YCBYCR:
case YCRYCB:
case CBYCRY:
case CRYCBY:
Outp32(&CAMERAR->rCIPRYSA1, uDstAddr0);
Outp32(&CAMERAR->rCIPRYSA2, uDstAddr1);
Outp32(&CAMERAR->rCIPRYSA3, uDstAddr0);
Outp32(&CAMERAR->rCIPRYSA4, uDstAddr1);
break;
case YC422:
case YC420:
Outp32(&CAMERAR->rCIPRYSA1, uDstAddr0);
Outp32(&CAMERAR->rCIPRCBSA1, uDstAddr0 + uOutYSz);
Outp32(&CAMERAR->rCIPRCRSA1, uDstAddr0 + uOutYSz + uOutCbCrSz);
Outp32(&CAMERAR->rCIPRYSA2, uDstAddr1);
Outp32(&CAMERAR->rCIPRCBSA2, uDstAddr1 + uOutYSz);
Outp32(&CAMERAR->rCIPRCRSA2, uDstAddr1 + uOutYSz + uOutCbCrSz);
Outp32(&CAMERAR->rCIPRYSA3, uDstAddr0);
Outp32(&CAMERAR->rCIPRCBSA3, uDstAddr0 + uOutYSz);
Outp32(&CAMERAR->rCIPRCRSA3, uDstAddr0 + uOutYSz + uOutCbCrSz);
Outp32(&CAMERAR->rCIPRYSA4, uDstAddr1);
Outp32(&CAMERAR->rCIPRCBSA4, uDstAddr1 + uOutYSz);
Outp32(&CAMERAR->rCIPRCRSA4, uDstAddr1 + uOutYSz + uOutCbCrSz);
break;
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -