?? qmcsw.c
字號:
_sync_io();
QmcSwGlobalInit();
splx(imask);
if(pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
if(pGCfg->UseTDM==1)SPLX(pda->si_simode|=0x00000c00;)
if(pGCfg->UseTDM==2)SPLX(pda->si_simode|=0x0c000000;)
break;
case SDC_SET_NORMAL_MODE:
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
StopReceive(i);
StopTransmit(i);
}
imask = splx(MAX_ILEV);/* mask interrupt*/
_sync_io();
QmcSwGlobalInit();
splx(imask);
if(pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
if(pGCfg->UseTDM==1)SPLX(pda->si_simode&=0xfffff3ff;)
if(pGCfg->UseTDM==2)SPLX(pda->si_simode&=0xf3ffffff;)
break;
case SDC_LIMITE_REINIT:
QmcSwLimitInit();
break;
default:
return SDE_UNKNOW_CMD;
}/*end of switch cmd */
return SDE_OK;
}/*end of QmcSwCtrl*/
static void QmcSwSubIsr(IntEntryStruct *ptr);
static void QmcIsr(void)
{
USHORT Events,Status;
PDA *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
IntEntryStruct *pIntrpt;
Events = pda->Scc_regs[pGCfg->ch].scc_scce;
pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event reg*/
pIntrpt=pGCfg->IntTablePtr;
if(Events & QMC_GLOB_INT) /* global interrupt */
{
while((pIntrpt->Bit).v) /* search the int table to find valid entry */
{
if(pIntrpt->Bit.rxf||pIntrpt->Bit.bsy||pIntrpt->Bit.txb)
QmcSwSubIsr(pIntrpt);
if((pIntrpt->Bit).w)/*process interrupt table */
{
pIntrpt->Word16=0;
(pIntrpt->Bit).w=1;
pIntrpt=pGCfg->IntTable;
}
else
{
pIntrpt->Word16=0;
pIntrpt++;
}
pGCfg->IntTablePtr=pIntrpt;
}/*end for while*/
} /*end for if global events*/
if((Events&QMC_GLOB_OV)!=0 || (Events&QMC_GLOB_UN)!=0)
{
int i;
UCHAR map[32];
memmove(map,MapTable,pGCfg->MaxSubChanNum);
QmcSwGlobalInit();
memmove(MapTable,map,pGCfg->MaxSubChanNum);
for(i=0;i<pGCfg->MaxSubChanNum;i++){
if(MapTable[i]!=QMCSW_SUBCHAN_INVALID)ReStartReceive(i);
ReStartTransmit(i);
}
}
if(Events&QMC_GLOB_IQOV) /* interrupt table is overflow */
{
int i;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
if(MapTable[i]!=QMCSW_SUBCHAN_INVALID)ReStartReceive(i);
ReStartTransmit(i);
}
}
} /*end of QmcSwIsr */
static void QmcSwSubIsrSend(int OutChannel)
{
QmcSubChanParamStruct *ch=(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)
+0x2000+pGCfg->SubChParamOffset);
LinkBufStruct *pData;
for(;;){
int cur=gDataBuf[OutChannel]->CurSendBD;
BuffDescType *bd=&(gDataBuf[OutChannel]->pBaseSendBD[cur]);
if((bd->status&BD_READY)==BD_READY) break;
if(LinkNumber(&TxLink[OutChannel])==0) break;
if(bd->address!=0 )
{
pData=(LinkBufStruct*)((ULONG)bd->address-8); /* adjust the addr*/
LinkAppendBuf(&FreeLink,pData);
}
pData=LinkGetBuf(&TxLink[OutChannel]);
bd->address=pData->Data;
bd->length=pData->Length;
bd->status&=(~gDataBuf[OutChannel]->SendErrMask);
bd->status|=BD_READY;
gDataBuf[OutChannel]->DrvInfo.SendPerNum++; /*statistic*/
gDataBuf[OutChannel]->CurSendBD=(gDataBuf[OutChannel]->CurSendBD+1)
%pGCfg->MaxSendBD;
}
ch[OutChannel].chamr.pol=1;
}
static void QmcSwSubIsr(IntEntryStruct *ptr)
{
USHORT Status;
LinkBufStruct *pData;
int InChannel=ptr->Bit.chnum;
int OutChannel;
if((ptr->Bit.rxf||ptr->Bit.bsy))
{
gDataBuf[InChannel]->DrvInfo.TotalRecvInt++; /* statistic */
OutChannel=MapTable[InChannel];
if((OutChannel==QMCSW_SUBCHAN_OPERATE)
&&(gDataBuf[InChannel]->RecvEv!=NULL)
&&(gDataBuf[InChannel]->RecvTid!=NULL))
{
ev_send(gDataBuf[InChannel]->RecvTid,gDataBuf[InChannel]->RecvEv);
if(ptr->Bit.bsy) ReStartReceive(InChannel);
}
else
{
for(;;)
{
BuffDescType *bd=&(gDataBuf[InChannel]->pBaseRecvBD \
[gDataBuf[InChannel]->CurRecvBD]);
Status=bd->status;
if((Status&BD_EMPTY)==BD_EMPTY) break;
if(((Status&gDataBuf[InChannel]->RecvErrMask)==0)
&&(bd->length>2)
&&(OutChannel<pGCfg->MaxSubChanNum)
&&(OutChannel>=0)
)
{
if(LinkNumber(&FreeLink)==0) break;
if(bd->address!=0)
{
pData=(LinkBufStruct*)((ULONG)bd->address-8);/*adjust the addr*/
pData->Length=bd->length-2;
LinkAppendBuf(&TxLink[OutChannel],pData);
gDataBuf[OutChannel]->DrvInfo.SendTryNum++; /* statistic */
}
pData=(LinkBufStruct*)LinkGetBuf(&FreeLink);
bd->address=pData->Data;
}
if((Status&gDataBuf[InChannel]->RecvErrMask)!=0)
{
int i;
gDataBuf[InChannel]->DrvInfo.RecvError++; /*statistic */
for(i=0;i<=15;i++)
if(Status&(0x8000L>>i))
gDataBuf[InChannel]->DrvInfo.RecvBDStat[i]++;
}
else
gDataBuf[InChannel]->DrvInfo.RecvNum++; /*statistic */
bd->status&=(~gDataBuf[InChannel]->RecvErrMask);
bd->status|=BD_EMPTY;
gDataBuf[InChannel]->CurRecvBD=(gDataBuf[InChannel]->CurRecvBD+1)
%pGCfg->MaxRecvBD;
} /* end of recv */
if(ptr->Bit.bsy) ReStartReceive(InChannel);
if((OutChannel>=0)
&&(OutChannel<pGCfg->MaxSubChanNum))
QmcSwSubIsrSend(OutChannel);
}
} /* end of receive */
/* start to process send */
if(ptr->Bit.txb)
{
gDataBuf[InChannel]->DrvInfo.TotalSendInt++;
if((gDataBuf[InChannel]->SendEv!=NULL)/* if set ev and id then this*/
&&(gDataBuf[InChannel]->SendTid!=NULL))/* channel process by up procedure*/
ev_send(gDataBuf[InChannel]->SendTid,gDataBuf[InChannel]->SendEv);
QmcSwSubIsrSend(InChannel); /* send intr */
}
} /*end of QmcSwSubIsr()*/
char *QmcSwBspInit(int DEV, char *FreeMemPtr,QmcSwCfgStruct *gcfg)
{
int i;
pGCfg=(QmcSwCfgStruct*)FreeMemPtr; /* need to add check param */
InstallSD(DEV,QmcSwRead,QmcSwWrite,QmcSwCntrl,FreeMemPtr);
memmove((char*)pGCfg,(char*)gcfg,sizeof(QmcSwCfgStruct));
FreeMemPtr+= sizeof(QmcSwCfgStruct);
pGCfg->UncachedBuffer
=(char*)AllocUncachedBuffer(pGCfg->MaxBufNum
*(sizeof(LinkBufStruct)+pGCfg->MaxBufLen-LINK_DATA_BUF_LEN),64);
pGCfg->BDTable
=(char*)AllocUncachedBuffer((pGCfg->MaxRecvBD+pGCfg->MaxSendBD)
*pGCfg->MaxSubChanNum*sizeof(BuffDescType),64);
pGCfg->IntTable
=(IntEntryStruct*)AllocUncachedBuffer(pGCfg->MaxIntEty \
*sizeof(IntEntryStruct),64);
pGCfg->IntTablePtr=pGCfg->IntTable;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
gDataBuf[i]=(DataBufStruct*)FreeMemPtr;
memset(gDataBuf[i],0,sizeof(DataBufStruct));
FreeMemPtr+=sizeof(DataBufStruct);
}
QmcSwGlobalInit();
memcpy(FreeMemPtr,"***QMCSW",8);
FreeMemPtr += 8;
return FreeMemPtr;
}
void QmcSwLimitInit()
{
UCHAR map[32];
int i,imax;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
StopTransmit(i);
StopReceive(i);
}
(*(pGCfg->InitTDM))();
imax=splx(MAX_ILEV);
memmove(map,MapTable,pGCfg->MaxSubChanNum);
QmcSwGlobalInit();
memmove(MapTable,map,pGCfg->MaxSubChanNum);
splx(imax);
pGCfg->FatalFlag=0;
}
/* this task is used for single channel loop back test */
/* 發(fā)送5個(gè),若接收的錯(cuò)包多于3個(gè),重新初始化*/
ULONG QmcClkErrNum;
ULONG QmcLoopErrNum;
void QmcSwBspTestTask(ULONG TaskID)
{
SDCSetActionStruct SDCSet;
char TBuf[100];
char RBuf[272];
int i,ret,ClkStatus;
ULONG ev;
ULONG OldErrorNum,SendNum,RecvCheckErr;
SDCGetDriverInfoStruct DrvInfo;
QmcSubChanParamStruct *ch=(QmcSubChanParamStruct*)((GetIMMR()&IO_MAP_MASK)
+0x2000+pGCfg->SubChParamOffset);
OldErrorNum=0;
RecvCheckErr=0;
SendNum=0;
QmcClkErrNum=0;
QmcLoopErrNum=0;
memset(&SDCSet,0,sizeof(SDCSetActionStruct));
SDCSet.RecvTid=TaskID;
SDCSet.RecvEv=QMCSW_BSP_LOOP_RECV_EV;
SDCSet.SendTid=TaskID;
SDCSet.SendEv=QMCSW_BSP_LOOP_SEND_EV;
BDCntrl(gDataBuf[pGCfg->MaxSubChanNum-1],SDC_SET_ACTION,&SDCSet,
sizeof(SDCSetActionStruct));
while(1)
{
/* check the clk is right*/
ClkStatus=(*(pGCfg->QmcSwClkErr))();
if(ClkStatus==1)
{
pGCfg->FatalFlag=1;
while((pGCfg->WrInUsing!=0) /*wait until all the channel not inusing */
||(pGCfg->ReInUsing!=0))
tm_wkafter(1);
QmcClkErrNum++;
QmcSwLimitInit(); /*reinit the channel */
}
sprintf(TBuf,"QMCSW Single Channel Loop Test");
ret=BDWrite(gDataBuf[pGCfg->MaxSubChanNum-1],TBuf,strlen(TBuf));
ch[pGCfg->MaxSubChanNum-1].chamr.pol=1;
SendNum++;
if(ret<0) tm_wkafter(1);
ret=ev_receive(QMCSW_BSP_LOOP_RECV_EV,EV_WAIT,100,&ev);
if(ret==0)
if((ev&QMCSW_BSP_LOOP_RECV_EV)==QMCSW_BSP_LOOP_RECV_EV)
{
for(;;)
{
memset(RBuf,0,272);
ret=BDRead(gDataBuf[pGCfg->MaxSubChanNum-1],RBuf,272);
if(ret==SDE_BUF_EMPTY) break;
else
{
ret=memcmp(TBuf,RBuf,strlen(TBuf));/* check the loop back data is right */
if(ret!=0) RecvCheckErr++; /* set the fatal flag */
}
}/* end for*/
}
else pGCfg->FatalFlag=1; /* receive unknown event */
else pGCfg->FatalFlag=1; /* evreceive time out */
if(SendNum%5==0)
{
BDCntrl(gDataBuf[pGCfg->MaxSubChanNum-1],SDC_GET_DRIVER_INFO,&DrvInfo,sizeof(SDCGetDriverInfoStruct));
if((DrvInfo.RecvError-OldErrorNum+RecvCheckErr)>3)
pGCfg->FatalFlag=1;
OldErrorNum=DrvInfo.RecvError;
RecvCheckErr=0;
}
if((pGCfg->FatalFlag==1)&&(SendNum%5==0))
{
while((pGCfg->WrInUsing!=0) /*wait until all the channel not inusing */
||(pGCfg->ReInUsing!=0))
tm_wkafter(1);
QmcSwLimitInit(); /*reinit the channel */
QmcLoopErrNum++;
}
tm_wkafter(100);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -