📄 vportcap_raw_support.c
字号:
}
else
{
chan->viops[i].frame.iFrm.cb1 = curAddr;
curAddr += chan->numLines*chan->cPitch;
chan->viops[i].frame.iFrm.cr1 = curAddr;
curAddr += chan->numLines*chan->cPitch;
}
/* field 2 */
if(params->fldOp == VPORT_FLDOP_FLD2) {
chan->viops[i].frame.iFrm.y2 =
chan->viops[i].frame.iFrm.y1;
chan->viops[i].frame.iFrm.cb2 =
chan->viops[i].frame.iFrm.cb1;
chan->viops[i].frame.iFrm.cr2 =
chan->viops[i].frame.iFrm.cr1;
}
else if(! chan->mergeFlds) {
chan->viops[i].frame.iFrm.y2 = chan->viops[i].frame.iFrm.y1 + chan->numLinesFld1*chan->yPitch;
// RAW CAPTURE INITIALIZATION SPECIFIC
// Do not set if in Raw Mode
if(chan->mode & _VPORT_MASK_RAW)
//if(chan->mode == VPORT_MODE_RAW_8BIT)
{
chan->viops[i].frame.iFrm.cb2 = 0;
chan->viops[i].frame.iFrm.cr2 = 0;
}
else
{
chan->viops[i].frame.iFrm.cb2 = chan->viops[i].frame.iFrm.cb1 + (chan->numLinesFld1*chan->cPitch);
chan->viops[i].frame.iFrm.cr2 = chan->viops[i].frame.iFrm.cr1 + (chan->numLinesFld1*chan->cPitch);
}
}else {
chan->viops[i].frame.iFrm.y2 =
chan->viops[i].frame.iFrm.y1 + chan->yPitch;
// RAW CAPTURE INITIALIZATION SPECIFIC
// Do not set if in Raw Mode
if(chan->mode & _VPORT_MASK_RAW)
//if(chan->mode == VPORT_MODE_RAW_8BIT)
{
chan->viops[i].frame.iFrm.cb2 = 0;
chan->viops[i].frame.iFrm.cr2 = 0;
}
else
{
chan->viops[i].frame.iFrm.cb2 = chan->viops[i].frame.iFrm.cb1 + chan->cPitch;
chan->viops[i].frame.iFrm.cr2 = chan->viops[i].frame.iFrm.cr1 + chan->cPitch;
}
}
}
}
for(i = ! chan->mergeFlds + 1; i < chan->numFrms; i ++) {
/* don't put the first 2 viop into the queue */
QUE_enqueue(&chan->qIn, (QUE_Handle)&chan->viops[i]);
}
chan->curViop = &chan->viops[0];
chan->nextViop = &chan->viops[1];
//RAW CAPTURE INITIALIZATION SPECIFIC
// set number of EDMA channels to cycle through based on RAW mode operation
numEdmaChans = (chan->mode & _VPORT_MASK_RAW) ? _VPORT_NUM_EDMA_CHANS_RAW : _VPORT_NUM_EDMA_CHANS;
//numEdmaChans = (chan->mode == VPORT_MODE_RAW_8BIT) ? _VPORT_NUM_EDMA_CHANS_RAW : _VPORT_NUM_EDMA_CHANS;
for(i = 0; i < numEdmaChans; i ++) {
Int optFld1 = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_YES,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_NO,
EDMA_OPT_TCC_OF(chan->tcc[i] & 0x0f),
EDMA_OPT_TCCM_OF(chan->tcc[i] >> 4),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
);
Int optFld2 = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_YES,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(chan->tcc[i] & 0x0f),
EDMA_OPT_TCCM_OF(chan->tcc[i] >> 4),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
);
EDMA_disableChannel(chan->hEdma[i]);
EDMA_intClear(chan->tcc[i]);
EDMA_clearChannel(chan->hEdma[i]);
// RAW CAPTURE INITIALIZATION SPECIFIC
thrld = (i == 0) ? chan->yThrld : chan->cThrld;
//thrld = chan->yThrld;
cfgEdma.src = EDMA_SRC_RMK(chan->edmaAddr[i]);
if(chan->mergeFlds) {
/* to merge the two fields together */
/* EDMA is configured to transfer only field 1 initially */
/* line pitch is twice the line size */
/* this requires that the threlhold is the same as line size */
cfgEdma.cnt =
EDMA_CNT_RMK((chan->numEventsFld1) - 1, (thrld << 1));
cfgEdma.idx = EDMA_IDX_RMK(thrld << 4, 0);
/* hard code the field 1 & 2 of the first */
/* frame buffer as current and reload buffers */
cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[2 * i + 1]);
cfgEdma.opt = optFld1;
cfgEdma.dst =
EDMA_DST_RMK(*((Int *)(&chan->viops[0].frame.iFrm.y1) + i));
EDMA_config(chan->hEdma[i], &cfgEdma);
EDMA_config(chan->hRld[2 * i], &cfgEdma);
cfgEdma.opt = optFld2;
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[2 * i]);
EDMA_config(chan->hRld[2 * i + 1], &cfgEdma);
}else {/* if fields are not merged, configure EDMA to transfer */
/* for both field1 and field 2 */
/* the line pitch is just the line size */
cfgEdma.opt = optFld2;
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[i]);
/* 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);
cfgEdma.dst = EDMA_DST_RMK(
*((Int *)(&chan->viops[1].frame.iFrm.y1) + i));
EDMA_config(chan->hRld[i], &cfgEdma);
}
}
/* enable EDMA channel */
EDMA_intHook(chan->tcc[0], captureEdmaISR);
/*
* The EDMA interrupt dispatcher will be called by the
* BIOS HWI interrupt dispatcher.
*/
IRQ_map(IRQ_EVT_EDMAINT, params->irqId);
HWI_dispatchPlug(params->irqId, (Fxn)EDMA_intDispatcher, -1, NULL);
EDMA_intClear(chan->tcc[0]);
EDMA_intEnable(chan->tcc[0]);
for(i = 0; i < numEdmaChans; 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;
volatile Int i;
int numEdmaChans = 0;
/* 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]);
//RAW CAPTURE INITIALIZATION SPECIFIC
// set number of EDMA channels to cycle through based on RAW mode operation
numEdmaChans = (chan->mode == VPORT_MODE_RAW_8BIT) ? _VPORT_NUM_EDMA_CHANS_RAW : _VPORT_NUM_EDMA_CHANS;
for(i = 0; i < numEdmaChans; i ++) {
EDMA_disableChannel(chan->hEdma[i]);
EDMA_clearChannel(chan->hEdma[i]);
}
/* set up DMA parameters again */
EDMA_RSETH(chan->hEdma[0], DST, chan->curViop->frame.iFrm.y1);
// RAW CAPTURE INITIALIZATION SPECIFIC
// Set if not in RAW mode
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[0], CNT, EDMA_CNT_RMK(chan->numEvents - 1,
(chan->yThrld << 1)));
// RAW CAPTURE INITIALIZATION SPECIFIC
// Set if not in RAW mode
if(!(chan->mode & _VPORT_MASK_RAW))
{
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_intEnable(chan->tcc[0]);
for(i = 0;i < numEdmaChans;i ++) {
EDMA_enableChannel(chan->hEdma[i]);
}
/* delay */
for(i = 0; i < 100000; 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;
}
/*
* ======== _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;
Uint16 mask = vIntCbParams->vIntMask;
Uns vif2 = 0, vInt2 = 0, vif1 = 0, vInt1 = 0, fscl2 = 0;
/* 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 */
IRQ_map(IRQ_EVT_VINT0 + chan->portNum, vIntCbParams->irqId);
HWI_dispatchPlug(vIntCbParams->irqId, (Fxn)captureISR, -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;
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;
volatile Int i;
/* enable channel */
cbase[_VP_VCACTL_OFFSETA] |= VP_VCACTL_VCEN_ENABLE << _VP_VCACTL_VCEN_SHIFT;
/* wait for port to sync up */
TSK_sleep(100);
//for(i = 0; i < 100000; i ++);
/* 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]);
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -