📄 copy of vportcap.c
字号:
/*
* 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 + -