📄 qmc.c
字号:
if(pCfg->InitSIMODE!=NULL)pCfg->InitSIMODE();
/* Step 2: Initialize the SICR (SI clock route) register */
SPLX(pda->si_sicr &= (~( (0x000000ff)<<(pCfg->ch*8) ));)
SPLX(pda->si_sicr |= ( (0x00000040)<<(pCfg->ch*8) );)
/* Step 3: Configure port A for TDMa and/or TDMb signals */
if(pCfg->InitIOMap!=NULL)pCfg->InitIOMap();
/* Step 6: Write the values to the SI RAM locations that will route the time slots required */
if(pCfg->InitTDM!=NULL)pCfg->InitTDM();
/* Step 7: Enable TDM */
SPLX(pda->si_sigmr|=(0x04)<<(pCfg->UseTDM-1);) /*enable static TDMA */
/* Step 9. Initialize general SCCx mode reg high */
regs(pCfg->ch).scc_gsmrb = 0x00000780; /* QMC 之不同 */
regs(pCfg->ch).scc_gsmra = 0x0000000A; /* QMC 之不同 */
/* Step 11. Initialize basic global multichannel parameters as follows. */
/* init Grobal Params*/
gmp->mcbase=(unsigned long)pCfg->BDTable;/* point to the start of BD table*/
gmp->mrblr=pCfg->MaxBufLen-8; /* set the MAX buffer length*/
gmp->intbase=(unsigned long)pCfg->IntTable;/*point to the start of int tab*/
gmp->grfthr=1; /* 1 receive frame to interrupt*/
gmp->grfcnt=1; /* 1 receive frame to interrupt*/
gmp->cmask32=0xdebb20e3; /*32 bit crc constant */
gmp->cmask16=0xf0b8; /*16 bit crc constant */
/* Step 12. Copy INTBASE to INTPTR */
gmp->intptr=gmp->intbase;
/* Step 13. Initialize the time slot assignment tables */
for (i=0;i<32;i++) /*init receive time slot table*/
{
gmp->tsatr[i].w=0;
gmp->tsatr[i].chp=0; /* init one slot to one channel */
gmp->tsatr[i].mask0_1 =0; /* no subchannel */
gmp->tsatr[i].mask2_7 =0;
gmp->tsatr[i].v=0;
}
for (i=0;i<pCfg->MaxRecvTSAEntry;i++)
{
if(pCfg->IsSuperChan==1)
{
gmp->tsatr[i].w=0; /* init config slots to channels */
gmp->tsatr[i].chp=pCfg->RecvTsTable[i];
gmp->tsatr[i].mask0_1 =0x3; /* no subchannel */
gmp->tsatr[i].mask2_7 =0x3f;
gmp->tsatr[i].v=1;
}
else
{
gmp->tsatr[i].w=0; /* init one slot to one channel */
gmp->tsatr[i].chp=i+(pCfg->SubChParamOffset>>6);
gmp->tsatr[i].mask0_1 =0x3; /* no subchannel */
gmp->tsatr[i].mask2_7 =0x3f;
gmp->tsatr[i].v=1;
}
}
gmp->tsatr[i-1].w=1;
for (i=0;i<32;i++) /* init transmit time slot table */
{
gmp->tsatt[i].w=0;
gmp->tsatt[i].chp=0;
gmp->tsatt[i].mask0_1 =0;
gmp->tsatt[i].mask2_7 =0;
gmp->tsatt[i].v=0;
}
for (i=0;i<pCfg->MaxSendTSAEntry;i++) /* init transmit time slot table */
{
if(pCfg->IsSuperChan==1)
{
gmp->tsatt[i].w=0; /* init one slot to one channel */
gmp->tsatt[i].chp=pCfg->SendTsTable[i];
gmp->tsatt[i].mask0_1 =0x3; /* no subchannel */
gmp->tsatt[i].mask2_7 =0x3f;
gmp->tsatt[i].v=1;
}
else
{
gmp->tsatt[i].w=0;
gmp->tsatt[i].chp=i+(pCfg->SubChParamOffset>>6);
gmp->tsatt[i].mask0_1 =0x3;
gmp->tsatt[i].mask2_7 =0x3f;
gmp->tsatt[i].v=1;
}
}
gmp->tsatt[i-1].w=1;
/* Step 14. Initialize TSAT pointers */
gmp->rx_s_ptr=0x3C00+0x100*pCfg->ch+0x20; /* init pointer to rsatr */
gmp->tx_s_ptr=0x3C00+0x100*pCfg->ch+0x60; /* init pointer to tsatr */
gmp->rxptr=gmp->rx_s_ptr;
gmp->txptr=gmp->tx_s_ptr;
/* Step 15. Initialize multichannel controller state QMC-STATE to 0x8000 */
gmp->qmcstate=0x8000;
}
int QmcCntrl(void *pDataBuf, int cmd, void *pParam, int maxlen)
{
int i;
PDA *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct *pData=(DataBufStruct *)pDataBuf;
QmcSubChanCfgStruct *pCfg =(QmcSubChanCfgStruct *)(pData+1);
QmcGlobalCfgStruct *pGCfg=pCfg->pGCfg;
QmcSupChanTsCfgStruct *pQmcTsCfg;
QmcGlobalParamStruct *gmp;
int ret=BDCntrl(pDataBuf, cmd, pParam, maxlen);
if(ret!=SDE_UNKNOW_CMD)return ret;
switch(cmd)
{
case SDC_REINIT: /* WARN!!! This is cmd will effect other subch!! */
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
QmcStopOp( (QmcSubChanCfgStruct*)((DataBufStruct *)
(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
}
QmcGlobalInit(pCfg->pGCfg,pCfg->pGCfg);
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
memset((pGCfg->IsrParam)[i+pGCfg->SubChParamOffset/64],0,
sizeof(DataBufStruct));
QmcSubChanInit((DataBufStruct *)(pGCfg->IsrParam
[i+pGCfg->SubChParamOffset/64]),(QmcSubChanCfgStruct*)
((DataBufStruct *)(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
}
QmcInitEnd(pCfg->pGCfg);
break;
case SDC_SET_TSA_LOOPBACK_MODE: /* WARN!!! effect other subch!! */
if(pCfg->pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
if(pCfg->pGCfg->UseTDM==1)SPLX(pda->si_simode|=0x00000c00;)
if(pCfg->pGCfg->UseTDM==2)SPLX(pda->si_simode|=0x0c000000;)
break;
case SDC_SET_NORMAL_MODE: /* WARN!!! effect other subch!! */
if(pCfg->pGCfg->UseTDM==0)return SDE_UNKNOW_CMD;
if(pCfg->pGCfg->UseTDM==1)SPLX(pda->si_simode&=0xfffff3ff;)
if(pCfg->pGCfg->UseTDM==2)SPLX(pda->si_simode&=0xf3ffffff;)
break;
case SDC_SET_TX_NO_CRC_MODE:
QmcStopOp(pCfg);
QmcResetSubChan(pData,pCfg);
for(i=0;i<pData->MaxSendBD;i++)
pData->pBaseSendBD[i].status &= (~HDLC_TX_CRC);
QmcStartOp(pCfg);
break;
case SDC_SET_TS_MAP:
if(maxlen!=sizeof(QmcSupChanTsCfgStruct))
return SDE_INVALID_ARG;
pQmcTsCfg=(QmcSupChanTsCfgStruct*)pParam;
for(i=0;i<pGCfg->MaxRecvTSAEntry;i++)
if((pQmcTsCfg->RecvTsTable[i]>=pGCfg->MaxSubChanNum+(pGCfg->SubChParamOffset>>6) )
||(pQmcTsCfg->RecvTsTable[i]<(pGCfg->SubChParamOffset>>6)) )
return SDE_INVALID_ARG;
for(i=0;i<pGCfg->MaxSendTSAEntry;i++)
if((pQmcTsCfg->SendTsTable[i]>=pGCfg->MaxSubChanNum+(pGCfg->SubChParamOffset>>6))
||(pQmcTsCfg->SendTsTable[i]<(pGCfg->SubChParamOffset>>6))
)
return SDE_INVALID_ARG;
memmove(pGCfg->RecvTsTable,pQmcTsCfg,sizeof(QmcSupChanTsCfgStruct));
pGCfg->IsSuperChan=1;
gmp =(QmcGlobalParamStruct *)((GetIMMR()&IO_MAP_MASK)+0x3C00+0x100*pGCfg->ch);
for (i=0;i<32;i++) /*init receive time slot table*/
{
gmp->tsatr[i].v=0;
gmp->tsatr[i].chp=0; /* init one slot to one channel */
gmp->tsatr[i].mask0_1 =0; /* no subchannel */
gmp->tsatr[i].mask2_7 =0;
}
for (i=0;i<pGCfg->MaxRecvTSAEntry;i++)
{
gmp->tsatr[i].chp=pQmcTsCfg->RecvTsTable[i];
gmp->tsatr[i].mask0_1 =0x3; /* no subchannel */
gmp->tsatr[i].mask2_7 =0x3f;
gmp->tsatr[i].v=1;
}
gmp->tsatr[i-1].w=1;
for (i=0;i<32;i++) /* init transmit time slot table */
{
gmp->tsatt[i].v=0;
gmp->tsatt[i].chp=0;
gmp->tsatt[i].mask0_1 =0;
gmp->tsatt[i].mask2_7 =0;
}
for (i=0;i<pGCfg->MaxSendTSAEntry;i++) /* init transmit time slot table */
{
gmp->tsatt[i].chp=pQmcTsCfg->SendTsTable[i];
gmp->tsatt[i].mask0_1 =0x3; /* no subchannel */
gmp->tsatt[i].mask2_7 =0x3f;
gmp->tsatt[i].v=1;
}
gmp->tsatt[i-1].w=1;
break;
case SDC_SET_SUBCH_LOOP:
if(pGCfg->SetSubChLoop==NULL) return SDE_SET_SUBCH_LOOP_FAULSE;
ret=pGCfg->SetSubChLoop(pCfg,1);
if(ret<0) return SDE_SET_SUBCH_LOOP_FAULSE;
break;
case SDC_SET_SUBCH_UNLOOP:
if(pGCfg->SetSubChLoop==NULL) return SDE_SET_SUBCH_LOOP_FAULSE;
ret=pGCfg->SetSubChLoop(pCfg,0);
if(ret<0) return SDE_SET_SUBCH_LOOP_FAULSE;
break;
case SDC_LIMITE_REINIT:
QmcLimitReInit(pGCfg);
break;
default:
return SDE_UNKNOW_CMD;
}/* end of switch(cmd) */
return SDE_OK;
}
/* allocate memory for Qmc */
UCHAR *QmcBspGlobalInit(UCHAR *FreeMemPtr, QmcGlobalCfgStruct *pGCfg,
QmcGlobalCfgStruct **id)
{
pGCfg->UncachedBuffer
=AllocUncachedBuffer((pGCfg->MaxRecvBD+pGCfg->MaxSendBD)
*pGCfg->MaxSubChanNum*pGCfg->MaxBufLen,64);
pGCfg->BDTable
=AllocUncachedBuffer((pGCfg->MaxRecvBD+pGCfg->MaxSendBD)
*pGCfg->MaxSubChanNum*BD_LEN,64);
pGCfg->IntTable
=(IntEntryStruct*)AllocUncachedBuffer(pGCfg->IntTableLen*2,64);
QmcGlobalInit(FreeMemPtr,pGCfg);
if(id)*id=(QmcGlobalCfgStruct*)FreeMemPtr;
FreeMemPtr += sizeof(QmcGlobalCfgStruct);
memcpy(FreeMemPtr,"**QmcDat",8);
FreeMemPtr += 8;
return FreeMemPtr;
}
/* allocate memory for Qmc' SubChan , id, return from QmcGlobalBspInit */
UCHAR *QmcBspSubChanInit(int DEV, UCHAR *FreeMemPtr,
QmcSubChanCfgStruct *pCfg, QmcGlobalCfgStruct *pGCfg)
{
pCfg->pGCfg=pGCfg;
InstallSD(DEV,QmcRead,QmcWrite,QmcCntrl,FreeMemPtr);
memset(FreeMemPtr, 0, sizeof(DataBufStruct));
QmcSubChanInit(FreeMemPtr, pCfg);
pGCfg->IsrParam[pCfg->ch]=FreeMemPtr;
FreeMemPtr += sizeof(DataBufStruct)+sizeof(QmcSubChanCfgStruct);
memcpy(FreeMemPtr,"**QmcSub",8);
FreeMemPtr += 8;
return FreeMemPtr;
}
void QmcInitEnd(QmcGlobalCfgStruct* pGCfg)
{
PDA *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
/* regs(pGCfg->ch).scc_gsmrb=0x780;
/* regs(pGCfg->ch).scc_gsmra=0x0a; /* enable QMC*/
/* Step 21. Initialize the SCCE register */
regs(pGCfg->ch).scc_scce=0xffff;
/* Step 22. Initialize the mask register, */
regs(pGCfg->ch).scc_sccm=0x000f; /*enable all */
SPLX(pda->cpmi_cimr|=(EN_SCC1 >> pGCfg->ch);)
SPLX(pda->cpmi_cipr|=(CLR_SCC1 >> pGCfg->ch);)
SPLX(pda->cpmi_cisr|=(CLR_SCC1 >> pGCfg->ch);)
SPLX(pda->cpmi_cicr|=CPM_EN_INTS|0x1b0000;)
#ifdef QMCPOLLING
SPLX(pda->cpmi_cimr&=(~(EN_SCC1 >> 1));)/* disable scc interrutp */
#endif
/* Step 23. Enable the transmitter and the receiver GSMR */
regs(pGCfg->ch).scc_gsmra|=0x00000030;/* Enable tx and rx */
}
static void QmcLimitReInit(QmcGlobalCfgStruct *pGCfg)
{
int i;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
QmcStopOp( (QmcSubChanCfgStruct*)((DataBufStruct *)
(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
}
QmcGlobalInit(pGCfg,pGCfg);
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
QmcSubChanInit((DataBufStruct *)(pGCfg->IsrParam
[i+pGCfg->SubChParamOffset/64]),(QmcSubChanCfgStruct*)
((DataBufStruct *)(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
}
QmcInitEnd(pGCfg);
}
/*************************************/
/* BYTE HdlcPathInit( BYTE byHdlcWid)
/* function: set HDLC Windows width
/* return value: 1-sucsess 0-fail
/* input: 0-64k,1-128k HDLC Windows width
/* version:0.0 2005-9-17 tianrongen
/*************************************/
BYTE HdlcPathInit( UCHAR byHdlcWid)
{
int i,j,Dev;
void *pDataBuf;
DataBufStruct *pData;
QmcSubChanCfgStruct *pCfg;
QmcGlobalCfgStruct *pGCfg,gcfg_set;
pDataBuf=(void *)sd_table[SDN_FRP1_SIG].databuf;
pData=(DataBufStruct *)pDataBuf;
pCfg =(QmcSubChanCfgStruct *)(pData+1);
pGCfg=pCfg->pGCfg;/*get current pGCfg*/
memset(&gcfg_set,0,sizeof(QmcGlobalCfgStruct));
memcpy(&gcfg_set,pGCfg,sizeof(QmcGlobalCfgStruct));
if(byHdlcWid==0)/*set gcfg_set for 64k HDLC config */
{
gcfg_set.IsSuperChan=0;
for(j=0;j<BD_QMC_CHAN_NUM;j++)
{
gcfg_set.SendTsTable[j]= j;
gcfg_set.RecvTsTable[j]= j;
}
}
else if(byHdlcWid==1)/*set gcfg_set for 128k HDLC config */
{
gcfg_set.IsSuperChan=1;
for(i=0;i<BD_QMC_CHAN_NUM;i++)
{
gcfg_set.SendTsTable[i]=(i>9) ? 10+(i-10)/2 : i;
gcfg_set.RecvTsTable[i]=(i>9) ? 10+(i-10)/2 : i;
}
}
else
return SDE_INVALID_ARG;/*Input is invalid */
for(Dev=SDN_FRP1_SIG;Dev<SDN_FRP1_SIG+14;Dev++)
sd_smp(Dev,0);/* ban DEV access*/
for(i=0;i<pGCfg->MaxSubChanNum;i++)/*ban interrupt*/
{
QmcStopOp( (QmcSubChanCfgStruct*)((DataBufStruct *)
(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
}
memcpy(pGCfg,&gcfg_set,sizeof(gcfg_set));/*use set config ordered */
QmcGlobalInit(pCfg->pGCfg,pCfg->pGCfg);
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
memset((pGCfg->IsrParam)[i+pGCfg->SubChParamOffset/64],0,
sizeof(DataBufStruct));
QmcSubChanInit((DataBufStruct *)(pGCfg->IsrParam
[i+pGCfg->SubChParamOffset/64]),(QmcSubChanCfgStruct*)
((DataBufStruct *)(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1) );
/*QmcStartOp((QmcSubChanCfgStruct*)
((DataBufStruct *)(pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64])+1));*/
}
QmcInitEnd(pCfg->pGCfg);
for(Dev=SDN_FRP1_SIG;Dev<SDN_FRP1_SIG+14;Dev++)
sd_smv(Dev);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -