📄 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -