?? qmc.c
字號:
#include "board.h"
#include "sdev.h"
#include "hdlc.h"
#include "qmc.h"
#define regs(ch) pda->Scc_regs[ch]
#if QMCPOLLING
void * Global_pGCfg;
#endif
/*---------Local functions-----------------------------*/
static void ReInitAllRecvCh(QmcGlobalCfgStruct *pGCfg);
static void ReInitAllSendCh(QmcGlobalCfgStruct *pGCfg);
static void QmcResetSubChan(DataBufStruct *pData,QmcSubChanCfgStruct *);
static void QmcStopOp(QmcSubChanCfgStruct *pCfg);
static void QmcStartOp(QmcSubChanCfgStruct *pCfg);
static void QmcSubChanIsr(void *pDataBuf,IntEntryStruct *pIES);
#ifndef QMCPOLLING
static void QmcIsr(void *pDataBuf);
#endif
static void QmcLimitReInit(QmcGlobalCfgStruct *pGCfg);
static void QmcResetSubChan(DataBufStruct *pData,QmcSubChanCfgStruct *pCfg)
{
int i;
/* QmcGlobalCfgStruct *pGCfg=pCfg->pGCfg;*/
QmcSubChanParamStruct* scpm=
(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);
scpm[pCfg->ch].tstate=0x30000000;
scpm[pCfg->ch].zistate=0x100;
scpm[pCfg->ch].tbptr=scpm[pCfg->ch].tbase;
scpm[pCfg->ch].rbptr=scpm[pCfg->ch].rbase;
pData->CurRecvBD=pData->CurSendBD=0;
for(i=0;i<pData->MaxRecvBD;i++)
pData->pBaseRecvBD[i].status = BD_EMPTY|BD_INTR;
if(i>0)pData->pBaseRecvBD[i-1].status |= BD_WRAP;
for(i=0;i<pData->MaxSendBD;i++)
pData->pBaseSendBD[i].status = BD_INTR|BD_LAST|HDLC_TX_CRC;
if(i>0)pData->pBaseSendBD[i-1].status |= BD_WRAP;
}
static void QmcStopOp(QmcSubChanCfgStruct *pCfg)
{
CPM_CMD(QMC_RESERVE|QMC_STOP_RX|((pCfg->ch)<<2));
CPM_CMD(QMC_RESERVE|QMC_STOP_TX|((pCfg->ch)<<2));
}
static void QmcStartOp(QmcSubChanCfgStruct *pCfg)
{
unsigned short k;
QmcGlobalParamStruct *gmp =(QmcGlobalParamStruct *)((GetIMMR()&IO_MAP_MASK)
+0x3C00+0x100*pCfg->pGCfg->ch);
QmcSubChanParamStruct* scpm=
(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);
k=pCfg->ch;
if(scpm[k].chamr.ent==0)/*do if channel is deactive*/
{
scpm[k].tstate=0x30000000;
scpm[k].zistate=0x100;
gmp->tsatt[k].v=1;
scpm[k].chamr.ent=1;
}
if(scpm[k].chamr.pol==0)
scpm[k].chamr.pol=1; /*start tx*/
scpm[k].rstate=0x31000000; /*start rev*/
scpm[k].zdstate=0x0000080;
}
int QmcRead(void *pDataBuf,void *pBuf, int MaxLen)
{
int ret;
/* DataBufStruct* pData=(DataBufStruct *)pDataBuf; */
/* QmcSubChanCfgStruct* pCfg =(QmcSubChanCfgStruct *)(pData+1); */
ret=BDRead(pDataBuf,pBuf,MaxLen);
if(ret>2)return ret-2; /* sub 2 bytes of CRC */
else if(ret>0)return SDE_INVALID_PACKET;
else return ret;
}
int QmcWrite(void *pDataBuf,void *pBuf, int MaxLen)
{
int ret;
DataBufStruct* pData=(DataBufStruct *)pDataBuf;
QmcSubChanCfgStruct* pCfg =(QmcSubChanCfgStruct *)(pData+1);
QmcSubChanParamStruct* scpm=
(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);
ret=BDWrite(pDataBuf,pBuf,MaxLen);
scpm[pCfg->ch].chamr.pol=1;
return ret;
}
static void QmcSubChanIsr(void *pDataBuf,IntEntryStruct *pIES)
{
IntEntryStruct ev=*pIES;
DataBufStruct* pData=(DataBufStruct *)pDataBuf;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
/* QmcSubChanCfgStruct* pCfg=(QmcSubChanCfgStruct *)(pData+1); keep for test*/
QmcSubChanParamStruct *pSubChanParam
=(QmcSubChanParamStruct *)((char*)pda+0x2000);
if( ev.Bit.bsy==1 )
{
pSubChanParam[ev.Bit.chnum].rstate=0x31000000;
pSubChanParam[ev.Bit.chnum].zdstate=0x0000080;
}
if( ev.Bit.un==1 )
{
pSubChanParam[ev.Bit.chnum].chamr.pol=1;
return;
}
if( ev.Bit.rxf == 1 || ev.Bit.rxb == 1|| ev.Bit.bsy==1)
{
pData->DrvInfo.TotalRecvInt++;
if( (pData->RecvEv!=NULL) && (pData->RecvTid!=NULL) )
{
ev_send(pData->RecvTid,pData->RecvEv);
}
if( pData->RecvQID!=NULL )
{
q_send(pData->RecvQID,pData->RecvMessage);
}
}
if( ev.Bit.txb == 1 )
{
pData->DrvInfo.TotalSendInt++;
if( (pData->SendEv!=NULL) && (pData->SendTid!=NULL) )
{
ev_send(pData->SendTid,pData->SendEv);
}
if( pData->SendQID!=NULL )
{
q_send(pData->SendQID,pData->SendMessage);
}
}
}
static void ReInitAllRecvCh(QmcGlobalCfgStruct *pGCfg)
{
USHORT i;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
QmcSubChanParamStruct *pSubChanParam
=(QmcSubChanParamStruct *)((char*)pda+0x2000);
DataBufStruct* pData;
QmcSubChanCfgStruct* pCfg;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
pData=(DataBufStruct*)pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64];
pCfg =(QmcSubChanCfgStruct *)(pData+1);
pSubChanParam[pCfg->ch].rstate=0x31000000;
pSubChanParam[pCfg->ch].zdstate=0x0000080;
}
pda->Scc_regs[pGCfg->ch].scc_gsmra|=0x00000020;/* Enable rx */
}
static void ReInitAllSendCh(QmcGlobalCfgStruct *pGCfg)
{
USHORT i;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
QmcSubChanParamStruct *pSubChanParam
=(QmcSubChanParamStruct *)((char*)pda+0x2000);
DataBufStruct* pData;
QmcSubChanCfgStruct* pCfg;
for(i=0;i<pGCfg->MaxSubChanNum;i++)
{
pData=(DataBufStruct*)pGCfg->IsrParam[i+pGCfg->SubChParamOffset/64];
pCfg =(QmcSubChanCfgStruct *)(pData+1);
pSubChanParam[pCfg->ch].chamr.pol=1;
}
pda->Scc_regs[pGCfg->ch].scc_gsmra|=0x00000010;/* Enable tx */
}
#ifndef QMCPOLLING
static void QmcIsr(void *pDataBuf)
{
unsigned short Events;
QmcGlobalCfgStruct *pGCfg=(QmcGlobalCfgStruct *)pDataBuf;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
Events = pda->Scc_regs[pGCfg->ch].scc_scce;
pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event register */
if( (Events & QMC_GLOB_OV)==QMC_GLOB_OV )
{
ReInitAllRecvCh(pGCfg);
return;
}
if( ((Events & QMC_GLOB_UN)==QMC_GLOB_UN) )
{
ReInitAllSendCh(pGCfg);
return;
}
if( ((Events & QMC_GLOB_INT )==QMC_GLOB_INT) /* global interrupt */
|| ((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV) )
{
while((pGCfg->IntTablePtr->Bit).v) /* search the interrupt table */
{
ULONG sub=pGCfg->IntTablePtr->Bit.chnum;
QmcSubChanIsr(pGCfg->IsrParam[sub],pGCfg->IntTablePtr);
pGCfg->IntTablePtr->Word16&=0x4000;
if(1 == pGCfg->IntTablePtr->Bit.w)
pGCfg->IntTablePtr=pGCfg->IntTable;
else
pGCfg->IntTablePtr++;
}
}/* end of if */
if((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV )
{
ReInitAllRecvCh(pGCfg);/* end of if */
}
} /* end of QmcIsr */
#else
void QmcIsr(void *pDataBuf)
{
unsigned short Events;
QmcGlobalCfgStruct *pGCfg=(QmcGlobalCfgStruct *)pDataBuf;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
Events = pda->Scc_regs[pGCfg->ch].scc_scce;
pda->Scc_regs[pGCfg->ch].scc_scce = Events; /* clear the event register */
if( (Events & QMC_GLOB_OV)==QMC_GLOB_OV )
{
ReInitAllRecvCh(pGCfg);
return;
}
if( ((Events & QMC_GLOB_UN)==QMC_GLOB_UN) )
{
ReInitAllSendCh(pGCfg);
return;
}
if( ((Events & QMC_GLOB_INT )==QMC_GLOB_INT) /* global interrupt */
|| ((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV) )
{
while((pGCfg->IntTablePtr->Bit).v) /* search the interrupt table */
{
ULONG sub=pGCfg->IntTablePtr->Bit.chnum;
QmcSubChanIsr(pGCfg->IsrParam[sub],pGCfg->IntTablePtr);
pGCfg->IntTablePtr->Word16&=0x4000;
if(1 == pGCfg->IntTablePtr->Bit.w)
pGCfg->IntTablePtr=pGCfg->IntTable;
else
pGCfg->IntTablePtr++;
}
}/* end of if */
if((Events & QMC_GLOB_IQOV)==QMC_GLOB_IQOV )
{
ReInitAllRecvCh(pGCfg);/* end of if */
}
}
#endif
void QmcSubChanInit(void *pDataBuf, QmcSubChanCfgStruct *cfg)
{
int i;
BuffDescType *temp_bufdes;
char *pRecvBuf,*pSendBuf;
DataBufStruct* pData=(DataBufStruct *)pDataBuf;
QmcSubChanCfgStruct* pCfg =(QmcSubChanCfgStruct *)(pData+1);
QmcGlobalCfgStruct * pGCfg=cfg->pGCfg;
QmcSubChanParamStruct* scpm=
(QmcSubChanParamStruct*)((GetIMMR() & IO_MAP_MASK)+0x2000);
/*--------------------------<< Initial data >>-------------------------------*/
memmove(pCfg,cfg,sizeof(*cfg));
memset(scpm[pCfg->ch], 0, sizeof(QmcSubChanParamStruct));
/* Step 16. Initialize channel-specific parameters for HDLC */
pCfg->ch&=0x3F;
pData->CurRecvBD=0;
pData->CurSendBD=0;
pData->MaxRecvBD=pGCfg->MaxRecvBD;
pData->MaxSendBD=pGCfg->MaxSendBD;
pData->MaxBufLen=pGCfg->MaxBufLen;
pData->RecvErrMask=(HDLC_DPLL_ERR|HDLC_GREATER_LEN|HDLC_NOT_ALIGNED
|HDLC_ABORT_SEQ|HDLC_RX_CRC|HDLC_OVERRUN|HDLC_CD_LOST);
pData->SendErrMask=(HDLC_UNDERRUN|HDLC_CTS_LOST);
pData->UncachedBuffer=pRecvBuf=pGCfg->UncachedBuffer
+(pGCfg->MaxRecvBD+pGCfg->MaxSendBD)*(pCfg->ch-pGCfg->SubChParamOffset/64)
*pGCfg->MaxBufLen;
pSendBuf=(char*)(pRecvBuf+( pGCfg->MaxRecvBD)*(pGCfg->MaxBufLen));
/*-------------------------<< stop SCCx operation >>----------------------*/
QmcStopOp(pCfg);
/*----------------------<< init SCCx >>-----------------------------------*/
scpm[pCfg->ch].tbase=(pGCfg->MaxRecvBD+pGCfg->MaxSendBD)*
(pCfg->ch-pGCfg->SubChParamOffset/64)*BD_LEN;
scpm[pCfg->ch].rbase=scpm[pCfg->ch].tbase+pGCfg->MaxSendBD*BD_LEN;
scpm[pCfg->ch].tstate=0x30000000;
scpm[pCfg->ch].rstate=0x31000000; /* we enable it later,in QmcStartOp() */
scpm[pCfg->ch].zistate=0x100; /* HDLC mode */
scpm[pCfg->ch].zdstate=0x80; /* we enable it later,in QmcStartOp() */
scpm[pCfg->ch].intmask=0x1e; /* enable UN,RXF TXB and BSY interrupt*/
scpm[pCfg->ch].mflr= pData->MaxBufLen-8; /* maximum frame length */
scpm[pCfg->ch].tbptr=scpm[pCfg->ch].tbase;
scpm[pCfg->ch].rbptr=scpm[pCfg->ch].rbase;
/* Step 17. Initialize RxBDs. */
/* rx */
temp_bufdes=pData->pBaseRecvBD
=(BuffDescType *)(pGCfg->BDTable+scpm[pCfg->ch].rbase);
for(i=0;i<pData->MaxRecvBD;i++)
{
temp_bufdes[i].status=BD_EMPTY|BD_INTR;
temp_bufdes[i].length=0;
temp_bufdes[i].address=pRecvBuf+i*pData->MaxBufLen;
}
if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
/* Step 18. Initialize TxBDs */
/* tx */
temp_bufdes=pData->pBaseSendBD
=(BuffDescType *)(pGCfg->BDTable+scpm[pCfg->ch].tbase);
for(i=0;i<pData->MaxSendBD;i++)
{
temp_bufdes[i].status=BD_INTR|BD_LAST|HDLC_TX_CRC;
temp_bufdes[i].length=pData->MaxBufLen-2;
temp_bufdes[i].address=pSendBuf+i*pData->MaxBufLen;
}
if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
pGCfg->IsrParam[pCfg->ch]=pDataBuf;
/* Step 19. Initialize the circular interrupt table */
/* init the interrupt table */
for(i=0;i<pGCfg->IntTableLen;i++)
pGCfg->IntTable[i].Word16=0;
if(i>=1)pGCfg->IntTable[i-1].Bit.w=1;
#ifdef QMCPOLLING
Global_pGCfg=(void *)pGCfg;
#else
SPLX(CpmIsrAddHandler(V_SCC1-pGCfg->ch,QmcIsr,(void *)pGCfg); )
#endif
/* Step 20. Initialize the channel mode register CHAMR */
scpm[pCfg->ch].chamr.mode=1; /* HDLC mode */
scpm[pCfg->ch].chamr.idlm=0; /* disable idle frame */
scpm[pCfg->ch].chamr.ent=1; /* enable channel xmit*/
scpm[pCfg->ch].chamr.crc=0; /* 16 bit crc */
scpm[pCfg->ch].chamr.nof=0; /* 1 flags */
scpm[pCfg->ch].chamr.pol=1; /* enable polling */
/* QmcStartOp(pCfg); */
}
void QmcGlobalInit(void *pDataBuf, QmcGlobalCfgStruct *cfg)
{
unsigned long i;
QmcGlobalCfgStruct *pCfg =(QmcGlobalCfgStruct *)(pDataBuf);
PDA *pda =(PDA *)(GetIMMR() & IO_MAP_MASK);
QmcGlobalParamStruct *gmp =(QmcGlobalParamStruct *)((GetIMMR()&IO_MAP_MASK)+0x3C00+0x100*cfg->ch);
memmove(pCfg,cfg,sizeof(*cfg));
memset(gmp,0,sizeof(QmcGlobalParamStruct));
if(pCfg->MaxRecvTSAEntry==0)pCfg->MaxRecvTSAEntry=pCfg->MaxSubChanNum;
if(pCfg->MaxSendTSAEntry==0)pCfg->MaxSendTSAEntry=pCfg->MaxSubChanNum;
/* add switch protocols*/
regs(pCfg->ch).scc_gsmra=0x0;
CPM_CMD((pCfg->ch)<<(2+4)); /* INIT_RX_TX_PARAMS */
SPLX(pda->si_sigmr&=~((0x04)<<(pCfg->UseTDM-1));) /*disable static TDMA */
pCfg->ch=(pCfg->ch&0x3);
SPLX(pda->cpmi_cimr&=(~(EN_SCC1 >> pCfg->ch));)/* disable scc interrutp */
pCfg->IntTablePtr=pCfg->IntTable;
pda->Scc_regs[pCfg->ch].scc_gsmra &= 0xffffffcf; /*disable rx & tx */
/* Step 1: Initialize the SIMODE (serial interface mode) register. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -