www.pudn.com > ax88796.rar > ax88796.c


//*---------------------------------------------------------------------------- 
//* File Name           : ax88796.c 
//* Object              : 10/100M网卡芯片ax88796的程序 
//* 
//* 1.0 24/06/02 	    : hql 
//*---------------------------------------------------------------------------- 
#define AX88796_GLOBALS 
#include "ax88796.h" 
//================================================================================= 
//const u_char cMAR[8] = {0x00,0x41,0x00,0x80,0x00,0x00,0x00,0x00}; 
 
//================================================================================== 
//功能:访问网卡芯片管脚模式的函数 
//入口参数:片子选择 
//出口参数:无 
//=================================================================================== 
void Network_PinMode(void) 
{ 
   NETWORK_RSTA_CLR_OUT(); 
   NETWORK_RSTB_CLR_OUT(); 
   NETWORK_IOCS16_SET_OUT(); 
   NETWORK_BHE_SET_OUT(); 
      
   //管脚属性定义 
   NETWORK_RSTA_MODE(); 
   NETWORK_RSTB_MODE(); 
   NETWORK_IOCS16_MODE(); 
   NETWORK_BHE_MODE(); 
} 
 
//================================================================================== 
//功能:网卡芯片复位的函数 
//入口参数:片子选择 
//出口参数:无 
//=================================================================================== 
void Network_Reset(void) 
{ 
   //复位 
   NETWORK_RSTA_SET_OUT(); 
   NETWORK_RSTB_SET_OUT(); 
   delay_ms(10); 
   NETWORK_RSTA_CLR_OUT(); 
   NETWORK_RSTB_CLR_OUT(); 
} 
 
//========================================================================== 
//功能:网卡芯片初始化的函数 
//入口参数: 网卡芯片的基地址,物理地址的首指针 
//出口参数:无 
//========================================================================== 
void Network_Init(volatile unsigned char * BaseAddr,u_char *cPar) 
{ 
   u_char cTempData; 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE0;       //选择0页 
   BaseAddr[NE2000_REG0] = DMAWRITE | NETSTOPWORK;  //网卡停止运行,远程DMA写  
   BaseAddr[NE2000_REG1] = 0x4c;                    //开始页寄存器        PSTART 
   BaseAddr[NE2000_REG2] = 0x80;                    //结束页寄存器        PSTOP 0x80 
   BaseAddr[NE2000_REG3] = 0x4c;                    //边界寄存器          BNRY 
   BaseAddr[NE2000_REG4] = 0x40;                    //发送起始页面寄存器  TPSR 
   BaseAddr[NE2000_REG7] = 0xff;                    //ISR	 
   BaseAddr[NE2000_REGC] = NETWORK_RCR;             //接收配置寄存器      RCR  
   BaseAddr[NE2000_REGD] = 0xe0;                    //发送配置寄存器	    TCR  
   BaseAddr[NE2000_REGE] = 0xc8;                    //数据配置寄存器      DCR 
   BaseAddr[NE2000_REGF] = 0x00;                    //中断屏蔽寄存器      IMR 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE1;       //选择1页 
   BaseAddr[NE2000_REG1] = cPar[0];                 //物理地址寄存器0     PAR0 
   BaseAddr[NE2000_REG2] = cPar[1];                 //物理地址寄存器1     PAR1 
   BaseAddr[NE2000_REG3] = cPar[2];                 //物理地址寄存器2     PAR2 
   BaseAddr[NE2000_REG4] = cPar[3];                 //物理地址寄存器3     PAR3 
   BaseAddr[NE2000_REG5] = cPar[4];                 //物理地址寄存器4     PAR4 
   BaseAddr[NE2000_REG6] = cPar[5];                 //物理地址寄存器5     PAR5 
   BaseAddr[NE2000_REG7] = 0x4d;                    //当前页寄存器        CURR	 
   BaseAddr[NE2000_REG8] = 0x00;                    //多址地址寄存器0     MAR0 
   BaseAddr[NE2000_REG9] = 0x41;                    //多址地址寄存器1     MAR1	 
   BaseAddr[NE2000_REGA] = 0x00;                    //多址地址寄存器2     MAR2 
   BaseAddr[NE2000_REGB] = 0x80;                    //多址地址寄存器3     MAR3 
   BaseAddr[NE2000_REGC] = 0x00;                    //多址地址寄存器4     MAR4 
   BaseAddr[NE2000_REGD] = 0x00;                    //多址地址寄存器5     MAR5 
   BaseAddr[NE2000_REGE] = 0x00;                    //多址地址寄存器6     MAR6 
   BaseAddr[NE2000_REGF] = 0x00;                    //多址地址寄存器7     MAR7 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE0;           //选择0页 
   BaseAddr[NE2000_REG0] = ABORT_C_DMA | NETSTARTWORK;  //网卡执行,完成远程DMA 
    
} 
 
//================================================================================== 
//功能:网卡发送报文函数 
//入口参数:网卡芯片的基地址,写入网卡哪个缓冲区的标志,,待发送数据的缓冲区指针,发送的字节数 
//出口参数:无 
//================================================================================== 
void Network_Send (volatile unsigned char * BaseAddr,u_char cSetBuff,u_char * cSendBuff,u_short sCount) 
{ 
   
   u_short sNum; 
   u_char cTemprtl,cTempData,cNum; 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE0;         //选择0页 
    
   if (cSetBuff == 0x00) 
   { 
      BaseAddr[NE2000_REG9] = 0x40;                   //远程开始地址寄存器1  RSAR1 
   } 
   else if (cSetBuff == 0xff) 
   { 
      BaseAddr[NE2000_REG9] = 0x46;                   //远程开始地址寄存器1  RSAR1 
   } 
   BaseAddr[NE2000_REG8] = 0x00;                      //远程开始地址寄存器0  RSAR0         
   BaseAddr[NE2000_REGB] = (sCount >> 8) & 0x00ff;    //远程字节计数器1      RBCR1 
   BaseAddr[NE2000_REGA] = sCount & 0x00ff;           //远程字节计数器0      RBCR0 
    
   cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
   BaseAddr[NE2000_REG0] = cTempData | DMAWRITE;      //DMA写 0xc3 
    
   for (sNum = 0; sNum < sCount ; sNum++) 
   { 
      BaseAddr[NE2000_REG10] = cSendBuff[sNum];       //写数据 
   } 
   BaseAddr[NE2000_REGB] = 0x00;                      //远程字节计数器1      RBCR1 
   BaseAddr[NE2000_REGA] = 0x00;                      //远程字节计数器0      RBCR0 
    
   cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
   BaseAddr[NE2000_REG0] = cTempData | ABORT_C_DMA;   //完成DMA  
  
   for(cTempData = 0; cTempData < 3; cTempData++)     //最多重发3次 
   {		  
      cNum = 0; 
      while (cNum < 120)                               //延时1。2MS 
      { 
         cTemprtl = BaseAddr[NE2000_REG0];       
         if((cTemprtl & 0x04)==0) break; 
         cTemprtl = BaseAddr[NE2000_REG4]; 
         if((cTemprtl & 0x01)!=0) break;               //表示发送成功 
         delay_us(10);                                 //延时10us 
         cNum++;       
      } 
      if (cNum > 119 )                                 //超时没有发送完成 
      { 
         BaseAddr[NE2000_REG0] = 0x3e;                 //发送包                
      } 
      else 
      { 
         break; 
      } 
   } 
    
   cNum = 0; 
   while (cNum < 120)                                   //延时1。2MS 
   { 
      cTemprtl = BaseAddr[NE2000_REG0];       
      if((cTemprtl & 0x04)==0) break; 
      cTemprtl = BaseAddr[NE2000_REG4]; 
      if((cTemprtl & 0x01)!=0) break;                   //表示发送成功 
      delay_us(10);                                     //延时10us 
      cNum++;       
   } 
     
   if (cSetBuff == 0x00) 
   { 
      BaseAddr[NE2000_REG4] = 0x40;                 //发送起始页面寄存器  TPSR 
   } 
   else if (cSetBuff == 0xff) 
   { 
      BaseAddr[NE2000_REG4] = 0x46;                 //远程开始地址寄存器1  RSAR1 
   }    
   BaseAddr[NE2000_REG6] = (sCount >> 8) & 0x00ff;  //发送字节计数器1      TBCR1 
   BaseAddr[NE2000_REG5] = sCount & 0x00ff;         //发送字节计数器0      TBCR0 
   BaseAddr[NE2000_REG0] = 0x3e;                    //发送包                
    
} 
 
 
//====================================================================================== 
//功能:网卡接收报文函数 
//入口参数:网卡芯片的基地址,接收缓冲区首指针(注意前4个字节是网卡自已加的控制字节) 
//出口参数:无数据返回FALSE,有数据返回TRUE 
//====================================================================================== 
u_char Network_RecievePacket(volatile unsigned char * BaseAddr,u_char * cRecieveBuff) 
{ 
    
   u_short sNum,sCount; 
   u_char cBNRY,cCURR,cTempData; 
    
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE0;     //选择0页 
   cBNRY = BaseAddr[NE2000_REG3];                 //读边界寄存器BNRY 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE1;     //选择1页 
   cCURR = BaseAddr[NE2000_REG7];                 //读当前页寄存器CURR 
    
   cBNRY++; 
   if(cBNRY > 0x7f)    
   { 
      cBNRY = 0x4c; 
   } 
    
   if(cCURR == cBNRY) 
   { 
      return (FALSE);                             //缓冲池没数据,退出 
   } 
    
   cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
   BaseAddr[NE2000_REG0] = cTempData | PAGE0;     //选择0页 
   cTempData = BaseAddr[NE2000_REG7];             //读中断状态寄存器 
   cTempData = cTempData & 0xff; 
   BaseAddr[NE2000_REG7] = cTempData;             //清中断状态寄存器   
   BaseAddr[NE2000_REG9] = cBNRY;                 //远程开始地址寄存器1  RSAR1    
   BaseAddr[NE2000_REG8] = 0x00;                  //远程开始地址寄存器0  RSAR0   
   BaseAddr[NE2000_REGB] = 0x00;                  //远程字节计数器1      RBCR1 
   BaseAddr[NE2000_REGA] = 0x04;                  //远程字节计数器0      RBCR0 
    
   cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
   BaseAddr[NE2000_REG0] = cTempData | DMAREAD;   //DMA读  
    
   for (sNum = 0; sNum < 4; sNum++) 
   { 
      cRecieveBuff[sNum] = BaseAddr[NE2000_REG10]; 
   } 
    
   if (((cRecieveBuff[0] & 0x01) == 0) || (cRecieveBuff[1] > 0x7f) || (cRecieveBuff[1] < 0x4c) || (cRecieveBuff[3] > 0x06))     //包不正确接收 
   { 
      cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
      BaseAddr[NE2000_REG0] = cTempData | PAGE1;     //选择1页 
       
      cCURR = BaseAddr[NE2000_REG7];                 //读当前页寄存器CURR 
      cBNRY = cCURR - 1; 
      if(cBNRY < 0x4c) 
         cBNRY = 0x7f;                                       
       
      cTempData = BaseAddr[NE2000_REG0] & 0x3b; 
      BaseAddr[NE2000_REG0] = cTempData | PAGE0;     //选择0页 
      BaseAddr[NE2000_REG3] = cBNRY;                 //写边界指针 
      
      cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
      BaseAddr[NE2000_REG0] = cTempData | ABORT_C_DMA;  //完成DMA //0xc3 
      return (FALSE); 
   }     
   else 
   {  
      sCount = cRecieveBuff[3];                        //读包长度的高字节  
      sCount = (sCount << 8) + cRecieveBuff[2];        //读包长度的低字节  
      BaseAddr[NE2000_REG9] = cBNRY;                   //远程开始地址寄存器1  RSAR1    
      BaseAddr[NE2000_REG8] = 0x04;                    //远程开始地址寄存器0  RSAR0    
      BaseAddr[NE2000_REGB] = (sCount >> 8) & 0x00ff;  //远程字节计数器1      RBCR1 
      BaseAddr[NE2000_REGA] = sCount & 0x00ff;         //远程字节计数器0      RBCR0     
       
      cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
      BaseAddr[NE2000_REG0] = cTempData | DMAREAD;   //DMA读  
    
      for(sNum = 0; sNum < sCount; sNum++)               //读包数据 
      { 
         cRecieveBuff[sNum + 4] = BaseAddr[NE2000_REG10]; 
      } 
    
      cBNRY = cRecieveBuff[1] - 1;                       //读下一包指针-1 
      if(cBNRY < 0x4c) 
         cBNRY = 0x7f;      
       
      BaseAddr[NE2000_REG3] = cBNRY;                     //写边界指针 
       
      cTempData = BaseAddr[NE2000_REG0] & 0xc3; 
      BaseAddr[NE2000_REG0] = cTempData | ABORT_C_DMA;  //完成DMA //0xc3 
      return (TRUE); 
   }    
   return (FALSE); 
}