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

📄 vportdis.c

📁 使用DM642 來進行scaling 有說明檔
💻 C
📖 第 1 页 / 共 4 页
字号:
    if(chanObjs[portNum].asyncModeEnable) {
        if(chanObjs[portNum].interlaced && (mask & VPORT_INT_VINT2) 
        ||!chanObjs[portNum].interlaced && (mask & VPORT_INT_VINT1) )
        _frmAlmostCmopleteIsr(portNum);
    } else if(mask && chanObjs[portNum].vIntFxn != INV) {
        chanObjs[portNum].vIntFxn(chanObjs[portNum].vIntCbArg, mask);
    }
    /* clear interrupts that has been handled */
    base[_VP_VPIS_OFFSET] |= vpis;
}  


/*
 *  ======== _displayStart ========
 *  start video display
 */
static Int _displayStart(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    volatile Int* base = (volatile Int *)chan->base;  
    volatile Int stat;
    volatile Int i = 0;
                                      
    /* enable port and display */
    base[_VP_VPCTL_OFFSET] |= VP_VPCTL_VPHLT_CLEAR << _VP_VPCTL_VPHLT_SHIFT;
    base[_VP_VDCTL_OFFSET] |= VP_VDCTL_VDEN_ENABLE << _VP_VDCTL_VDEN_SHIFT;
    /* wait for display counters and control signals to sync up */
    do {
        stat = base[_VP_VDSTAT_OFFSET];
        i ++ ;
    }while(!(stat & 0x70000000) && i < 1000000);
    base[_VP_VDSTAT_OFFSET] = stat;
    
    do {
        stat = base[_VP_VDSTAT_OFFSET];
        i ++;
    }while(!(stat & 0x70000000) && i < 1000000);
    base[_VP_VDSTAT_OFFSET] = stat;
    base[_VP_VDCTL_OFFSET] &= ~ (_VP_VDCTL_BLKDIS_MASK);
    /* enable interrupt */
    base[_VP_VPIE_OFFSET] |= VP_VPIE_VIE_ENABLE << _VP_VPIE_VIE_SHIFT;     
    base[_VP_VPIS_OFFSET] |= 0XFFFFFFFF;    
    IRQ_clear(IRQ_EVT_VINT0 + chan->portNum);
    IRQ_enable(IRQ_EVT_VINT0 + chan->portNum);
    return IOM_COMPLETED;
}        


/*                                              
 *  ======== _displayStop ========
 *  stop video display
 */
static Int _displayStop(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    volatile Int* base = (volatile Int *)chan->base;    
    
    
    base[_VP_VDCTL_OFFSET] &= ~  (VP_VDCTL_VDEN_ENABLE << _VP_VDCTL_VDEN_SHIFT);
    return IOM_COMPLETED;
}


/*
 *  ======== _dundRecover ========
 *  force recover from display under-run
 */
static Int _dundRecover(Ptr chanp)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    Int i;          
    Int stat;
    Int numEvents;
    volatile Int* base = (volatile Int *)chan->base;  
    
    
    /* disable under run interrupt */
    base[_VP_VPIE_OFFSET] &= ~ (_VP_VPIE_DUND_MASK);
    /* clear any pending under-run interrupt */
    base[_VP_VPIS_OFFSET] &= ~ (_VP_VPIS_DUND_MASK);

     /* block display events */
    base[_VP_VDCTL_OFFSET] |= _VP_VDCTL_BLKDIS_MASK;
    /* Disable the edmas before settings them up */
    if(!(chan->mode & _VPORT_MASK_RAW)){
        EDMA_disableChannel(chan->hEdma[1]);
        EDMA_clearChannel(chan->hEdma[1]);
        EDMA_disableChannel(chan->hEdma[2]);
        EDMA_clearChannel(chan->hEdma[2]);
    }
    EDMA_intDisable(chan->tcc[0]);
    EDMA_intDisable(chan->tcc[1]);
    EDMA_disableChannel(chan->hEdma[0]);            
    EDMA_clearChannel(chan->hEdma[0]);
    

    if(chan->mergeFlds) {
        numEvents = chan->numEventsFld1;        
    } else {
        numEvents = chan->numEvents;
    }
    /* set up DMA parameters again */
    EDMA_RSETH(chan->hEdma[0], SRC, 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], SRC, chan->curViop->frame.iFrm.cb1);
        EDMA_RSETH(chan->hEdma[2], SRC, 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_enableChannel(chan->hEdma[1]);
    EDMA_enableChannel(chan->hEdma[2]);          
   
    EDMA_intEnable(chan->tcc[0]);
    EDMA_intEnable(chan->tcc[1]);
    EDMA_enableChannel(chan->hEdma[0]);

    base[_VP_VDCTL_OFFSET] |= VP_VDCTL_VDEN_ENABLE << _VP_VDCTL_VDEN_SHIFT;
    /* wait for display counters and control signals to sync up */
    do {
        stat = base[_VP_VDSTAT_OFFSET];
        i ++ ;
    }while(!(stat & 0x70000000) && i < 1000000);
    base[_VP_VDSTAT_OFFSET] = stat;
    
    do {
        stat = base[_VP_VDSTAT_OFFSET];
        i ++;
    }while(!(stat & 0x70000000) && i < 1000000);

    base[_VP_VDCTL_OFFSET] &= ~(_VP_VDCTL_BLKDIS_MASK);
    /* re-enable under run interrupt */
    base[_VP_VPIE_OFFSET] |= _VP_VPIE_DUND_MASK;
    return IOM_COMPLETED;

}

/*
 *  ======== _getlastActiveLine ========
 *  get the line number of the last active line
 */
static Int _getlastActiveLine(VPORTDIS_Params* params)
{
    int lastActiveLine = -1;
    switch (params->fldOp){
        case VPORT_FLDOP_FRAME:
        case VPORT_FLDOP_FLD2:  
            lastActiveLine = params->vBlnkYStopFld2 
              + params->imgVOffsetFld2
              + params->imgVSizeFld2;
            
       break;                      
        case VPORT_FLDOP_FLD1:
        case VPORT_FLDOP_PROGRESSIVE:
            lastActiveLine = params->vBlnkYStopFld1 
              + params->imgVOffsetFld1
              + params->imgVSizeFld1;
        break;        
    }
    return lastActiveLine;
}    

/*
 *  ======== _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 ========
 *  set video port interrutp call-back
 */
static Int _setVIntCb(Ptr chanp, Ptr args)
{
    _VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
    volatile Int* base = (volatile Int *)chan->base;  
    VPORT_VIntCbParams* vIntCbParams = (void *)args;
    Int mask = vIntCbParams->vIntMask;
    Uns vif2 = 0, vInt2 = 0, vif1 = 0, vInt1 = 0;
    HWI_Attrs attrs = HWI_ATTRS;


    chan->vIntMask = mask;
    /* check to see if vertical interrupt is enabled */
    if(!chan->asyncModeEnable) {
        if(mask & VPORT_INT_VINT1) {
            vif1 = 1;
            vInt1 = vIntCbParams->vIntLine;
        }
        if(mask & VPORT_INT_VINT2) {
            vif2 = 1;
            vInt2 = vIntCbParams->vIntLine;    
        }        
    } else {
        return IOM_EINUSE;    
    }
    base[_VP_VDVINT_OFFSET] = VP_VDVINT_RMK(vif2, 
        vInt2, vif1, vInt1);
    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)displayISR, -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;
}

static Int  _frmAlmostCmopleteIsr(int portNum)
{

    _VPORT_ChanObj* chan = &chanObjs[portNum];
    FVID_Frame *viop, *viopOut;                             
    Uint32 gie = IRQ_globalDisable();     
    Int offset = chan->nextEDMARlds << 1;
    
    if(!chan->startFlag) return -1;
    assert(chan->asyncCallBackFxn != INV);
    if((viop = (FVID_Frame *)QUE_dequeue(&chan->qOut))
        ==(FVID_Frame *)&chan->qOut) {
        /* queue enpty */
        viop = INV;            
    }
    viopOut = viop;
    if(chan->pullDownMode == VPORTDIS_PULLDOWN_24P_30I){
        if(chan->asyncFrameCt < 2){    /* 0, 1 */
            chan->asyncCallBackFxn(chan->asyncCbArg, chan->asyncFrameCt, &viopOut);
            if(viop == viopOut && viopOut != INV){
                QUE_enqueue(&chan->qOut, viopOut);
            } else if(viopOut != INV){
                chan->nextViop = viopOut;
                /* now modify the EDMA rld entries */
                EDMA_RSETH(chan->hRld[offset], SRC, 
                    viopOut->frame.iFrm.y1);
                EDMA_RSETH(chan->hRld[offset + 1], SRC, 
                    viopOut->frame.iFrm.y2);
                if(!(chan->mode & _VPORT_MASK_RAW)){
                    EDMA_RSETH(chan->hRld[4 + offset], SRC, 
                      viopOut->frame.iFrm.cb1);     
                    EDMA_RSETH(chan->hRld[5 + offset], SRC, 
                      viopOut->frame.iFrm.cb2);                         
                    EDMA_RSETH(chan->hRld[8 + offset], SRC, 
                      viopOut->frame.iFrm.cr1);     
                    EDMA_RSETH(chan->hRld[9 + offset], SRC, 
                      viopOut->frame.iFrm.cr2);              
                }           
                chan->asyncFrameCt ++;                           
            } else {
                chan->asyncFrameCt = 0;
            }
        }else if(chan->asyncFrameCt < 4) { /* 2, 3 */
            chan->asyncCallBackFxn(chan->asyncCbArg, chan->asyncFrameCt, &viopOut);
            if(viop == viopOut && viopOut != INV){
                QUE_enqueue(&chan->qOut, viopOut);
            } else if(viopOut != INV){
                chan->nextViop = viopOut;
                EDMA_RSETH(chan->hRld[offset + 1], SRC, 
                    viopOut->frame.iFrm.y2);
                if(!(chan->mode & _VPORT_MASK_RAW)){
                    EDMA_RSETH(chan->hRld[5 + offset], SRC, 
                          viopOut->frame.iFrm.cb2);                         
                    EDMA_RSETH(chan->hRld[9 + offset], SRC, 
                          viopOut->frame.iFrm.cr2);              
                }
                chan->asyncFrameCt ++;                           
            } else {
                chan->asyncFrameCt = 0;               
            
            }
        }else { /* 4 */
            chan->asyncFrameCt = 0;                           
            QUE_enqueue(&chan->qOut, viop);
        }
        
    } else if(chan->pullDownMode == VPORTDIS_PULLDOWN_24P_60P){
        if(chan->asyncFrameCt == 1 || chan->asyncFrameCt == 4) {
            chan->asyncCallBackFxn(chan->asyncCbArg, &viopOut);
            if(viop == viopOut && viopOut != INV){
                QUE_enqueue(&chan->qOut, viopOut);
            } else if(viopOut != INV){
                chan->nextViop = viopOut;
                EDMA_RSETH(chan->hRld[offset], SRC, 
                    viopOut->frame.iFrm.y1);
                if(!(chan->mode & _VPORT_MASK_RAW)){
                    EDMA_RSETH(chan->hRld[4 + offset], SRC, 
                      viopOut->frame.iFrm.cb1);     
                    EDMA_RSETH(chan->hRld[8 + offset], SRC, 
                      viopOut->frame.iFrm.cr1);                         
                }                                           
            }
            chan->asyncFrameCt ++;
            if(chan->asyncFrameCt == 5) chan->asyncFrameCt = 0;
        } else {
            QUE_enqueue(&chan->qOut, viop);
            chan->asyncFrameCt = 0;
        }                                   
    } else { /* not in pull-down modes */
        chan->asyncCallBackFxn(chan->asyncCbArg, chan->asyncFrameCt, &viopOut);   
        if(viop == viopOut && viopOut != INV){
            QUE_enqueue(&chan->qOut, viopOut);
        } else if(viopOut != INV){
	        chan->nextViop = viopOut;
	        if(chan->mergeFlds){
	            EDMA_RSETH(chan->hRld[offset], SRC, 
	                viopOut->frame.iFrm.y1);
	            EDMA_RSETH(chan->hRld[offset + 1], SRC, 
	                viopOut->frame.iFrm.y2);
	            if(!(chan->mode & _VPORT_MASK_RAW)){
	                EDMA_RSETH(chan->hRld[4 + offset], SRC, 
	                  viopOut->frame.iFrm.cb1);     
	                EDMA_RSETH(chan->hRld[5 + offset], SRC, 
	                  viopOut->frame.iFrm.cb2);                         
	                EDMA_RSETH(chan->hRld[8 + offset], SRC, 
	                  viopOut->frame.iFrm.cr1);     
	                EDMA_RSETH(chan->hRld[9 + offset], SRC, 
	                  viopOut->frame.iFrm.cr2);              
	            }           
	        
	        } else {
	            EDMA_RSETH(chan->hRld[offset], SRC, 
	                viopOut->frame.iFrm.y1);
	            if(!(chan->mode & _VPORT_MASK_RAW)){
	                EDMA_RSETH(chan->hRld[4 + offset], SRC, 
	                  viopOut->frame.iFrm.cb1);     
	                EDMA_RSETH(chan->hRld[8 + offset], SRC, 
	                  viopOut->frame.iFrm.cr1);                         
	            }                                           
	        } /* if(chan->mergeFlds) */
	    }
    }
    return 0;
}


⌨️ 快捷键说明

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