mutlihdlc.c
来自「该程序是MPC860的SCC2用作HDLC模式的驱动程序。供大家参考。」· C语言 代码 · 共 1,299 行 · 第 1/3 页
C
1,299 行
// for( j=0; j<BDNUM; j++ )
// {
// temp = bdbase[i].RxBd[j].bd_cstatus ;
// if(( temp & 0x8000 == 0 ) /*|| ( temp & 0x00ff )*/)
// {
////rxChReset[i] = rxChReset[i] + 1 ;
/* enter hunt mode */
// *CPCR(vxImmrGet()) = 0x0341 ;
//chReset[i] = chReset[i] + 1 ;
// while(*CPCR(vxImmrGet())&0x0001) ;
// }
// }
// }
}
/*多通道HDLC设备安装,主要调用iosDrvInstall()完成
参数:无
返回值:无*/
STATUS mutliHdlcDrv ( void )
{
/* check if driver already installed */
if (mutliHdlcDrvNum > 0)
return (OK);
mutliHdlcDrvNum = iosDrvInstall( mutliHdlcOpen, (FUNCPTR)NULL,
mutliHdlcOpen, (FUNCPTR) NULL,
mutliHdlcRead, mutliHdlcWrite,
mutliHdlcIoctl);
return (mutliHdlcDrvNum == ERROR ? ERROR : OK);
}
STATUS mutliHdlcDevCreate
(
PPC860SCCHDLC_CHAN *pChan,
u_char * name, /* name to use for this device */
FAST int channel /* physical channel for this device */
)
{
if (mutliHdlcDrvNum <= 0)
{
return (ERROR);
}
/* if this doesn't represent a valid channel, don't do it */
if(channel < 0)
return (ERROR);
/* if this device already exists, don't create it */
if (pChan->creatFlag)
return (ERROR);
/* mark the device as created, and add the device to the I/O system */
pChan->creatFlag = TRUE;
return(OK);
/*return (iosDevAdd (pChan->devHdr, name, mutliHdlcDrvNum));*/
/*QMC for 32 channels HDLC driver is finished installing*/
/*writen by d.c.peng,4.20,2001*/
}
/******参考860qmc1h.c**************************************************************/
/*初始化结构mutliHdlcChan */
/*参数:无 */
/*返回值:无 */
void mutliChannelHdlcInit ( void )
{
UINT32 regBase,qmcGlobalRegbase,qmcChParaRegbase;
int i;
/* IMMR reg has base adr */
mutliHdlcChan.regBase = vxImmrGet();
regBase=mutliHdlcChan.regBase;
/*设置SI的工作模式,SDMA使用,帧同步时钟和收发时钟分开*/
*MPC860_SDCR(regBase) = 0x00000001;
*MPC860_SIMODE(regBase)|=(SIMODE_SDMA_NORM|SIMODE_RFSDA_NO_DELAY|SIMODE_TFSDA_NO_DELAY|
SIMODE_CRTA|SIMODE_FEA_RISING|
SIMODE_SDMB_NORM|SIMODE_RFSDB_NO_DELAY|SIMODE_TFSDB_NO_DELAY|
SIMODE_CRTB|SIMODE_FEB_RISING);
/*设置SICR*/
*MPC860_SICR(regBase)|=0x00004000; /*scc2 connect STA, sc2=1*/
/*设置I/O口A*/
*MPC860_PAPAR(regBase)|=0x00c0; /*L1RDXA&LITXDA enable */
*MPC860_PADIR(regBase)|=0x00c0; /*L1RXDB&L1TXDB disable*/
*MPC860_PAPAR(regBase)|=0x0500; /*L1RCLKA&L1TCLKA enable,both input pin*/
*MPC860_PADIR(regBase)&=~(0x0500); /*L1RCLKb&L1TCLK disable*/
/*设置I/O口C*/
*MPC860_PCPAR(regBase)|=0x0c00; /*pc4,pc5*/
*MPC860_PCDIR(regBase)&=~(0x0c00);
/*填写SIRAM,参看860手册和QMC手册*/
/*32个时隙,收发*/
for(i=0;i<MAXLOGCHAN;i++)
{
*(UINT32*)MPC860_SIRAM_BASE(regBase+i*4)=0x00820000;
*(UINT32*)MPC860_SIRAM_BASE(regBase+(i+64)*4)=0x00820000;
}
*(UINT32*)MPC860_SIRAM_BASE(regBase+(MAXLOGCHAN-1)*4)=0x00830000;
*(UINT32*)MPC860_SIRAM_BASE(regBase+(MAXLOGCHAN+63)*4)=0x00830000;
*MPC860_SIGMR(regBase)=0x06; /*各32个静态,TDMA enable, TDM B disable*/
*MPC860_SICMR(regBase)=0x00;
/*初始化SCC3全局寄存器*/
sccMutliHdlcInit();
/*初始化QMC*/
QMC_GlobalInit();
/*----------------------------------------*/
/* Initialize Channel Specific parameters */
/*----------------------------------------*/
QMC_ChannelInit();
/*初始化数据结构mutliHdlcChan*/
qmcGlobalRegbase=/*(UINT32)(PPC860_DPR_SCC2(MPC860_DPRAM_BASE(vxImmrGet())));*/0xff003d00;
qmcChParaRegbase=(UINT32)MPC860_DPRAM_BASE(vxImmrGet());
mutliHdlcChan.creatFlag=0;
/*=0,设备未创建*/
mutliHdlcChan.intCounter=0;
/*=0,中断次数计数器*/
mutliHdlcChan.hdlc.sccNum=2;
/*SCC3*/
mutliHdlcChan.hdlc.txBdNum=BDNUM;
/*对于每个通道只使用一个BD*/
mutliHdlcChan.hdlc.rxBdNum=BDNUM;
/*对于每个通道只使用一个BD*/
/*每个通道的收发BD都保存在一块外部存储区内,首地址为0x01fE0000,值保存在MCBASE中*/
/*偏移地址保存在TBASE[channelNum]中,这里只保存通道0的TxBD,其它地址通过计算得到*/
mutliHdlcChan.hdlc.txBufSize=QMC_BUFFER_SIZE;
mutliHdlcChan.hdlc.rxBufSize=QMC_BUFFER_SIZE;
mutliHdlcChan.hdlc.txBufBase=(u_char*)qmcTxBuffer;
mutliHdlcChan.hdlc.rxBufBase=(u_char*)qmcRxBuffer;
for(i=0;i<MAXLOGCHAN;i++)
{
mutliHdlcChan.hdlc.txBdNext[i]=0;
mutliHdlcChan.hdlc.rxBdNext[i]=0;
}
/* DPRAM addr of SCC2 params */
mutliHdlcChan.hdlc.pScc=(SCC*)(qmcGlobalRegbase);
/*初始化TxBD和RxBD表*/
QMC_InitBDs();
/*初始化中断事件表,环行的表*/
for (i=0;i<MAXLOGCHAN; i++)
IntCQ[i] = 0;
IntCQ[MAXLOGCHAN-1] |= 0x4000;
/*w bit =1*/
for (i=0;i<MAXLOGCHAN; i++)
*(UINT16 *)(0xff002000+0x02+i*64)|=0x1000;
for(i=MAXLOGCHAN;i<32;i++)
*(UINT16 *)(0xff002000+0x02+i*64)=0x0000;
/*CHAMR,通道模式寄存器*/
/*MODE=1,HDLC模式*/
/*IDLM=1,空闲字符传输*/
/*ENT=1,传输使能*/
/*POL=1,轮询模式,检查发送BD*/
/*CRC=1,32位CRC*/
*MPC860_SCCE2(vxImmrGet())=0xffff;
/*清除所有中断*/
*MPC860_SCCM2(vxImmrGet())=0x0004;
/*使能GINT*/
/* 收发使能在驱动程序安装后完成*/
/*MPC860_CIPR(vxImmrGet())=0xffff;*/
/*QMC初始化结束*/
/*writen by d.c.peng,4.25,2001*/
}
/*SCC全局变量初始化 */
/*参数:无 */
/*返回值:无 */
void sccMutliHdlcInit ( void )
{
*MPC860_GSMR_H2(vxImmrGet())=0x00000780;
*MPC860_GSMR_L2(vxImmrGet())=0x0000000a; //860环回
}
/*QMC全局变量初始化 */
/*参数:无 */
/*返回值:无 */
void QMC_GlobalInit ( void )
{
UINT32 qmcGlobalRegbase;
UINT8 i;
UINT16 tempHword;
qmcGlobalRegbase=(UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE(vxImmrGet()));
*(UINT32*)(qmcGlobalRegbase+0x00)=(UINT32)bdbase; /*QMC BD table base address*/
/*MCBASE*/
/*中断表指针初始化时指在开始处*/
*(UINT32 *)(qmcGlobalRegbase+0x10)=(UINT32)IntCQ; /*INTBASE*/
*(UINT32 *)(qmcGlobalRegbase+0x14)=(UINT32)IntCQ; /*INTPTR*/
/*最大接收缓冲区长度*/
*(UINT16 *)(qmcGlobalRegbase+0x06)= MAX_HDLC_FRAME; /*MRBLR*/
/*产生中断的帧个数最大值 */
*(UINT16 *)(qmcGlobalRegbase+0x0c)= 1; /*GRFTHR*/
*(UINT16 *)(qmcGlobalRegbase+0x0e)= 1; /*GRFCNT*/
/*CRC校验值*/
*(UINT32*)(qmcGlobalRegbase+0x1c)=0xdebb20e3; /*C_MASK32*/
*(UINT16 *)(qmcGlobalRegbase+0xa0)=0xf0b8; /*C_MASK16*/
/*初始化TSA表*/
/*SCC3.TSATR[x].W = 0; not last time slot */
/*SCC3.TSATR[x].CP = x; mark channel number */
/*SCC3.TSATR[x].mask0_1 = 3; no subchanneling */
/*SCC3.TSATR[x].mask2_7 = 0x3F; no subchanneling */
/*SCC3.TSATR[x].V = 1; mark time slot valid */
/*SCC3.TSATR[31].W = 1; last time slot wrap */
/*SCC3.TSATT[x].W = 0; not last time slot */
/*SCC3.TSATT[x].CP = x; mark channel number */
/*SCC3.TSATT[x].mask0_1 = 3; no subchanneling */
/*SCC3.TSATT[x].mask2_7 = 0x3F; no subchanneling */
/*SCC3.TSATT[x].V = 1; mark time slot valid */
/*SCC3.TSATT[31].W = 1; last time slot wrap */
tempHword=0xb03f;
for(i=0;i<MAXLOGCHAN;i++)
{
*(UINT16 *)(qmcGlobalRegbase+0x20+i*2)=tempHword;
*(UINT16 *)(qmcGlobalRegbase+0x60+i*2)=tempHword;
tempHword+=0x40;
}
*(UINT16 *)(qmcGlobalRegbase+0x20+2*(MAXLOGCHAN-1))|=0x4000;
*(UINT16 *)(qmcGlobalRegbase+0x60+2*(MAXLOGCHAN-1))|=0x4000;
/*初始化TSA表指针*/
/*SCC2=0x3d00*/
*(UINT16 *)(qmcGlobalRegbase+0x18)=0x3d60; /*RX_S_PTR*/
*(UINT16 *)(qmcGlobalRegbase+0x0a)=0x3d60; /*RXPTR*/
*(UINT16 *)(qmcGlobalRegbase+0x08)=0x3d20; /*TX_S_PTR*/
*(UINT16 *)(qmcGlobalRegbase+0x1a)=0x3d20; /*TXPTR*/
/*QMC状态初始化值*/
*(UINT16 *)(qmcGlobalRegbase+0x04)=0x8000; /*QMCSTATE*/
}
/*初始化通道特殊参数,HDLC模式 */
/*参数:无 */
/*返回值:无 */
/*32个通道共占32*64=2K的双口RAM资源,其首地址为双口RAM首地址 */
void QMC_ChannelInit ( void )
{
UINT32 qmcChParaRegbase;
UINT8 channelNum;
qmcChParaRegbase=(UINT32)MPC860_DPRAM_BASE(vxImmrGet());
for(channelNum=0;channelNum<MAXLOGCHAN;channelNum++)
{
*(UINT16 *)(qmcChParaRegbase+0x00+channelNum*64)=16*channelNum*BDNUM;
/*ch[0].tbase=0, address=00 */
/*ch[1].tbase=16,address=64,每个通道参数为64bytes,每个收发BD为8字节,共16个字节*/
/*ch[n].tbase=16*n,address=64*n */
/*TBASE*/
*(UINT16 *)(qmcChParaRegbase+0x20+channelNum*64)=(16*channelNum+8)*BDNUM;
/*接收BD初始化*/
/*RBASE*/
/*每个收发缓冲区有BDNUM个BD*/
*(UINT16 *)(qmcChParaRegbase+0x0c+channelNum*64)=16*channelNum*BDNUM;
/*TBPTR*/
/*指向当前活动的BD*/
*(UINT16 *)(qmcChParaRegbase+0x2c+channelNum*64)=(16*channelNum+8)*BDNUM;
/*RBTPR*/
/*指向当前活动的BD*/
*(UINT32 *)(qmcChParaRegbase+0x04+channelNum*64)=0x30000000;
/*TSTATE*/
*(UINT32 *)(qmcChParaRegbase+0x24+channelNum*64)=0x31000000;
/*RSTATE*/
*(UINT32 *)(qmcChParaRegbase+0x14+channelNum*64)=0x00000100;
/*ZISTATE,插入比特零*/
*(UINT32 *)(qmcChParaRegbase+0x34+channelNum*64)=0x00000080;
/*ZDSTATE,删除比特零*/
*(UINT16 *)(qmcChParaRegbase+0x22+channelNum*64)=MAX_HDLC_FRAME;
/*MFLR,最大帧长度*/
*(UINT16 *)(qmcChParaRegbase+0x1c+channelNum*64)=0x0008;
/*INTMSK,中断掩码,只RXF有中断*/
*(UINT16 *)(qmcChParaRegbase+0x02+channelNum*64)=0x8000;
}
}
/*收发BD表的初始化 */
/*参数:无 */
/*返回值:无 */
void QMC_InitBDs ( void )
{
UINT8 channelNum,bdNo;
for(channelNum=0;channelNum<MAXLOGCHAN;channelNum++)
{
for(bdNo=0;bdNo<BDNUM;bdNo++)
{
bdbase[channelNum].TxBd[bdNo].bd_addr =
(u_char*)&qmcTxBuffer[(channelNum*BDNUM+bdNo)*QMC_BUFFER_SIZE];
/*指向数组的地址*/
bdbase[channelNum].TxBd[bdNo].bd_length =0;
/*初始长度为0*/
bdbase[channelNum].RxBd[bdNo].bd_addr =
(u_char*)&qmcRxBuffer[(channelNum*BDNUM+bdNo)*QMC_BUFFER_SIZE];
/*指向数组的地址*/
bdbase[channelNum].RxBd[bdNo].bd_length = 0;
/*初始长度为0*/
bdbase[channelNum].TxBd[bdNo].bd_cstatus = 0x0c00;
/* NOT Ready,last buffer in a frame,crc*/
bdbase[channelNum].RxBd[bdNo].bd_cstatus = 0x8000;
/* Empty,最后一个 */
}
bdbase[channelNum].TxBd[BDNUM-1].bd_cstatus = 0x2c00;
/* NOT Ready,w*/
bdbase[channelNum].RxBd[BDNUM-1].bd_cstatus = 0xb000;
/* Empty ,w*/
}
}
void oneHdlcChannelInit( int hdlcChNo )
{
UINT32 regBase, qmcGlobalRegbase, qmcChParaRegbase ;
UINT16 tempHword;
UINT8 bdNo ;
if( hdlcChNo > 31 )
{
printf( "\nERROR hdlc channel No!!\n" ) ;
return ;
}
regBase=mutliHdlcChan.regBase;
qmcGlobalRegbase=(UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE(vxImmrGet()));
tempHword = 0xb03f + hdlcChNo * 0x40 ;
qmcChParaRegbase=(UINT32)MPC860_DPRAM_BASE(vxImmrGet());
if( hdlcChNo == 31 )
{
*(UINT32*)MPC860_SIRAM_BASE(regBase+31*4)=0x00830000;
*(UINT32*)MPC860_SIRAM_BASE(regBase+95*4)=0x00830000;
tempHword = tempHword | 0x4000 ;
}
else
{
*(UINT32*)MPC860_SIRAM_BASE(regBase+hdlcChNo*4)=0x00820000;
*(UINT32*)MPC860_SIRAM_BASE(regBase+(hdlcChNo+64)*4)=0x00820000;
}
*(UINT16 *)(qmcGlobalRegbase+0x20+hdlcChNo*2)=tempHword;
*(UINT16 *)(qmcGlobalRegbase+0x60+hdlcChNo*2)=tempHword;
*(UINT16 *)(qmcChParaRegbase+0x00+hdlcChNo*64)=16*hdlcChNo*BDNUM;
*(UINT16 *)(qmcChParaRegbase+0x20+hdlcChNo*64)=(16*hdlcChNo+8)*BDNUM;
*(UINT16 *)(qmcChParaRegbase+0x0c+hdlcChNo*64)=16*hdlcChNo*BDNUM;
*(UINT16 *)(qmcChParaRegbase+0x2c+hdlcChNo*64)=(16*hdlcChNo+8)*BDNUM;
*(UINT32 *)(qmcChParaRegbase+0x04+hdlcChNo*64)=0x30000000;
*(UINT32 *)(qmcChParaRegbase+0x24+hdlcChNo*64)=0x31000000;
*(UINT32 *)(qmcChParaRegbase+0x14+hdlcChNo*64)=0x00000100;
*(UINT32 *)(qmcChParaRegbase+0x34+hdlcChNo*64)=0x00000080;
*(UINT16 *)(qmcChParaRegbase+0x22+hdlcChNo*64)=MAX_HDLC_FRAME;
*(UINT16 *)(qmcChParaRegbase+0x1c+hdlcChNo*64)=0x0008;
*(UINT16 *)(qmcChParaRegbase+0x02+hdlcChNo*64)=0x8000;
mutliHdlcChan.hdlc.txBdNext[hdlcChNo]=0;
mutliHdlcChan.hdlc.rxBdNext[hdlcChNo]=0;
for(bdNo=0;bdNo<BDNUM;bdNo++)
{
bdbase[hdlcChNo].TxBd[bdNo].bd_addr =
(u_char*)&qmcTxBuffer[(hdlcChNo*BDNUM+bdNo)*QMC_BUFFER_SIZE];
//指向数组的地址
bdbase[hdlcChNo].TxBd[bdNo].bd_length =0;
//初始长度为0
bdbase[hdlcChNo].RxBd[bdNo].bd_addr =
(u_char*)&qmcRxBuffer[(hdlcChNo*BDNUM+bdNo)*QMC_BUFFER_SIZE];
//指向数组的地址
bdbase[hdlcChNo].RxBd[bdNo].bd_length = 0;
//初始长度为0
bdbase[hdlcChNo].TxBd[bdNo].bd_cstatus = 0x0c00;
//NOT Ready,last buffer in a frame,crc
bdbase[hdlcChNo].RxBd[bdNo].bd_cstatus = 0x8000;
//Empty,最后一个
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?