?? vportdis.c
字號:
EDMA_enableChannel(chan->hEdma[1]);
EDMA_disableChannel(chan->hEdma[2]);
EDMA_clearChannel(chan->hEdma[2]);
EDMA_enableChannel(chan->hEdma[2]);
}
/*
* 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_disableChannel(chan->hEdma[0]);
EDMA_clearChannel(chan->hEdma[0]);
EDMA_enableChannel(chan->hEdma[0]);
EDMA_intClear(chan->tcc[0]);
EDMA_intEnable(chan->tcc[0]);
EDMA_intHook(chan->tcc[0], displayEdmaISR);
EDMA_intClear(chan->tcc[1]);
EDMA_intEnable(chan->tcc[1]);
EDMA_intHook(chan->tcc[1], displayEdmaISR);
chan->status |= _VPORT_READY;
IRQ_enable(IRQ_EVT_EDMAINT);
}
return IOM_COMPLETED;
}
/*
* ======== _configPort ========
*/
static Int _configPort(Ptr chanp, Ptr args)
{
_VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
VPORT_PortParams* portParams = (VPORT_PortParams*)args;
volatile Int* base = (volatile Int *)chan->base;
/* reset video port */
base[_VP_VPCTL_OFFSET] =
VP_VPCTL_VPRST_RESET << _VP_VPCTL_VPRST_SHIFT;
/* enable video port */
base[_VP_PCR_OFFSET] |=
VP_PCR_PEREN_ENABLE << _VP_PCR_PEREN_SHIFT;
base[_VP_VDCTL_OFFSET] =
(Int)VP_VDCTL_RSTCH_RESET << _VP_VDCTL_RSTCH_SHIFT;
/* configure video port control register */
base[_VP_VPCTL_OFFSET] = VP_VPCTL_RMK(0,0,1,portParams->vc3Polarity,
portParams->vc2Polarity,portParams->vc1Polarity,0,1,0);
/* enable video port */
base[_VP_VPCTL_OFFSET] |= (VP_VPCTL_VPHLT_CLEAR << _VP_VPCTL_VPHLT_SHIFT);
chan->edcFxns = portParams->edcTbl[0];
return IOM_COMPLETED;
}
/*
* ======== _configRegs ========
* configure video port registers for display
*/
static Int _configRegs(Ptr chanp, VPORTDIS_Params* params)
{
_VPORT_ChanObj* chan = (_VPORT_ChanObj *)chanp;
volatile Int* base = (volatile Int *)chan->base;
Int numPixels, numLines, numCPixels;
Int vdCtl;
Int nh1 = 0, nh2 = 0, nv1 = 0, nv2 = 0;
if(chan->status & _VPORT_OPENED) {
/* configure display settings */
chan->status |= _VPORT_CFGED;
vdCtl = VP_VDCTL_RMK(0,1,0,((params->extCtl&4) >> 2),
((params->extCtl&2)>>1), params->extCtl&1,params->vctl3Config,
params->vctl2Config,params->vctl1Config,0, params->bpk10Bit,
params->rgbX,0,params->defValEn,params->resmpl,
params->scale, 1,((params->fldOp & 4) >> 2),
((params->fldOp & 2) >> 1),
(params->fldOp & 1),
params->dmode);
numLines = 0;
numPixels = 0;
if(params->fldOp != VPORT_FLDOP_FLD2){
// progressive scan, or field 1 or frame
numPixels = params->imgHSizeFld1;
numLines = params->imgVSizeFld1;
}
chan->numLinesFld1 = numLines;
if(params->fldOp == VPORT_FLDOP_FLD2 ||
params->fldOp == VPORT_FLDOP_FRAME){
if(!numPixels) numPixels = params->imgHSizeFld2;
numLines += params->imgVSizeFld2;
chan->interlaced = TRUE;
}
chan->numLines = numLines;
chan->frmSz = params->frmVSize;
base[_VP_VDCTL_OFFSET] = vdCtl;
base[_VP_VDFRMSZ_OFFSET] =
VP_VDFRMSZ_RMK(params->frmVSize, params->frmHSize);
base[_VP_VDHBLNK_OFFSET] =
VP_VDHBLNK_RMK(params->hBlnkStop, !(params->dmode&_VPORT_MASK_RAW),
params->hBlnkStart);
base[_VP_VDVBLKS1_OFFSET] =
VP_VDVBLKS1_RMK(params->vBlnkYStartFld1, params->vBlnkXStartFld1);
base[_VP_VDVBLKE1_OFFSET] =
VP_VDVBLKE1_RMK(params->vBlnkYStopFld1, params->vBlnkXStopFld1);
base[_VP_VDVBLKS2_OFFSET] =
VP_VDVBLKS2_RMK(params->vBlnkYStartFld2, params->vBlnkXStartFld2);
base[_VP_VDVBLKE2_OFFSET] =
VP_VDVBLKE2_RMK(params->vBlnkYStopFld2, params->vBlnkXStopFld2);
base[_VP_VDVBIT1_OFFSET] =
VP_VDVBIT1_RMK(params->vBlnkYStopFld1, params->vBlnkYStartFld1);
base[_VP_VDVBIT2_OFFSET] =
VP_VDVBIT1_RMK(params->vBlnkYStopFld2, params->vBlnkYStartFld2);
if(params->imgHOffsetFld1<0) {
nh1 = 1;
params->imgHOffsetFld1 = -params->imgHOffsetFld1;
}
if(params->imgHOffsetFld2<0) {
nh2 = 1;
params->imgHOffsetFld2 = -params->imgHOffsetFld2;
}
if(params->imgVOffsetFld1<0) {
nv1 = 1;
params->imgVOffsetFld1 = -params->imgVOffsetFld1;
}
if(params->imgHOffsetFld2<0) {
nv2 = 1;
params->imgVOffsetFld2 = -params->imgVOffsetFld2;
}
base[_VP_VDIMGOFF1_OFFSET] =
VP_VDIMGOFF1_RMK(nv1, params->imgVOffsetFld1, nh1,
params->imgHOffsetFld1);
base[_VP_VDIMGSZ1_OFFSET] =
VP_VDIMGSZ1_RMK(params->imgVSizeFld1, params->imgHSizeFld1);
base[_VP_VDIMGOFF2_OFFSET] =
VP_VDIMGOFF2_RMK(nv2, params->imgVOffsetFld2, nh2,
params->imgHOffsetFld2);
base[_VP_VDIMGSZ2_OFFSET] =
VP_VDIMGSZ2_RMK(params->imgVSizeFld2, params->imgHSizeFld2);
base[_VP_VDFLDT1_OFFSET] =
VP_VDFLDT1_RMK(params->yStartFld1, params->xStartFld1);
base[_VP_VDFLDT2_OFFSET] =
VP_VDFLDT2_RMK(params->yStartFld2, params->xStartFld2);
base[_VP_VDFBIT_OFFSET] =
VP_VDFBIT_RMK(params->yStartFld2, params->yStartFld1);
base[_VP_VDHSYNC_OFFSET] =
VP_VDHSYNC_RMK(params->hSyncStop, params->hSyncStart);
base[_VP_VDVSYNS1_OFFSET] =
VP_VDVSYNS1_RMK(params->vSyncYStartFld1, params->vSyncXStartFld1);
base[_VP_VDVSYNE1_OFFSET] =
VP_VDVSYNE1_RMK(params->vSyncYStopFld1, params->vSyncXStopFld1);
base[_VP_VDVSYNS2_OFFSET] =
VP_VDVSYNS2_RMK(params->vSyncYStartFld2, params->vSyncXStartFld2);
base[_VP_VDVSYNE2_OFFSET] =
VP_VDVSYNE2_RMK(params->vSyncYStopFld2, params->vSyncXStopFld2);
base[_VP_VDCLIP_OFFSET] =
VP_VDCLIP_RMK(params->cClipHigh, params->cClipLow,
params->yClipHigh, params->yClipLow);
base[_VP_VDDEFVAL_OFFSET] = params->yDefVal |
(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 frmCnt = 0;
static void displayEdmaISR(tcc)
{
Int i;
FVID_Frame *viop, *curViop;
Int offset;
/* 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] || tcc == chan->tcc[1])){
/*****************************************************************************/
// AVSync changes (Tim Simerly) Feb. 8th, 2004
/*****************************************************************************/
// VideoAVSyncISR();
/* re-sync tcc with activeEDMARlds */
/* they may be out of sync after interrupt over-run */
/* e.g. execution is halted at break-point */
frmCnt ++;
chan->nextEDMARlds = (tcc == chan->tcc[0]) ? 0 : 1;
offset = chan->nextEDMARlds << 1;
/* update the current and next viop pointers */
curViop = chan->curViop;
chan->curViop = chan->nextViop;
chan->startFlag = 1;
if(!chan->asyncModeEnable) {
if((viop = (FVID_Frame *)QUE_dequeue(&chan->qIn))
!= (FVID_Frame *)&chan->qIn) {
/* queue IS not empty */
chan->nextViop = viop;
}else {
chan->queEmpty = TRUE;
}
}
/* Update the EDMA reload entry */
if(chan->mergeFlds){
EDMA_RSETH(chan->hRld[offset], SRC,
chan->nextViop->frame.iFrm.y1);
EDMA_RSETH(chan->hRld[offset + 1], SRC,
chan->nextViop->frame.iFrm.y2);
if(!(chan->mode & _VPORT_MASK_RAW)){
EDMA_RSETH(chan->hRld[4 + offset], SRC,
chan->nextViop->frame.iFrm.cb1);
EDMA_RSETH(chan->hRld[5 + offset], SRC,
chan->nextViop->frame.iFrm.cb2);
EDMA_RSETH(chan->hRld[8 + offset], SRC,
chan->nextViop->frame.iFrm.cr1);
EDMA_RSETH(chan->hRld[9 + offset], SRC,
chan->nextViop->frame.iFrm.cr2);
}
} else {
EDMA_RSETH(chan->hRld[offset], SRC,
chan->nextViop->frame.iFrm.y1);
if(! (chan->mode & _VPORT_MASK_RAW)){
EDMA_RSETH(chan->hRld[offset + 4], SRC,
chan->nextViop->frame.iFrm.cb1);
EDMA_RSETH(chan->hRld[offset + 8], 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->packetIOM->status = IOM_COMPLETED;
chan->cbFxn((Ptr)chan->cbArg, chan->packetIOM);
chan->packetIOM = INV;
}else {
QUE_enqueue(&chan->qOut,curViop);
}
}/*if(curViop != chan->curViop) {*/
}/*if((chan->status & READY) && tcc == chan->tcc){*/
} /*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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -