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 + -
显示快捷键?