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

📄 vportcap.c

📁 dm642evm板的音视频驱动源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
                EDMA_config(chan->hRld[4 * i + 2], &cfgEdma);

                /* second field */
                cfgEdma.opt = optFld2a;
                cfgEdma.cnt = 
                  EDMA_CNT_RMK((chan->numEvents-chan->numEventsFld1) - 1, 
                   (thrld << 1));
                cfgEdma.dst = 
                  EDMA_DST_RMK(*((Int *)(&chan->viops[0].frame.iFrm.y2) + i));
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i + 2]);
                EDMA_config(chan->hRld[4 * i + 1], &cfgEdma); 
                cfgEdma.opt = optFld2b;
                cfgEdma.dst = 
                  EDMA_DST_RMK(*((Int *)(&chan->viops[1].frame.iFrm.y2) + i));
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i]);
                EDMA_config(chan->hRld[4 * i + 3], &cfgEdma);
                
            }else {/* if not interlaced capture, configure EDMA to transfer */
                   /* the whole frame. The line pitch is just the line size */
                cfgEdma.opt = optFld2a;
                cfgEdma.cnt = EDMA_CNT_RMK((chan->numEvents) - 1, (thrld << 1));
                cfgEdma.idx = EDMA_IDX_RMK(thrld << 3, 0);
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i + 2]);
                /* hard code the first and second frame buffer as current  */
                /* and reload buffers */
                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.opt = optFld2b;
                cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[4 * i]);
                cfgEdma.dst = EDMA_DST_RMK(
                    *((Int *)(&chan->viops[1].frame.iFrm.y1) + i));
                EDMA_config(chan->hRld[4 * i + 2], &cfgEdma);
            }
        }
        chan->nextEDMARlds = 1;        
        /* enable EDMA channel */
        /*
         * The EDMA interrupt dispatcher will be called by the
         * BIOS HWI interrupt dispatcher.
         */
        IRQ_map(IRQ_EVT_EDMAINT, irqId);
        HWI_dispatchPlug(irqId, (Fxn)EDMA_intDispatcher, -1, NULL);
        
        EDMA_intClear(chan->tcc[0]);
        EDMA_intHook(chan->tcc[0], captureEdmaISR);       
        EDMA_intEnable(chan->tcc[0]);
        EDMA_intClear(chan->tcc[1]);
        EDMA_intHook(chan->tcc[1], captureEdmaISR);       
        EDMA_intEnable(chan->tcc[1]);
        for(i = 0; i < numEdmaChans; i ++) {
            EDMA_disableChannel(chan->hEdma[i]);
            EDMA_clearChannel(chan->hEdma[i]);
            EDMA_enableChannel(chan->hEdma[i]);
        }    
        chan->status |= _VPORT_READY;
        IRQ_enable(IRQ_EVT_EDMAINT);
        
    }   
    return IOM_COMPLETED;

}

/*
 *  ======== _covrRecover ========
 *  force recover from FIFO over-run
 */
static Int _covrRecover(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj* )chanp;
    PortObj* port = &portObjs[chan->portNum];
    volatile Int *base = (volatile Int *)port->base;
    volatile Int *cbase = (volatile Int *)chan->base;    
    Int numEvents;  
    volatile Int i;            
    Int numEdmaChans;                                

    /* disable over-run interrupt */
    base[_VP_VPIE_OFFSET] &= ~(_VP_VPIE_COVRA_MASK<<(chan->chanNum*16));
    /* block capture events */
    cbase[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;

    /* Disable the edmas before settings them up */
    EDMA_intDisable(chan->tcc[0]);
    EDMA_intDisable(chan->tcc[1]);
    if(chan->mode & _VPORT_MASK_RAW) {
        numEdmaChans = 1;
    }else {
        numEdmaChans = _VPORT_NUM_EDMA_CHANS;
    }
    for(i = 0; i < numEdmaChans; i ++) {
        EDMA_disableChannel(chan->hEdma[i]);
        EDMA_clearChannel(chan->hEdma[i]);
    }
    if(chan->mergeFlds) {
        numEvents = chan->numEventsFld1;        
    } else {
        numEvents = chan->numEvents;
    }

    /* set up DMA parameters again */
    EDMA_RSETH(chan->hEdma[0], DST, chan->curViop->frame.iFrm.y1);
    EDMA_RSETH(chan->hEdma[0], CNT, EDMA_CNT_RMK(numEvents - 1, 
        (chan->yThrld << 1)));
    if(!(chan->mode & _VPORT_MASK_RAW)) {
	    EDMA_RSETH(chan->hEdma[1], DST, chan->curViop->frame.iFrm.cb1);
	    EDMA_RSETH(chan->hEdma[2], DST, chan->curViop->frame.iFrm.cr1);
	    EDMA_RSETH(chan->hEdma[1], CNT, EDMA_CNT_RMK(numEvents - 1, 
	        (chan->cThrld << 1)));
	    EDMA_RSETH(chan->hEdma[2], CNT, EDMA_CNT_RMK(numEvents - 1, 
	        (chan->cThrld<<1)));
    }
    /* enable the edma events again before settings them up */
    EDMA_intEnable(chan->tcc[0]);
    EDMA_intEnable(chan->tcc[1]);
    for(i = 0;i < numEdmaChans;i ++) {
        EDMA_enableChannel(chan->hEdma[i]);
    }

    /* clear any pending over-run interrupt */
    if(chan->chanNum == 0) {
        base[_VP_VPIS_OFFSET] |= _VP_VPIS_COVRA_MASK;
    }else {
        base[_VP_VPIS_OFFSET] |= _VP_VPIS_COVRB_MASK;
    }    
    /* enable event generation */
    cbase[_VP_VCACTL_OFFSETA] &= ~(_VP_VCACTL_BLKCAP_MASK);

    /* enable over-run interrupt */
    base[_VP_VPIE_OFFSET] |= _VP_VPIE_COVRA_MASK << (chan->chanNum * 16);
    return IOM_COMPLETED;
}

/*
 *  ======== _getNumPendingIORqsts ========
 *  get number of frames in qIn
 */
static Int _getNumPendingIORqsts(Ptr chanp, Ptr args)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    QUE_Handle nextElem = &chan->qIn;
    int i  = 0;
    while((nextElem = QUE_next(nextElem)) != &chan->qIn){
        i++;
    
    }
    if(chan->curViop != chan->nextViop) i++;
    *(int *)args = i;
    return IOM_COMPLETED;
}

/*
 *  ======== _setVIntCb ========
 *  setup video port interrupt call-back
 */
static Int _setVIntCb(Ptr chanp, Ptr args)
{      
    _VPORT_ChanObj* chan = (_VPORT_ChanObj* )chanp;
    PortObj* port = &portObjs[chan->portNum];
    volatile Int *base = (volatile Int *)port->base;
    volatile Int *cBase = (volatile Int *)chan->base;
    VPORT_VIntCbParams* vIntCbParams = (void *)args;
    Int mask = vIntCbParams->vIntMask;
    Uns vif2 = 0, vInt2 = 0, vif1 = 0, vInt1 = 0, fscl2 = 0;
    HWI_Attrs attrs = HWI_ATTRS;
    
    
    /* check to see if vertical interrupt is enabled */
    if(mask & VPORT_INT_VINT1) {
        vif1 = 1;
        vInt1 = vIntCbParams->vIntLine;
    }
    if(mask & VPORT_INT_VINT2) {
        vif2 = 1;
        vInt2 = vIntCbParams->vIntLine;    
    }
    fscl2 = vif2 & (~ vif1);
    /* setup vertical interrupt */
    cBase[_VP_VCAVINT_OFFSETA] = VP_VCAVINT_RMK(vif2,fscl2, 
        vInt2, vif1, vInt1);
    
    if(chan->chanNum == 1) {
        mask <<= 16;    /* channel B */
    }
    chan->vIntMask = mask;
    if(mask) {
        mask |= 1; /* turn on video port interrupt */
        attrs.arg = chan->portNum;
        IRQ_map(IRQ_EVT_VINT0 + chan->portNum, vIntCbParams->irqId);    
        HWI_dispatchPlug(vIntCbParams->irqId, (Fxn)captureISR, -1, &attrs);
        IRQ_disable(IRQ_EVT_VINT0 + chan->portNum);
        IRQ_clear(IRQ_EVT_VINT0 + chan->portNum);
    }
    base[_VP_VPIE_OFFSET] |= mask;  /* register write */    
    chan->vIntFxn = vIntCbParams->vIntCbFxn;    
    chan->vIntCbArg = vIntCbParams->cbArg;
    return IOM_COMPLETED;   
}      

/*
 *  ======== _startVPCapture ========
 *  start video port capture operation
 */
static Int _startVPCapture(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj* )chanp;
    PortObj* port = &portObjs[chan->portNum];
    volatile Int *base = (volatile Int *)port->base;
    volatile Int *cbase = (volatile Int *)chan->base;    

    /* enable channel */
    cbase[_VP_VCACTL_OFFSETA] |= VP_VCACTL_VCEN_ENABLE << _VP_VCACTL_VCEN_SHIFT;

    /* clear the block capture event mask bit to enable */
    /* generating capture events                        */
    cbase[_VP_VCACTL_OFFSETA] &= ~ (_VP_VCACTL_BLKCAP_MASK);
      
    /* enable interrupt generation in video port level */
    base[_VP_VPIE_OFFSET] |= VP_VPIE_VIE_ENABLE << _VP_VPIE_VIE_SHIFT;
    base[_VP_VPIS_OFFSET] |= 0XFFFFFFFF;
    /* clear any pending video port interrupt */
    IRQ_clear(IRQ_EVT_VINT0 + chan->portNum);
    /* enable corresponding video port interrupt in chip-level*/
    IRQ_enable(IRQ_EVT_VINT0 + chan->portNum);
    
    return IOM_COMPLETED;
}

/*
 *  ======== _stopVPCapture ========
 *  stop video port capture operation
 */
static Int _stopVPCapture(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj* )chanp;
    PortObj* port = &portObjs[chan->portNum];
    volatile Int *cbase = (volatile Int *)chan->base;    
    volatile Int *base = (volatile Int *)port->base;

    /* block events generation */
    cbase[_VP_VCACTL_OFFSETA] |= (_VP_VCACTL_BLKCAP_MASK);

    /* disable channel */
    cbase[_VP_VCACTL_OFFSETA] &= 
        ~ (VP_VCACTL_VCEN_ENABLE << _VP_VCACTL_VCEN_SHIFT);

    /* disable interrupt generation in video port level */
    base[_VP_VPIE_OFFSET] &= ~ (VP_VPIE_VIE_ENABLE << _VP_VPIE_VIE_SHIFT);
    base[_VP_VPIS_OFFSET] |= 0XFFFFFFFF;
    
    /* disble corresponding video port interrupt in chip-level*/
    IRQ_disable(IRQ_EVT_VINT0 + chan->portNum);

    /* clear any pending video port interrupt */
    IRQ_clear(IRQ_EVT_VINT0 + chan->portNum);
    
    EDMA_intDisable(chan->tcc[0]);
    EDMA_intClear(chan->tcc[0]);

    EDMA_intDisable(chan->tcc[1]);
    EDMA_intClear(chan->tcc[1]);

    return IOM_COMPLETED;
}



/*
 *  ======== captureISR ========
 */
static void captureISR(Int portNum)
{
    volatile Int *base =  
        (volatile Int *)portObjs[portNum].base;
    Int vpis = base[_VP_VPIS_OFFSET];
    Int mask = vpis;
    _VPORT_ChanObj* chanObjs = portObjs[portNum].chanObj;
        
    if(vpis & chanObjs[0].vIntMask && chanObjs[0].vIntFxn != INV) {
        chanObjs[0].vIntFxn(chanObjs[0].vIntCbArg, vpis);
        mask &=  chanObjs[0].vIntMask;
    }else if(vpis & chanObjs[1].vIntMask && chanObjs[1].vIntFxn != INV) {
        chanObjs[1].vIntFxn(chanObjs[1].vIntCbArg, (vpis >> 16));
        mask &=  chanObjs[1].vIntMask;
    }
    /* clear interrupts that has been handled */
    base[_VP_VPIS_OFFSET] |= mask;
}

static void _delay(Int delayTime)
{
    asm("loop1: BDEC loop1, A4");
    asm(" NOP 5");

}

static void _autoSync(_VPORT_ChanObj* chan) 
{
    volatile Int *cbase = (volatile Int *)chan->base;    
    volatile Int fid_stat = 
      (cbase[_VP_VCASTAT_OFFSETA] & _VP_VCASTAT_VCFLD_MASK) 
      >> _VP_VCASTAT_VCFLD_SHIFT;
    volatile Int ypos = 
     (cbase[_VP_VCASTAT_OFFSETA] & _VP_VCASTAT_VCYPOS_MASK) 
      >> _VP_VCASTAT_VCYPOS_SHIFT;
    Int offset = chan->nextEDMARlds << 1;

    if(chan->interlaced && ( fid_stat == 0 && ypos >= chan->numTotalLinesFld1
      || fid_stat == 1 && ypos <= chan->numLinesFld1)){
        /* Reconfig the EDMA to link to field 0 of the current transfer */
        EDMA_link(chan->hEdma[0], chan->hRld[offset]);
        EDMA_link(chan->hEdma[1], chan->hRld[offset+4]);
        EDMA_link(chan->hEdma[2], chan->hRld[offset+8]);
    } 
}




⌨️ 快捷键说明

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