⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copy of vportcap.c

📁 dm642_video_stream
💻 C
📖 第 1 页 / 共 4 页
字号:
        }            

        pChan->cThrld = (pChan->yThrld + 1) >> 1;

		/*set threshold for both fields*/
        base[_VP_VCATHRLD_OFFSETA] = VP_VCATHRLD_RMK(pChan->yThrld, pChan->yThrld);  
        
        
        base[_VP_VCAEVTCT_OFFSETA] = VP_VCAEVTCT_RMK(
            (pChan->numEvents - pChan->numEventsFld1), pChan->numEventsFld1 );  
        
        pChan->status|=_VPORT_CFGED;
        retVal = IOM_COMPLETED;
    }    
    else if (pChan->chanNum == 1)
    { /*channel B*/
		/* control register  */
        vcCtl = VP_VCBCTL_RMK(0,1,params->fldInv, 
            					params->vCtRst,
            					params->hCtRst, 0, params->bpk10Bit, 0, 0, 
            					params->resmpl,params->scale,1,
            					((params->fldOp & 4) >> 2), 
            					((params->fldOp & 2) >> 1), 
            					(params->fldOp & 1), 
            					params->cmode);

		/*YStart1 value will be put from the 16th bits in VCBSTRT1 register*/
        fld1Strt = params->fldXStrt1 + (params->fldYStrt1 << 16);         
		
		/*YStop1 value will be put from the 16th bits in VCBSTOP1 register*/		                
        fld1Stop = params->fldXStop1 + (params->fldYStop1 << 16);
        
        /*YStart2 value will be put from the 16th bits in VCBSTRT2 register*/
        fld2Strt = params->fldXStrt2 + (params->fldYStrt2 << 16);
        
        /*YStop2 value will be put from the 16th bits in VCBSTOP2 register*/
        fld2Stop = params->fldXStop2 + (params->fldYStop2 << 16);           
        
        if(params->fldOp == VPORT_FLDOP_FRAME) 
        {
            assert(params->fldXStrt1 == params->fldXStrt2);
            assert(params->fldXStop1 == params->fldXStop2);
        }
        
        /* reset channel */
	    base[_VP_VCBCTL_OFFSETB] |=  
	          VP_VCBCTL_RSTCH_RESET << _VP_VCBCTL_RSTCH_SHIFT;
	              
		_delay(2000);
		 
        base[_VP_VCBCTL_OFFSETB]   = vcCtl;
        base[_VP_VCBSTRT1_OFFSETB] = fld1Strt;
        base[_VP_VCBSTOP1_OFFSETB] = fld1Stop;
        base[_VP_VCBSTRT2_OFFSETB] = fld2Strt;
        base[_VP_VCBSTOP2_OFFSETB] = fld2Stop;             
        
        numPixels = params->fldXStop1 - params->fldXStrt1 + 1;/* line size */
        numLines = 0;
        
        if(params->fldOp != VPORT_FLDOP_FLD2)
        {
            numLines += params->fldYStop1 - params->fldYStrt1 + 1;
        }
        
        pChan->numLinesFld1 = numLines;
		pChan->numTotalLinesFld1 = params->fldYStop1;
        
        if(params->fldOp == VPORT_FLDOP_FLD2
          || params->fldOp == VPORT_FLDOP_FRAME)
        {
            numLines += params->fldYStop2 - params->fldYStrt2 + 1;
        }
        
        pChan->resmpl = params->resmpl;
        pChan->scale = params->scale;
        pChan->numLines = numLines;  
        
        numPixels >>= params->scale;
        numCPixels = numPixels >> 1;         
        
        /* set both field1 and field2 threshold to the line size */
        pChan->numPixels = numPixels;
        pChan->lastLineNum = pChan->numLines;  
              
        if(params->cmode & _VPORT_MASK_10BIT)
        {
            /* 10-bit BT.656 or 20-bit Y/C mode */
			if( params->bpk10Bit == VPORTCAP_BPK_10BIT_ZERO_EXTENDED
             	|| params->bpk10Bit == VPORTCAP_BPK_10BIT_SIGN_EXTENDED)
            {
                pChan->yPitch = (numPixels * 2 + 7) & (~ 7);
                pChan->cPitch = (numCPixels * 2 + 7) & (~ 7);
            }
            else
            {
                pChan->yPitch = (numPixels * 4 / 3 + 7) & (~ 7);
                pChan->cPitch = (numCPixels* 4 / 3 + 7) & (~ 7);
            }
        } 
        else 
        {/* 8-bit BT.656 or 16-bit Y/C mode */
            pChan->yPitch = (numPixels + 7) & (~ 7);
            pChan->cPitch = (numCPixels + 7) & (~ 7);
        }
             
        pChan->yThrld = params->thrld;     /* thrld = 88 , number of doublewords threshold in the FIFO*/
		pChan->interlaced = TRUE;

        if(params->mergeFlds && params->fldOp == VPORT_FLDOP_FRAME) 
        { 
            /* merge field comments */
            /* frame capture and merge 2 fields into one frame */
            /* set threshold is same as line size */
            pChan->yThrld = pChan->yPitch >> 3;
            pChan->numEventsFld1 = pChan->numLinesFld1;
            pChan->numEvents = pChan->numLines;
            pChan->mergeFlds = TRUE;  
        }
        else 
        {            
            assert(((pChan->yPitch * pChan->numLinesFld1) / (pChan->yThrld << 3)) 
                *(pChan->yThrld << 3) == (pChan->yPitch * pChan->numLinesFld1));
            assert(((pChan->yPitch * pChan->numLines) / (pChan->yThrld << 3)) 
                *(pChan->yThrld << 3) == (pChan->yPitch * pChan->numLines));
            pChan->numEventsFld1 = 
                pChan->yPitch * pChan->numLinesFld1 / (pChan->yThrld << 3);
            pChan->numEvents = 
                pChan->yPitch * pChan->numLines / (pChan->yThrld << 3);
            pChan->mergeFlds = FALSE;
			if (params->fldOp != VPORT_FLDOP_FRAME) 
				pChan->interlaced = FALSE;
        }            

        pChan->cThrld = (pChan->yThrld + 1) >> 1;

		/*set threshold for both fields*/
        base[_VP_VCBTHRLD_OFFSETB] = VP_VCBTHRLD_RMK(pChan->yThrld, pChan->yThrld);  
        
        
        base[_VP_VCBEVTCT_OFFSETB] = VP_VCBEVTCT_RMK(
            (pChan->numEvents - pChan->numEventsFld1), pChan->numEventsFld1 );  
        
        pChan->status|=_VPORT_CFGED;
        retVal = IOM_COMPLETED;    
    }
    
    return retVal;

}


/*
 *  ======== _configChan ========
 *  configure channel settings
 */
static Int _configChan(Ptr chanp, Ptr args)
{
    VPChanCap_Params *params = (VPChanCap_Params*)args; 
    
    /* configure video port channel A/B control register */
    ConfigChannel(chanp, params);

    /* configure EDMA and frame buffer */
    ConfigTransfer(chanp, params);   
    
    return IOM_COMPLETED;
}


/*
 *  ======== _configPort ========
 *  configure port level registers
 */
static Int _configPort(Ptr chanp, Ptr args)
{
    PortObj* port = (PortObj *)chanp;
    volatile Int *base = (volatile Int *)port->base; 
   
    /* configure video port control register */
    VPORT_PortParams* portParams = (VPORT_PortParams*)args; 
    
    /* enable video port */
    base[_VP_PCR_OFFSET] |= VP_PCR_PEREN_ENABLE << _VP_PCR_PEREN_SHIFT;
                
    /* reset video port */  
    /* VP_VPCTL_VPRST_RESET = 0x00000001u, _VP_VPCTL_VPRST_SHIFT =  0x0000000Fu */
    //base[_VP_VPCTL_OFFSET] |= 
    //    VP_VPCTL_VPRST_RESET << _VP_VPCTL_VPRST_SHIFT;

    base[_VP_VPCTL_OFFSET] = VP_VPCTL_RMK(0,0,0,portParams->vc3Polarity,
        portParams->vc2Polarity,portParams->vc1Polarity,0,0,
        portParams->dualChanEnable);
    
    /* enable video port */
    base[_VP_VPCTL_OFFSET] |= (VP_VPCTL_VPHLT_CLEAR << _VP_VPCTL_VPHLT_SHIFT);	/* clear the video port halt bit */
    port->chanObj[0].edcFxns = portParams->edcTbl[0];
    port->chanObj[1].edcFxns = portParams->edcTbl[1];
    
    IRQ_clear(IRQ_EVT_EDMAINT);
    return IOM_COMPLETED;

}


/*
 *  ======== ConfigTransfer ========
 *  configure channel EDMA settings
 */
static Int ConfigTransfer(Ptr chanp, VPChanCap_Params *params)
{
    _VPORT_ChanObj *pChan = (_VPORT_ChanObj*)chanp;
    Int i;
    EDMA_Config  cfgEdma;
    Int thrld;
    Int8 *curAddr;
    
    if (pChan->status & _VPORT_CFGED) 
    {               
    	/* VPORT_MAX_NUM_FRMBUFS = 10 */
        assert(params->numFrmBufs >= 2 && params->numFrmBufs <= VPORT_MAX_NUM_FRMBUFS);
        
        while (!QUE_empty(&pChan->qIn))       
			QUE_dequeue(&pChan->qIn);
		
		QUE_new(&pChan->qIn);     
        pChan->queEmpty = FALSE;   
        pChan->mrViop = INV;
        pChan->packetIOM = INV;     
        pChan->segId = params->segId;
        
        EDMA_intDisable(pChan->tcc[0]);
        EDMA_intDisable(pChan->tcc[1]);
        
        if (pChan->numFrms == 0) 
        {
            pChan->numFrms = params->numFrmBufs;

            /* allocate frame buffer */  
            /*oldBufSz = pChan->bufSz;*/
            pChan->bufSz = VIDEO_CAP_BUF_MAX_SIZE;/*pChan->yPitch * pChan->numLines 
                  + pChan->cPitch * pChan->numLines * 2;*/
                  
            for (i = 0; i < pChan->numFrms; i ++) 
            {  
            	if (pChan->viops[i].frame.iFrm.y1)  
            	{
	        		/*MEM_free(pChan->segId, pChan->viops[i].frame.iFrm.y1, oldBufSz);*/
	        		curAddr = pChan->viops[i].frame.iFrm.y1;
	        	}
	        	else
	        	{
/*#ifdef DSP_NETWORK_RAWANDENCODED_TEST
					//size of CACHE_L2_LINESIZE of buffer is reserved for header of communication
					if ((curAddr = MEM_calloc(pChan->segId, pChan->bufSz+CACHE_L2_LINESIZE+ENCODED_VIDEO_BUF_SIZE+END_MARK_BYTES, 
	                    params->alignment)) == MEM_ILLEGAL)
	                {
	                    return IOM_EALLOC;
	                }
	                
	                curAddr += (ENCODED_VIDEO_BUF_SIZE+CACHE_L2_LINESIZE);
	                
#else*/
		        	if ((curAddr = MEM_calloc(pChan->segId, pChan->bufSz, params->alignment)) == MEM_ILLEGAL)
	                {
	                    return IOM_EALLOC;
	                }
//#endif
                }
            	
                    
                /* field 1 */
				pChan->viops[i].frame.iFrm.y1 = curAddr;
                curAddr += pChan->numLines * pChan->yPitch;
                pChan->viops[i].frame.iFrm.cb1 = curAddr;
                curAddr += pChan->numLines * pChan->cPitch;
                pChan->viops[i].frame.iFrm.cr1 = curAddr;
                curAddr += pChan->numLines * pChan->cPitch;
                
                /* field 2 */    
                if (params->fldOp == VPORT_FLDOP_FLD2) 
                {
                    pChan->viops[i].frame.iFrm.y2 = pChan->viops[i].frame.iFrm.y1;
                    pChan->viops[i].frame.iFrm.cb2 = pChan->viops[i].frame.iFrm.cb1;
                    pChan->viops[i].frame.iFrm.cr2 = pChan->viops[i].frame.iFrm.cr1;
                }
                else if (!pChan->mergeFlds) 
                {
                    pChan->viops[i].frame.iFrm.y2 = pChan->viops[i].frame.iFrm.y1
                        + pChan->numLinesFld1 * pChan->yPitch;
                    pChan->viops[i].frame.iFrm.cb2 = pChan->viops[i].frame.iFrm.cb1
                        + pChan->numLinesFld1 * pChan->cPitch;
                    pChan->viops[i].frame.iFrm.cr2 = pChan->viops[i].frame.iFrm.cr1
                        + pChan->numLinesFld1 * pChan->cPitch;
                }
                else 
                {   /*merge fields*/
                    pChan->viops[i].frame.iFrm.y2 = pChan->viops[i].frame.iFrm.y1 + pChan->yPitch;
                    pChan->viops[i].frame.iFrm.cb2 = pChan->viops[i].frame.iFrm.cb1 + pChan->cPitch;
                    pChan->viops[i].frame.iFrm.cr2 = pChan->viops[i].frame.iFrm.cr1 + pChan->cPitch;            
                }
                    
                if(i > 1) 
                {
                    /* don't put the first 2 viop into the queue */
                    QUE_enqueue(&pChan->qIn, (QUE_Handle)&pChan->viops[i]);
                }
            }
        }  
          
        CACHE_clean(CACHE_L2ALL, 0, 0);
        
        pChan->curViop = &pChan->viops[0];
        pChan->nextViop = &pChan->viops[1]; 
        
        for(i = 0; i < _VPORT_NUM_EDMA_CHANS; i ++) 
        {   /*Y,U,V*/  
        	/*For first field if merge fields is enabled*/
            Int optFld1 = EDMA_OPT_RMK(params->edmaPri,
						                EDMA_OPT_ESIZE_32BIT,
						                EDMA_OPT_2DS_NO,
						                EDMA_OPT_SUM_NONE,
						                EDMA_OPT_2DD_YES,
						                EDMA_OPT_DUM_INC,   
						                /*donot neet to notify TR complete,
						                field 2 will send it.
						                */
						                EDMA_OPT_TCINT_NO,
						                EDMA_OPT_TCC_OF(0), 
						                EDMA_OPT_TCCM_OF(0),
						                EDMA_OPT_ATCINT_NO,    
						                EDMA_OPT_ATCC_DEFAULT,
						                EDMA_OPT_PDTS_DISABLE,
						                EDMA_OPT_PDTD_DISABLE,
						                EDMA_OPT_LINK_YES,
						                EDMA_OPT_FS_NO
            							);
    
            Int optFld2a = EDMA_OPT_RMK(params->edmaPri,
						                EDMA_OPT_ESIZE_32BIT,
						                EDMA_OPT_2DS_NO,
						                EDMA_OPT_SUM_NONE,
						                EDMA_OPT_2DD_YES,
						                EDMA_OPT_DUM_INC,
						                (i == 0 ? EDMA_OPT_TCINT_YES:EDMA_OPT_TCINT_NO),
						                EDMA_OPT_TCC_OF(i == 0 ? pChan->tcc[0] & 0x0f : 0), 
						                EDMA_OPT_TCCM_OF(i == 0 ? pChan->tcc[0] >> 4 : 0),
						                EDMA_OPT_ATCINT_NO,    
						                EDMA_OPT_ATCC_DEFAULT,
						                EDMA_OPT_PDTS_DISABLE,
						                EDMA_OPT_PDTD_DISABLE,
						                EDMA_OPT_LINK_YES,
						                EDMA_OPT_FS_NO
            							);
			
			Int optFld2b = EDMA_OPT_RMK(params->edmaPri,
						                EDMA_OPT_ESIZE_32BIT,
						                EDMA_OPT_2DS_NO,
						                EDMA_OPT_SUM_NONE,
						                EDMA_OPT_2DD_YES,
						                EDMA_OPT_DUM_INC,
						                (i == 0 ? EDMA_OPT_TCINT_YES:EDMA_OPT_TCINT_NO),
						                EDMA_OPT_TCC_OF(i == 0 ? pChan->tcc[1] & 0x0f : 0), 
						                EDMA_OPT_TCCM_OF(i == 0 ? pChan->tcc[1] >> 4 : 0),
						                EDMA_OPT_ATCINT_NO,    
						                EDMA_OPT_ATCC_DEFAULT,
						                EDMA_OPT_PDTS_DISABLE,
						                EDMA_OPT_PDTD_DISABLE,
						                EDMA_OPT_LINK_YES,
						                EDMA_OPT_FS_NO
							            );

            thrld = (i == 0) ? pChan->yThrld : pChan->cThrld;
            
            cfgEdma.src = EDMA_SRC_RMK(pChan->edmaAddr[i]);
            
            if(pChan->mergeFlds) 
            {
                /* to merge the two fields together */
                /* EDMA is configured to transfer only field 1 initially */
                /* line pitch is twice the line size */
                /* this requires that the threlhold is the same as line size */
                
                /* first field */  
                
                /*according to the document, the value of frame_count equals to the actual count - 1
                  and thrld is derived based on the doublewords, 
                  element count is the number of words here.*/
                cfgEdma.cnt = 
                  EDMA_CNT_RMK((pChan->numEventsFld1) - 1, (thrld << 1));  
                  
                /*field 1 & 2 are interlacedly located in the buffer, layout shows below:
                ////////////////////////////////////////////////
                field1 1st line y
                field2 1st line y
                field1 2rd line y
                field2 2rd line y
                  .
                  .
                  .
                field1 last line y
                field2 last line y
                field1 1st line cb
                field2 1st line cb
                  .
                  .
                  .
                ////////////////////////////////////
                and idx is the address offset to the next array in EDMA configuration,
                
                offset is the double size of the corresponding one line size. 
                if the line size is 704, then thrld is 88(doubleword) for y, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -