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

📄 vportdis.c

📁 TI DM642 DSP 驱动CMOS 成像芯片MT9T001(Micron)源代码,TI原版资料.包含驱动环境配置,对如基于DSP的数码相机,摄像机开发有重要参考价值.
💻 C
📖 第 1 页 / 共 3 页
字号:
           (params->cbDefVal << 16) | (params->crDefVal << 24);
        
        chan->resmpl = params->resmpl;
        chan->scale = params->scale;
        numPixels >>= params->scale;
        chan->numPixels = numPixels;
        numCPixels = (params->dmode & _VPORT_MASK_RAW) ? 0 : numPixels >> 1;
        
        if(params->dmode & _VPORT_MASK_RAW) { /* raw mode */
            chan->cPitch = 0;
            if(params->dmode == VPORT_MODE_RAW_8BIT) {
                chan->yPitch = (numPixels + 7) & (~ 7);
                chan->cPitch = (numCPixels + 7) & (~ 7);
            } else if(params->dmode == VPORT_MODE_RAW_10BIT) {
                if(params->bpk10Bit == VPORTDIS_BPK_10BIT_DENSE){
                    chan->yPitch = (numPixels * 4 / 3 + 7) & (~ 7);
                }else {
                    chan->yPitch = (numPixels * 2 + 7) & (~ 7);
                }
            } else if(params->dmode == VPORT_MODE_RAW_16BIT) {
                chan->yPitch = (numPixels * 2 + 7) & (~ 7);
            } else {
                chan->yPitch = (numPixels * 4 + 7) & (~ 7);
            }                                                                        
        } else {
            if(params->dmode & _VPORT_MASK_10BIT) {
                if(params->bpk10Bit == VPORTDIS_BPK_10BIT_DENSE){
                    chan->yPitch = (numPixels * 4 / 3 + 7) & (~ 7);
                    chan->cPitch = (numCPixels* 4 / 3 + 7) & (~ 7);
                }else {
                    chan->yPitch = (numPixels * 2 + 7) & (~ 7);
                    chan->cPitch = (numCPixels * 2 + 7) & (~ 7);
                }
            } else {/* 8 bit mode */
                chan->yPitch = (numPixels + 7) & (~ 7);
                chan->cPitch = (numCPixels + 7) & (~ 7);
            }
        }
        chan->yThrld = params->thrld;       
        if(params->mergeFlds && params->fldOp == VPORT_FLDOP_FRAME) {
            /* frame capture and merge 2 fields into one frame */
            /* make sure threshold is same as line size */
            chan->yThrld = chan->yPitch >> 3;
            chan->numEventsFld1 = chan->numLinesFld1;
            chan->numEvents = chan->numLines;
            chan->mergeFlds = TRUE;  
        }else {            
            /* these two asserts make sure that total transfer sizes of */
            /* both the whole frame and the first field are multiples   */
            /* of the threshold                                         */
            assert(((chan->yPitch*chan->numLinesFld1)/(chan->yThrld << 3)) 
                *(chan->yThrld << 3) == (chan->yPitch*chan->numLinesFld1));
            assert(((chan->yPitch*chan->numLines)/(chan->yThrld << 3)) 
                *(chan->yThrld << 3) == (chan->yPitch*chan->numLines));
            chan->numEventsFld1 = 
                chan->yPitch * chan->numLinesFld1 / (chan->yThrld << 3);
            chan->numEvents = 
                chan->yPitch * chan->numLines / (chan->yThrld << 3);
            chan->mergeFlds = FALSE;
        }                    
        if(params->dmode & _VPORT_MASK_RAW) {
            chan->cThrld = 0;
        }    
        else {
            chan->cThrld = (chan->yThrld + 1) >> 1;
        }    
        base[_VP_VDTHRLD_OFFSET] = 
            VP_VDTHRLD_RMK(chan->yThrld,params->incPix,chan->yThrld);
        base[_VP_VDDISPEVT_OFFSET] = 
            VP_VDDISPEVT_RMK((chan->numEvents-chan->numEventsFld1), 
            chan->numEventsFld1 );  

        
        chan->mode = params->dmode;
        chan->status |= _VPORT_CFGED;
    }
    return IOM_COMPLETED;

}


/*
 *  ======== displayEdmaISR ========
 */
Int frame = 0;
Int totalFrame = 0;
static void displayEdmaISR(tcc) 
{
    Int i;
    FVID_Frame *viop, *curViop;      
    
    
    /* find out the source of the edma interrupt */
    for(i = 0; i < _VP_PORT_CNT; i ++) {      
        _VPORT_ChanObj* chan = &chanObjs[i];
        if((chan->status & _VPORT_READY) && tcc == chan->tcc[0]){
            totalFrame ++;
            /* make sure all transfers are completed */
            if(!(chan->mode & _VPORT_MASK_RAW)) {
                while(! EDMA_intTest(chan->tcc[1]));
                EDMA_intClear(chan->tcc[1]);
                while(! EDMA_intTest(chan->tcc[2]));
                EDMA_intClear(chan->tcc[2]);
            }
            if(chan->mergeFlds){
                /* 1st field is being captured, update */
                /* the rld to point to the 2nd field   */
                /* of the current frame, which is the nextViop */
                EDMA_RSETH(chan->hEdma[0], SRC, 
                    chan->nextViop->frame.iFrm.y1);
                EDMA_RSETH(chan->hRld[0], SRC, 
                    chan->nextViop->frame.iFrm.y1);
                EDMA_RSETH(chan->hRld[1], SRC, 
                    chan->nextViop->frame.iFrm.y2);
                if(!(chan->mode & _VPORT_MASK_RAW)){
                    EDMA_RSETH(chan->hEdma[1], SRC, 
                        chan->nextViop->frame.iFrm.cb1);
                    EDMA_RSETH(chan->hEdma[2], SRC, 
                        chan->nextViop->frame.iFrm.cr1);
                    EDMA_RSETH(chan->hRld[2], SRC, 
                        chan->nextViop->frame.iFrm.cb1);     
                    EDMA_RSETH(chan->hRld[4], SRC, 
                        chan->nextViop->frame.iFrm.cr1);                         
                    EDMA_RSETH(chan->hRld[3], SRC, 
                        chan->nextViop->frame.iFrm.cb2);     
                    EDMA_RSETH(chan->hRld[5], SRC, 
                        chan->nextViop->frame.iFrm.cr2);                         
                }
            }/*if(chan->mergeFlds){*/
            /* update the reload address */
            curViop = chan->curViop;
            chan->curViop = chan->nextViop;
            if((viop = (FVID_Frame *)QUE_dequeue(&chan->qIn))
                != (FVID_Frame *)&chan->qIn) {
                /* queue IS not empty */
                chan->nextViop = viop;
            }else {
                chan->queEmpty = TRUE;
            }
            if(!chan->mergeFlds) {
                EDMA_RSETH(chan->hRld[0], SRC, 
                    chan->nextViop->frame.iFrm.y1);
                if(! (chan->mode & _VPORT_MASK_RAW)){
                    EDMA_RSETH(chan->hRld[1], SRC, 
                        chan->nextViop->frame.iFrm.cb1);
                    EDMA_RSETH(chan->hRld[2], SRC, 
                        chan->nextViop->frame.iFrm.cr1);
                }
            }/* if(!chan->mergeFlds) {*/
            
            if(curViop != chan->curViop) {
                if(chan->packetIOM != INV) {
                    /* call the channel's callback function */
                    *(void **)chan->packetIOM->addr = curViop;             
                    chan->packetIOM->size = sizeof(FVID_Frame);
                    chan->cbFxn((Ptr)chan->cbArg, chan->packetIOM);  
                    chan->packetIOM = INV;
                }else {
                    QUE_enqueue(&chan->qOut,curViop);
                }
            }/*if(curViop != chan->curViop) {*/  
            else {
                frame ++;
            }      
        }/*if((chan->status & READY) && tcc == chan->tcc[0]){*/
    } /*for(i = 0; i <_VP_PORT_CNT; i++) {  */
}


/*
 *  ======== displayISR ========
 */
static void displayISR(int portNum)
{
    volatile Int *base =  
        (volatile Int *)chanObjs[portNum].base;
    Int vpis = base[_VP_VPIS_OFFSET];
    Int mask = vpis & chanObjs[portNum].vIntMask;
        
    if(mask && chanObjs[portNum].vIntFxn != INV) {
        chanObjs[portNum].vIntFxn(chanObjs[portNum].cbArg, 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;  
                                      
    /* 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 */
    TSK_sleep(100);
    base[_VP_VDCTL_OFFSET] &= ~ (_VP_VDCTL_BLKDIS_MASK);
    /* enable interrupt */
    base[_VP_VPIE_OFFSET] |= VP_VPIE_VIE_ENABLE << _VP_VPIE_VIE_SHIFT;     
    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;
    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 */
    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_disableChannel(chan->hEdma[0]);            
    EDMA_clearChannel(chan->hEdma[0]);
    

    /* 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(chan->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(chan->numEvents - 1, chan->cThrld << 1));
        EDMA_RSETH(chan->hEdma[2], CNT, 
            EDMA_CNT_RMK(chan->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_enableChannel(chan->hEdma[0]);

   base[_VP_VDCTL_OFFSET] |= VP_VDCTL_VDEN_ENABLE << _VP_VDCTL_VDEN_SHIFT;
   for(i = 0; i < 10000; i ++);
   base[_VP_VDCTL_OFFSET] &= ~(_VP_VDCTL_BLKDIS_MASK);
   /* re-enable under run interrupt */
   base[_VP_VPIE_OFFSET] |= _VP_VPIE_DUND_MASK;
   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;


    chan->vIntMask = mask;
    /* 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;    
    }
    base[_VP_VDVINT_OFFSET] = VP_VDVINT_RMK(vif2, 
        vInt2, vif1, vInt1);
    if(mask) {
        mask |= 1; /* turn on video port interrupt */
        IRQ_map(IRQ_EVT_VINT0 + chan->portNum, vIntCbParams->irqId);    
        HWI_dispatchPlug(vIntCbParams->irqId, (Fxn)displayISR, -1, NULL);
        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;       
    return IOM_COMPLETED;
}



⌨️ 快捷键说明

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