📄 rtl8019.c
字号:
#include "net.h"
#include "Rtl8019.h"
#include "..\inc\44b.h"
#include "..\44blibs\int_onoff.h"
#include "..\44blibs\lcd.h"
#define SHIFT(x) (x<<1)
#define BaseAddr 0x06000000
#define RWPORT (BaseAddr+SHIFT(0x10)) /* dma read write address, form 0x10 - 0x17 */
#define RstAddr (BaseAddr+SHIFT(0x18)) /* reset register, 0x18, 0x1a, 0x1c, 0x1e even address is recommanded */
#define CR (BaseAddr+SHIFT(0))
/* page 0 */
#define Pstart (BaseAddr+SHIFT(0x01)) /* page start */
#define Pstop (BaseAddr+SHIFT(0x02)) /* page stop */
#define BNRY (BaseAddr+SHIFT(0x03))
#define TPSR (BaseAddr+SHIFT(0x04)) /* transmit page start */
#define TBCR0 (BaseAddr+SHIFT(0x05))
#define TBCR1 (BaseAddr+SHIFT(0x06))
#define ISR (BaseAddr+SHIFT(0x07)) /* interrupt status register */
#define RSAR0 (BaseAddr+SHIFT(0x08)) /* dma read address */
#define RSAR1 (BaseAddr+SHIFT(0x09))
#define RBCR0 (BaseAddr+SHIFT(0x0A)) /* dma read byte count */
#define RBCR1 (BaseAddr+SHIFT(0x0B))
#define RCR (BaseAddr+SHIFT(0x0C)) /* receive config */
#define TCR (BaseAddr+SHIFT(0x0D)) /* transmit config */
#define DCR (BaseAddr+SHIFT(0x0E)) /* data config */
#define IMR (BaseAddr+SHIFT(0x0F)) /* interrupt mask */
#define ID8019L (BaseAddr+SHIFT(0x0A))
#define ID8019H (BaseAddr+SHIFT(0x0B))
/* page 1 */
#define PAR0 (BaseAddr+SHIFT(0x01))
#define PAR1 (BaseAddr+SHIFT(0x02))
#define PAR2 (BaseAddr+SHIFT(0x03))
#define PAR3 (BaseAddr+SHIFT(0x04))
#define PAR4 (BaseAddr+SHIFT(0x05))
#define PAR6 (BaseAddr+SHIFT(0x06))
#define CURR (BaseAddr+SHIFT(0x07))
#define MAR0 (BaseAddr+SHIFT(0x08))
#define MAR1 (BaseAddr+SHIFT(0x09))
#define MAR2 (BaseAddr+SHIFT(0x0A))
#define MAR3 (BaseAddr+SHIFT(0x0B))
#define MAR4 (BaseAddr+SHIFT(0x0C))
#define MAR5 (BaseAddr+SHIFT(0x0D))
#define MAR6 (BaseAddr+SHIFT(0x0E))
#define MAR7 (BaseAddr+SHIFT(0x0F))
/* page 2 */
/* page 3 */
#define CR9346 (BaseAddr+SHIFT(0x01))
#define CONFIG0 (BaseAddr+SHIFT(0x03))
#define CONFIG1 (BaseAddr+SHIFT(0x04))
#define CONFIG2 (BaseAddr+SHIFT(0x05))
#define CONFIG3 (BaseAddr+SHIFT(0x06))
/* 端口操作 */
#define outportb(port, data) *((volatile unsigned char *)(port)) = (unsigned char)(data)
#define inportb(port) *((volatile unsigned char *)(port))
#define outportw(port, data) *((volatile unsigned short *)(port)) = (unsigned short)(data)
#define inportw(port) *((volatile unsigned short *)(port))
#define ETH_FRAME_LEN 1514
#define ETH_ZLEN 60
#define ETH_ALEN 6
#define RPSTART 0x4c
#define RPSTOP 0x80
#define SPSTART 0x40
unsigned int ETH_SendPackets;
unsigned int ETH_ReceivePackets;
unsigned int ETH_EVENT = 0;
static Ethernet RXBuf[ETH_BUFRX]; //ETH_BUFRX 是常数量32
static short int ETH_Rx_Readx;
static short int ETH_Rx_Receivex;
static Ethernet TXBuf[ETH_BUFTX]; //ETH_BUFTX 是常数量16
static short int ETH_Tx_Sendx;
static short int ETH_Tx_Addx;
unsigned char ETH_isTXing = 0;
unsigned char ETH_TX_TimeOut = 0;
/*
void ETH_Init();
void ETH_Receive();
void ETH_StartSend();
void ETH_AddSend(Ethernet SData);
*/
/** 8019数据定义 **/
static unsigned char net_start;
extern unsigned char my_hwaddr[];
void Rlt8019_Init();
void Rlt8019_Tx(Ethernet *pTx);
/*设置寄存器页面*/
void Rlt8019_Page( unsigned char PageIdx)
{
unsigned char temp;
temp = inportb(CR);
temp = (temp&(0x3a|net_start))|(PageIdx<<6);
outportb(CR, temp);
}
/*设置网卡地址*/
void Rlt8019_SetMacID()
{
int i;
Rlt8019_Page(1);
for(i=0; i<6; i++)
outportb(PAR0+i*2, my_hwaddr[i]);
Rlt8019_Page(0);
}
/*软件复位网卡*/
void Rlt8019_Rst()
{
int i;
Rlt8019_Page(3);
//outportb(CR9346, 0xcf); //set eem1-0, 11 ,enable write config register
outportb(CONFIG3, 0x70); //clear pwrdn, sleep mode, set led0 as led_col, led1 as led_crs
outportb(CONFIG1, 0x80); //0x0300,int0
//outportb(CR9346, 0x3f); //disable write config register
outportb(RstAddr, 0x5a);
i = 400000;
while(i--);
Rlt8019_Page(0);
//return ( inportb(ISR)&0x80 );
}
/*初始化网卡*/
void Rlt8019_Init()
{
int i;
Rlt8019_Rst();
net_start = 1;
outportb(CR, 0x21); /* set page 0 and stop */
outportb(RBCR0, 0x00); /* dma read byte count */
outportb(RBCR1, 0x00);
outportb(RCR, 0xe0); // 接收设置
outportb(TCR, 0xe2); // 发送设置
outportb(Pstart, RPSTART); //接收缓冲页起始地址 0x04c
outportb(Pstop, RPSTOP); //接收缓冲页终止地址 0x080
outportb(BNRY, RPSTART); /* BNRY-> the last page has been read */
outportb(TPSR, SPSTART); /* transmit page start register, 0x40 */
outportb(DCR, 0xc9); /* set DCR 0xc9, 16bit DMA */
outportb(IMR, 0x03); //中断开关
outportb(ISR, 0xff); //中断标志
Rlt8019_Page(1);
outportb(CURR, RPSTART+1);
outportb(MAR0, 0x00);
outportb(MAR1, 0x41);
outportb(MAR2, 0x00);
outportb(MAR3, 0x80);
outportb(MAR4, 0x00);
outportb(MAR5, 0x00);
outportb(MAR6, 0x00);
outportb(MAR7, 0x00);
Rlt8019_Page(0);
outportb(CR, 0x22); /* set page 0 and start */
//outportb(RCR, 0xcc); // 接收设置
outportb(RCR, 0xcc); // 接收设置
outportb(TCR, 0xe0); // 发送设置
outportb(ISR, 0xff);
net_start = 0;
//============================
i = inportb(ID8019L);
i |= inportb(ID8019H) << 8;
Rlt8019_SetMacID();
Rlt8019_Page(0);
}
/*发送数据*/
void Rlt8019_Tx( Ethernet *pTx )
{
int i;
unsigned short len,TxLen;
len = pTx->Length < ETH_ZLEN ? ETH_ZLEN : pTx->Length;
outportb(CR,0x22); //switch to page 0 and stop remote dma
outportb(RSAR0, 0);
outportb(RSAR1, SPSTART);
outportb(RBCR0, len&0xff);
outportb(RBCR1, len>>8);
outportb(CR, 0x12); //begin remote write
TxLen=(len+1)/2;
for(i=0; i<TxLen; i++)
{
outportw(RWPORT, pTx->Packet[i]); // copy data to nic ram
}
while(inportb(CR)&4);
outportb(TPSR, SPSTART); // transmit begin page 0x40
outportb(TBCR0, len&0xff);
outportb(TBCR1, len>>8);
outportb(CR, 0x1e); // begin to send packet
}
/* 接收数据 */
void Rlt8019_Rx()
{
unsigned char RxPageBeg, RxPageEnd;
unsigned char RxNextPage;
unsigned char RxStatus;
unsigned short temp,*data;
unsigned short i, RxLength,RxLen,txp;
unsigned char rBNRY,irqs;
Rlt8019_Page(0);
irqs = inportb(ISR); //读入8019的ISR寄存器
if( irqs & 0x01 ) //接收成功
{
outportb(ISR, 0x01); //清除中断标志
/* 接受数据 */
Rlt8019_Page(1);
RxPageEnd = inportb(CURR); //读入8019的CURR CURR指向要写入的下一页。写数据时网卡自动加一
Rlt8019_Page(0);
rBNRY = inportb(BNRY); //读入8019的BNRY寄存器 BNRY指向要读当前要读的页。用户操作。读数据时加一。
RxPageBeg = rBNRY+1;
if(RxPageBeg >= RPSTOP) RxPageBeg = RPSTART;
while( RxPageBeg != RxPageEnd ) //是否还有数据包
{
//接收1个数据包
Rlt8019_Page(1);
RxPageEnd = inportb(CURR);
Rlt8019_Page(0);
rBNRY = inportb(BNRY);
RxPageBeg = rBNRY+1;
if(RxPageBeg >= RPSTOP) RxPageBeg = RPSTART;
if( RxPageBeg == RxPageEnd ) break;
outportb(CR, 0x22);
outportb(RSAR0, 0);
outportb(RSAR1, RxPageBeg);
outportb(RBCR0, 4);
outportb(RBCR1, 0);
outportb(CR, 0xa);
temp = inportw(RWPORT); //
RxStatus = temp&0xff; //这四个字节应该是网卡加上的,
RxNextPage = temp>>8; //并不是以太网的物理帧的数据。
RxLength = inportw(RWPORT); //这四个字节后面跟着的是以太网的物理帧的DA,SA,TYPE,DATA
if( (RxLength > ETH_FRAME_LEN ) || !(RxStatus & 0x01) ) //if RxLength > 1514 或 RxStatus的D0=0
{
if(RxPageEnd == RPSTART)
{
rBNRY = RPSTOP-1;
}else
{
rBNRY = RxPageEnd-1;
}
outportb(BNRY, rBNRY);
return ;
}
//=======
RXBuf[ETH_Rx_Receivex].Status = RxStatus;
RXBuf[ETH_Rx_Receivex].Nextpage = RxNextPage;
RXBuf[ETH_Rx_Receivex].Length = RxLength -4; //前面-4,是去掉已经读出的数据,与后面将要读出而要去掉的CRC长度一样,所以....
//======
RxLength -= 4;
outportb(RSAR0, 4);
outportb(RSAR1, RxPageBeg);
outportb(RBCR0, RxLength);
outportb(RBCR1, RxLength>>8);
outportb(CR, 0xa);
data = RXBuf[ETH_Rx_Receivex].Packet; //RXBuf[ETH_Rx_Receivex].Packet的地址送data (shar)指针变量
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -