📄 vportdis.c
字号:
Int8* curAddr;
if(chan->status & _VPORT_CFGED) {
assert(params->numFrmBufs >= 2
&& params->numFrmBufs <= VPORT_MAX_NUM_FRMBUFS);
chan->numFrms = params->numFrmBufs;
chan->segId = params->segId;
/* allocate frame buffers */
chan->bufSz = chan->yPitch * chan->numLines
+ chan->cPitch * chan->numLines * 2;
for(i = 0; i < chan->numFrms; i ++) {
if((curAddr = MEM_calloc(params->segId,chan->bufSz,
params->alignment)) == MEM_ILLEGAL){
int j;
for(j = 0; j < i ; j ++) {
MEM_free(params->segId, chan->viops[j].frame.iFrm.y1,
chan->bufSz);
}
/* memory allocation fails */
return IOM_EALLOC;
}
/* field 1 */
chan->viops[i].frame.iFrm.y1 = curAddr;
curAddr += chan->numLines*chan->yPitch;
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->yPitch;
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;
}else {
chan->viops[i].frame.iFrm.y2 = chan->viops[i].frame.iFrm.y1
+ (chan->numLinesFld1*chan->yPitch);
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);
}
if(i > 1) {
/* don't put the first 1 viop into the queue */
QUE_enqueue(&chan->qOut, (QUE_Handle)&chan->viops[i]);
}
}
chan->nextViop = &chan->viops[1];
chan->curViop = &chan->viops[0];
if(chan->mode & _VPORT_MASK_RAW) edmaChans = 1;
else edmaChans = 3;
for(i = 0; i < edmaChans; i ++) {
Int optFld1 = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_YES,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_NONE,
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_YES,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_NONE,
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
);
thrld = (i == 0)? chan->yThrld:chan->cThrld;
cfgEdma.dst = EDMA_DST_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*/
/* first field */
cfgEdma.opt = optFld1;
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.src = EDMA_SRC_RMK(
*((Int *)(&chan->viops[0].frame.iFrm.y1) + i));
cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[2*i + 1]);
EDMA_config(chan->hEdma[i], &cfgEdma);
EDMA_config(chan->hRld[2 * i], &cfgEdma);
/* second field */
cfgEdma.opt = optFld2;
cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[2 * i]);
cfgEdma.cnt = EDMA_CNT_RMK(
(chan->numEvents-chan->numEventsFld1) - 1, (thrld << 1));
cfgEdma.src = EDMA_SRC_RMK(
*((Int *)(&chan->viops[0].frame.iFrm.y2) + 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);
/* hard code the first and second frame buffer as current */
/*and reload buffers */
cfgEdma.src = EDMA_SRC_RMK(
*((Int *)(&chan->viops[0].frame.iFrm.y1) + i));
cfgEdma.rld = EDMA_RLD_RMK(0, chan->hRld[i]);
EDMA_config(chan->hEdma[i], &cfgEdma);
cfgEdma.src = EDMA_SRC_RMK(
*((Int *)(&chan->viops[1].frame.iFrm.y1) + i));
EDMA_config(chan->hRld[i], &cfgEdma);
}
}
/* enable EDMA channel */
if(!(chan->mode & _VPORT_MASK_RAW)) {
EDMA_clearChannel(chan->hEdma[1]);
EDMA_enableChannel(chan->hEdma[1]);
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_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);
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->numLines = numLines;
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 |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -