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

📄 vportcap.c

📁 dm642evm板的音视频驱动源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	            chan->numEvents = 
	                chan->yPitch * chan->numLines / (chan->yThrld << 3);
	            if(params->fldOp != VPORT_FLDOP_FRAME) {
	                chan->interlaced = FALSE;
	            }
	        }      
            chan->mergeFlds = params->mergeFlds;
            chan->cThrld = (chan->yThrld + 1) >> 1;
            base[_VP_VCAEVTCT_OFFSETA] = VP_VCAEVTCT_RMK(
                (chan->numEvents-chan->numEventsFld1), chan->numEventsFld1 );  
            base[_VP_VCATHRLD_OFFSETA] = VP_VCATHRLD_RMK(chan->yThrld,chan->yThrld);
	    } else { /* raw capture */
	        VPORTCAP_ParamsRaw *paramsRaw = (VPORTCAP_ParamsRaw *)params;     
	        Int totalNumPixels = paramsRaw->lineSz * paramsRaw->numLines;  
	        Int totalBytesPerFrame;
	        
	        /* make sure the number is in the correct range */
	        assert(totalNumPixels < 2^24);
	        
	        /* configure channel A capture settings  */
	        vcCtl = VP_VCACTL_RMK(0, 1, 0, 0, 0, 0, 0, 0, 0, 
	            paramsRaw->bpk10Bit, 0, 0, 0, 0, 1, 0,0, 0, paramsRaw->cmode);
	
	        /* reset channel */
	        base[_VP_VCACTL_OFFSETA] |=  
	          VP_VCACTL_RSTCH_RESET << _VP_VCACTL_RSTCH_SHIFT;
	        _delay(2000);
	        base[_VP_VCACTL_OFFSETA]   = vcCtl;
	        base[_VP_VCASTRT1_OFFSETA] 
	            = VP_VCASTRT1_RMK(1, paramsRaw->startupSyncEnable, 
	                              paramsRaw->blankperiod);
	                              
	        base[_VP_VCASTOP1_OFFSETA] 
	         = VP_VCASTOP1_RMK((totalNumPixels >> 12), (totalNumPixels & 0xFFF));

	        chan->resmpl = FALSE;
	        chan->scale = FALSE;
	        
            if( paramsRaw->cmode == VPORT_MODE_RAW_16BIT ) {
                totalBytesPerFrame = paramsRaw->lineSz * 2 * paramsRaw->numLines;
            } else if(paramsRaw->cmode == VPORT_MODE_RAW_20BIT) {
                totalBytesPerFrame = paramsRaw->lineSz * 4 * paramsRaw->numLines;            
            } else if(paramsRaw->cmode == VPORT_MODE_RAW_10BIT){ 
	            if( paramsRaw->bpk10Bit == VPORTCAP_BPK_10BIT_ZERO_EXTENDED
	             || paramsRaw->bpk10Bit == VPORTCAP_BPK_10BIT_SIGN_EXTENDED){
	             /* each 10-bit pixel takes 2 bytes */
	                totalBytesPerFrame = paramsRaw->lineSz * 2 * paramsRaw->numLines;
                } else { /* dense packing, 3 10-bit pixel takes 4 bytes */
	                /* make sure this is dividable */
	                assert((paramsRaw->lineSz * paramsRaw->numLines / 3) * 3 == 
	                    paramsRaw->lineSz * paramsRaw->numLines );
	                totalBytesPerFrame = paramsRaw->lineSz * 4 * paramsRaw->numLines / 3;                
                }            
            
            } else { /* 8-bit raw mode */
                totalBytesPerFrame = paramsRaw->lineSz * paramsRaw->numLines;
                
            }

	        chan->yPitch = paramsRaw->thrld << 3;
	        chan->cPitch = 0;
	        chan->yThrld = paramsRaw->thrld;
	        chan->interlaced = FALSE;  
            chan->mergeFlds = FALSE;
            chan->cThrld = 0;
            
            assert(totalBytesPerFrame / chan->yPitch * chan->yPitch == totalBytesPerFrame);
            chan->numLines = totalBytesPerFrame / chan->yPitch;   
            chan->numEvents = chan->numLines;
            base[_VP_VCATHRLD_OFFSETA] = VP_VCATHRLD_RMK(chan->yThrld,chan->yThrld);

	    } /* if(!(chan->mode & _VPORT_MASK_RAW)) */

        chan->status|=_VPORT_CFGED;
        retVal = IOM_COMPLETED;
    }    
    return retVal;

}


/*
 *  ======== _configChan ========
 *  configure channel settings
 */
static Int _configChan(Ptr chanp, Ptr args)
{
    VPORTCAP_Params*   params = (VPORTCAP_Params*)args; 

    
    
    /* configure video port channel A/B control register */
    _configCh(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 */
    base[_VP_VPCTL_OFFSET] |= 
        VP_VPCTL_VPRST_RESET << _VP_VPCTL_VPRST_SHIFT;
    while(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);
    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, 
        VPORTCAP_Params  *params
        )
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    Int i;
    EDMA_Config  cfgEdma;
    Int thrld;
    Int8* curAddr;
    Int numEdmaChans;   
    VPORTCAP_ParamsRaw *paramsRaw = (VPORTCAP_ParamsRaw *)params;
    Int numFrmBufs;              
    Int segId;            
    Int alignment;    
    Int irqId;
    Int edmaPri;
    
    if(!(params->cmode & _VPORT_MASK_RAW)) {
        numFrmBufs = params->numFrmBufs;
        segId = params->segId;
        alignment = params->alignment;
        irqId = params->irqId;
        edmaPri = params->edmaPri;
    } else {
        numFrmBufs = paramsRaw->numFrmBufs;
        segId = paramsRaw->segId;        
        alignment = paramsRaw->alignment;
        irqId = paramsRaw->irqId;
        edmaPri = paramsRaw->edmaPri;
    }    
    if(chan->status & _VPORT_CFGED) {
     
        assert(numFrmBufs >= 2 && numFrmBufs 
                <= VPORT_MAX_NUM_FRMBUFS);
        QUE_new(&chan->qIn);     
        chan->queEmpty = FALSE;   
        chan->mrViop = INV;
        chan->packetIOM = INV;     
        chan->segId = segId;
        
        EDMA_intDisable(chan->tcc[0]);
        EDMA_intDisable(chan->tcc[1]);
        
        if(chan->numFrms == 0) {
            chan->numFrms = numFrmBufs;

            /* allocate frame buffer */
            chan->bufSz = chan->yPitch * chan->numLines 
                  + chan->cPitch * chan->numLines * 2;
            for(i = 0; i < chan->numFrms; i ++) {                    
                if((curAddr = MEM_calloc(segId,chan->bufSz, 
                    alignment)) == MEM_ILLEGAL){
                    return IOM_EALLOC;
                }    
                /* field 1 */
                chan->viops[i].frame.iFrm.y1 = curAddr;
                if(!(params->cmode & _VPORT_MASK_RAW)) {
                    curAddr += chan->numLines*chan->yPitch;
                    chan->viops[i].frame.iFrm.cb1 = curAddr;
                    curAddr += chan->numLines*chan->cPitch;
                    chan->viops[i].frame.iFrm.cr1 = curAddr;
                    curAddr += chan->numLines*chan->cPitch;
                    /* field 2 */    
	                if(params->fldOp == VPORT_FLDOP_FLD2) {
	                    chan->viops[i].frame.iFrm.y2 = 
	                        chan->viops[i].frame.iFrm.y1;
	                    chan->viops[i].frame.iFrm.cb2 = 
	                        chan->viops[i].frame.iFrm.cb1;
	                    chan->viops[i].frame.iFrm.cr2 = 
	                        chan->viops[i].frame.iFrm.cr1;
	                }
	                else if(! chan->mergeFlds) {
	                    chan->viops[i].frame.iFrm.y2 = 
	                      chan->viops[i].frame.iFrm.y1
	                        + chan->numLinesFld1*chan->yPitch;
	                    chan->viops[i].frame.iFrm.cb2 = 
	                      chan->viops[i].frame.iFrm.cb1
	                        + (chan->numLinesFld1*chan->cPitch);
	                    chan->viops[i].frame.iFrm.cr2 = 
	                      chan->viops[i].frame.iFrm.cr1
	                        + (chan->numLinesFld1*chan->cPitch);
	                }else {
	                    chan->viops[i].frame.iFrm.y2 = 
	                      chan->viops[i].frame.iFrm.y1 + chan->yPitch;
	                    chan->viops[i].frame.iFrm.cb2 = 
	                      chan->viops[i].frame.iFrm.cb1 + chan->cPitch;
	                    chan->viops[i].frame.iFrm.cr2 = 
	                      chan->viops[i].frame.iFrm.cr1 + chan->cPitch;            
	                }    
	            }
            }
        }    
        for(i = 2; i < chan->numFrms; i ++)  {
            /* don't put the first 2 viop into the queue */
            QUE_enqueue(&chan->qIn, (QUE_Handle)&chan->viops[i]);
        }
        chan->curViop = &chan->viops[0];
        chan->nextViop = &chan->viops[1]; 
        if(chan->mode & _VPORT_MASK_RAW) {
            numEdmaChans = 1; 
        } else {
            numEdmaChans = _VPORT_NUM_EDMA_CHANS;
        }
        for(i = 0; i < numEdmaChans; i ++) {
            Int optFld1 = EDMA_OPT_RMK(
                edmaPri,
                EDMA_OPT_ESIZE_32BIT,
                EDMA_OPT_2DS_NO,
                EDMA_OPT_SUM_NONE,
                EDMA_OPT_2DD_YES,
                EDMA_OPT_DUM_INC,
                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(
                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 ? chan->tcc[0] & 0x0f : 0), 
                EDMA_OPT_TCCM_OF(i == 0 ? chan->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(
                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 ? chan->tcc[1] & 0x0f : 0), 
                EDMA_OPT_TCCM_OF(i == 0 ? chan->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) ? chan->yThrld : chan->cThrld;
            cfgEdma.src = EDMA_SRC_RMK(chan->edmaAddr[i]);
            if(chan->interlaced) {
                /* 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 */
                cfgEdma.cnt = 
                  EDMA_CNT_RMK((chan->numEventsFld1) - 1, (thrld << 1));
                if(chan->mergeFlds) {
                    cfgEdma.idx = EDMA_IDX_RMK(thrld << 4, 0);
                } else {
                    cfgEdma.idx = EDMA_IDX_RMK(thrld << 3, 0);                
                }
    
                /* hard code the first two frames as current and reload buffers */                
                /* first field */
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i + 1]);
                cfgEdma.opt = optFld1;
                cfgEdma.dst = 
                  EDMA_DST_RMK(*((Int *)(&chan->viops[0].frame.iFrm.y1) + i));
                EDMA_config(chan->hEdma[i], &cfgEdma);
                EDMA_config(chan->hRld[4 * i], &cfgEdma); 
                cfgEdma.dst = 
                  EDMA_DST_RMK(*((Int *)(&chan->viops[1].frame.iFrm.y1) + i));
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i + 3]);

⌨️ 快捷键说明

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