⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ax88796.c

📁 88796驱动
💻 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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -