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

📄 copy of vportcap.c

📁 dm642_video_stream
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  Copyright 2003 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */

/* DSP/BIOS standard include files */
#include <std.h>
#include <mem.h>
#include <que.h>     
#include <tsk.h>    
#include <hwi.h>          
#include <clk.h>

/* Chip-support library include files */
#include <csl.h>
#include <csl_edma.h>
#include <csl_vphal.h>         
#include <csl_irq.h>
#include <csl_cache.h>

/* IOM/GIO driver model include files */
#include <iom.h>
#include <fvid.h>                       

/* video driver specific include files */
#include <vport.h>
#include <vportcap.h>
#include <edc.h>
#include "_vport.h"

/* debug include files */
/* to minimize code size and cycle count overhead of the driver */             
/* error checking is only performed at debug time               */
#include <assert.h>

interrupt void IsrForEDMA();

/* type defines and data structures */
/**************************************************************
 *     data structure for video port object                   *
 **************************************************************/
typedef struct PortObj{
    /* port status register, contains information on whether */
    /* port is opened, configured, etc.                      */
    Int     status;
    /* vp base address for all register access */
    Int     base;
    
    /* two channel objects for channel A & B.  */
    /* This is only for capture operation      */
    _VPORT_ChanObj chanObj[2];
} PortObj;


/* mini-driver API functions */
static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams);
static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args);
static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
        Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg);
static Int mdDeleteChan(Ptr chanp);
static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet);


/* local functions */
static void captureEdmaISR(Int tcc);
static void captureISR(Int portNum);
static Int ConfigChannel(Ptr chanp, VPChanCap_Params *params);
static Int _configChan(Ptr chanp, Ptr args);     
static Int _configPort(Ptr chanp, Ptr args);    
static Int ConfigTransfer(Ptr chanp,VPChanCap_Params *params);  
static Int _covrRecover(Ptr chanp);
static Int _setVIntCb(Ptr chanp, Ptr args);
static Int _startVPCapture(Ptr chanp);
static Int _stopVPCapture(Ptr chanp);  
static void _autoSync(_VPORT_ChanObj *pChan); 
static void _delay(Int delayTime);


/* global and static variables */
IOM_Fxns VPORTCAP_Fxns = {
    mdBindDev,    
    (IOM_TmdUnBindDev)IOM_mdNotImpl,
    mdControlChan,
    mdCreateChan,
    mdDeleteChan,
    mdSubmitChan
};

/**************************************************************
 * Static allocation and initialization of port objects       *
 **************************************************************/   
/* _VP_PORT_CNT = 3, defined in clsc6000\include\csl_vphal.h*/
static PortObj gsPortObjs[_VP_PORT_CNT] = {
    /* video port 0 */
    {
    	0, 
    	_VP_BASE_PORT0,    /*0x01C40000u, defined in cslc6000\include\csl_vphal.h*/
        {
        	/* channel A */  
        	{0, 0, 0, _VP_BASE_CHAPORT0, EDMA_CHA_VP0EVTYA, EDMA_CHA_VP0EVTUA, 
        		EDMA_CHA_VP0EVTVA, _VP_YSRCA0_ADDR, _VP_CBSRCA0_ADDR, 
        		_VP_CRSRCA0_ADDR 
        	}, 
    		/* channel B */  
        	{0, 0, 1, _VP_BASE_CHBPORT0, EDMA_CHA_VP0EVTYB, EDMA_CHA_VP0EVTUB, 
        		EDMA_CHA_VP0EVTVB,  _VP_YSRCB0_ADDR, _VP_CBSRCB0_ADDR, 
        		_VP_CRSRCB0_ADDR
        	}
        }
	},

    /* video port 1 */
    {
    	0, 
    	_VP_BASE_PORT1, /*0x01C44000u*/
        {
        	/* channel A */  
        	{0, 1, 0, _VP_BASE_CHAPORT1, EDMA_CHA_VP1EVTYA, EDMA_CHA_VP1EVTUA, 
        		EDMA_CHA_VP1EVTVA, _VP_YSRCA1_ADDR, _VP_CBSRCA1_ADDR, 
        		_VP_CRSRCA1_ADDR 
        	}, 
            
            /* channel B */  
        	{0, 1, 1, _VP_BASE_CHBPORT1, EDMA_CHA_VP1EVTYB, EDMA_CHA_VP1EVTUB, 
        		EDMA_CHA_VP1EVTVB, _VP_YSRCB1_ADDR, _VP_CBSRCB1_ADDR, 
        		_VP_CRSRCB1_ADDR
        	}
        }
	},

    /* video port 2 */
    {
    	0, 
    	_VP_BASE_PORT2,	/*0x01C48000u*/
        {
        	/* channel A */  
        	{0, 2, 0, _VP_BASE_CHAPORT2, EDMA_CHA_VP2EVTYA, EDMA_CHA_VP2EVTUA, 
         		EDMA_CHA_VP2EVTVA, _VP_YSRCA2_ADDR, _VP_CBSRCA2_ADDR, 
         		_VP_CRSRCA2_ADDR  
         	}, 
    		/* channel B */  
        	{0, 2, 1, _VP_BASE_CHBPORT2, EDMA_CHA_VP2EVTYB, EDMA_CHA_VP2EVTUB, 
         		EDMA_CHA_VP2EVTVB,  _VP_YSRCB2_ADDR, _VP_CBSRCB2_ADDR, 
         		_VP_CRSRCB2_ADDR 
         	}
         }
	}
};



/*
 *  =================== mdBindDev ============================
 *  Register all external devices to video port capture driver 
 */
static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams)
{
    Int portNum = devid; 
    Uint32 data, data1 = VP_VPCTL_VPRST_RESET;        
    volatile Int i;
    volatile Int *base = (volatile Int *)gsPortObjs[portNum].base;                       
   
    assert(portNum < _VP_PORT_CNT);
    
    /*_VP_VPCTL_OFFSET = 48, defined in cslc6000\include\csl_vphal.h
	48xsizeof(Int) = 192, the addr of video port control reg 
	VP_VPCTL_VPRST_RESET = 0x00000001u, _VP_VPCTL_VPRST_SHIFT =  0x0000000Fu     */
	base[_VP_VPCTL_OFFSET] = VP_VPCTL_VPRST_RESET << _VP_VPCTL_VPRST_SHIFT;
/*	for (;;)
	{
		data = (Uint32)base[_VP_VPCTL_OFFSET];
		if ((data & (data1 << _VP_VPCTL_VPRST_SHIFT)) == 0)
			break;
		SEEDDM642_wait(1000);
	}*/

    for(i = 0; i < 100000; i ++);             
   
    *devp = &gsPortObjs[portNum];                                                
    
	/*cannot understand pass PortObj to be the first params, comment it out*/                                                                                          
    /*return mdControlChan(&gsPortObjs[portNum], VPORT_CMD_CONFIG_PORT, devParams); */
    return mdControlChan(&(gsPortObjs[portNum].chanObj[0]), VPORT_CMD_CONFIG_PORT, devParams);
}


/*
 *  ======== mdControlChan ========
 */
static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args)
{
    Int retVal = IOM_EBADMODE;
    _VPORT_ChanObj *pChan = (_VPORT_ChanObj*)chanp;
    PortObj *pPort = &gsPortObjs[pChan->portNum];

    switch (cmd) 
    {
	case VPORT_CMD_START:
        retVal = _startVPCapture(chanp);
        break;
    
	case VPORT_CMD_STOP:
        retVal = _stopVPCapture(chanp);
        break;
    
	case VPORT_CMD_SET_VINTCB:
        retVal = _setVIntCb(chanp, args);
        break;
    
	case VPORT_CMD_CONFIG_PORT:               
		/* We correct the chanp param passed from mdBindDev,
			and therefore should correct the param here */
        /*retVal = _configPort(chanp, args);*/ 
		retVal = _configPort(pPort, args);
        break;
    
	case VPORT_CMD_COVR_RECOVER:
        retVal = _covrRecover(chanp);
        break;
    
    case VPORT_CMD_CONFIG_CHAN:
        if (!(pPort->status & _VPORT_CFGED)) 
        {
            retVal = _configChan(chanp, args);
        }
        break;
        
	default: 
        if(pChan->edcFxns!=INV)
        {
            retVal = pChan->edcFxns->ctrl(pChan->edcHandle, 
                cmd-VPORT_CMD_EDC_BASE,(Arg)args);
        }
        else 
        {
            retVal = IOM_ENOTIMPL;
        } 
        break;   
    }   
    
    return retVal;
}              


/*
 *  =================== mdCreateChan ============================
 *  create a capture channel
 */
static Int  mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
                      Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg)
{
    Int chanNum;           
    volatile Int *base;
    PortObj *pPort;
    Int retVal = IOM_COMPLETED;       
 
    if(mode != IOM_INPUT)
        return IOM_EBADARGS;
    
	if(*name ++ != '/') 
        return IOM_EBADARGS;
    
    chanNum = *name ++ - 'A';

    assert(chanNum < _VPORT_CHAN_CNT);
    
    pPort = (PortObj*)devp;
    
    if (pPort->chanObj[chanNum].edcFxns != INV) 
    {
        /* open external device */
        pPort->chanObj[chanNum].edcHandle 
           = pPort->chanObj[chanNum].edcFxns->open(name, (Arg)INV);
    } 
    
    if(!(pPort->status & _VPORT_OPENED)) 
    {
        pPort->status |= _VPORT_OPENED;
        base = (volatile Int*)pPort->base;                       
        
        /* reset both channels */
        base[_VP_VCACTL_OFFSET] |= 
            VP_VCACTL_RSTCH_RESET << _VP_VCACTL_RSTCH_SHIFT;
        base[_VP_VCBCTL_OFFSET] |= 
            VP_VCBCTL_RSTCH_RESET << _VP_VCBCTL_RSTCH_SHIFT;
    } /* if(!port->opened)  */ 
    
    /* initialize the channel object */
    if (!(pPort->chanObj[chanNum].status & _VPORT_OPENED)) 
    {
        Int j;
        _VPORT_ChanObj *pChan = &pPort->chanObj[chanNum];       
        pChan->status |= _VPORT_OPENED;
        pChan->vIntMask = 0;
        QUE_new(&pChan->qIn);

		while (!QUE_empty(&pChan->qIn))
				QUE_dequeue(&pChan->qIn);
			
        pChan->cbFxn = cbFxn;
        pChan->vIntFxn = (VPORT_IntCallBack)INV;
        pChan->queEmpty = FALSE;   
        pChan->cbArg = (Arg)cbArg;
        pChan->mrViop = INV;
        pChan->packetIOM = INV;     
        pChan->numFrms = 0;
        pChan->vIntCbArg = (Int)INV;
        pChan->bufSz = 0;
        
        for (j = 0; j < VPORT_MAX_NUM_FRMBUFS; j++)
        {
        	pChan->viops[j].frame.iFrm.y1 = 0;
        }   
        
        /* _VPORT_NUM_EDMA_CHANS = 3, Y U V */
        for (j = 0; j < _VPORT_NUM_EDMA_CHANS && retVal == IOM_COMPLETED; j++)
        {
            if ((pChan->hEdma[j] = EDMA_open(pChan->edmaChanNum[j], EDMA_OPEN_RESET))==EDMA_HINV
            	|| (pChan->hRld[4 * j] = EDMA_allocTable(-1))== EDMA_HINV
            	|| (pChan->hRld[4 * j + 1] = EDMA_allocTable(-1))== EDMA_HINV
            	|| (pChan->hRld[4 * j + 2] = EDMA_allocTable(-1))== EDMA_HINV
            	|| (pChan->hRld[4 * j + 3] = EDMA_allocTable(-1))== EDMA_HINV 
            	/*Transfer complete code is generated by EDMA_intAlloc*/
            	|| (pChan->tcc[j] = EDMA_intAlloc(pChan->edmaChanNum[j])) == -1)
            {
                retVal = IOM_EALLOC;
            }
        }
        
        if (retVal == IOM_COMPLETED && (void*)chanParams != INV) 
        { 
        	/* configure the channel */
            retVal = mdControlChan(&pPort->chanObj[chanNum], 
                VPORT_CMD_CONFIG_CHAN, chanParams); 
        } 
        
        if (retVal == IOM_COMPLETED) 
        {
             *chanp = &pPort->chanObj[chanNum];
        }
        else 
        {
            mdDeleteChan(&pPort->chanObj);
            *chanp = INV;                     
        }               
    } /*if(!chan->opened) */
    return retVal;
}               


/*
 *  =================== mdDeleteChan ============================
 *  delete the capture channel
 */

static Int  mdDeleteChan(Ptr chanp)
{
    _VPORT_ChanObj *pChan = (_VPORT_ChanObj*)chanp;
    PortObj *pPort = &gsPortObjs[pChan->portNum];
    Int j;
    volatile Int *base;
    
    if (pChan->status & _VPORT_OPENED) 
    {
        pChan->status = 0;
        mdControlChan(chanp, VPORT_CMD_STOP, NULL);
        for (j = 0; j < _VPORT_NUM_EDMA_CHANS; j ++) 
        {
            EDMA_disableChannel(pChan->hEdma[j]);
            EDMA_clearChannel(pChan->hEdma[j]);
            EDMA_close(pChan->hEdma[j]);
            EDMA_freeTable(pChan->hRld[4 * j]);
            EDMA_freeTable(pChan->hRld[4 * j + 1]);
            EDMA_freeTable(pChan->hRld[4 * j + 2]);
            EDMA_freeTable(pChan->hRld[4 * j + 3]);
            EDMA_intFree(pChan->tcc[j]);
        }
        
        for (j = 0; j < pChan->numFrms ; j ++) 
        {
        	if (pChan->viops[j].frame.iFrm.y1)
            	MEM_free(pChan->segId, pChan->viops[j].frame.iFrm.y1, pChan->bufSz);
        }        
        /* close external device */
        if (pChan->edcFxns != INV) 
        {
            pChan->edcFxns->close(pChan->edcHandle);
        }
    }    
    
    if (!(pPort->chanObj[0].status & _VPORT_OPENED) 
    	&& !(pPort->chanObj[1].status & _VPORT_OPENED))
    {
        base = (volatile Int*)pPort->base;
        /* reset both channels */
        base[_VP_VCACTL_OFFSET] |= 
            VP_VCACTL_RSTCH_RESET << _VP_VCACTL_RSTCH_SHIFT;
        base[_VP_VCBCTL_OFFSET] |= 
            VP_VCBCTL_RSTCH_RESET << _VP_VCBCTL_RSTCH_SHIFT;

        /* reset video port */
        base[_VP_VPCTL_OFFSET] |= 
            VP_VPCTL_VPRST_RESET << _VP_VPCTL_VPRST_SHIFT;
        pPort->status = 0;
    }
    return IOM_COMPLETED;
}

⌨️ 快捷键说明

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