最好是先看8019AS的文档,再找个初始化、发送、接收的例程具体分析以下
最好是先看8019AS的文档,再找个初始化、发送、接收的例程具体分析以下。
void init_8019(void)
{
Delay1ms(10);
Rtl8019AS_Reset(); //复位8019
R8019_CHIP_SELECT;
reg00=0x21; //使芯片处于停止模式,这时进行寄存器设置 停止模式下,将不会发送和接收数据包
Delay1ms(10); //延时10毫秒,确保芯片进入停止模式
page(0);
reg0a=0x00; reg0b=0x00;
reg0c= 0xe0; //monitor mode (no packet receive)
reg0d= 0xe2; //loop back mode 使芯片处于mon和loopback模式,跟外部网络断开
reg01=0x4c; reg02=0x80; reg03=0x4c; reg04=0x40;
reg07=0xff; //清除所有中断标志位
reg0f=0x00; //disable all interrupt
reg0e=0xc8; //byte dma 8位dma方式
page(1);
reg07=0x4d; reg08=0x00; reg09=0x00; reg0a=0x00; reg0b=0x00;
reg0c=0x00; reg0d=0x00; reg0e=0x00; reg0f=0x00;
reg00=0x22; //这时让芯片开始工作
ReadRtl8019NodeID(); //读出网卡的物理地址48位
WriteRtl8019NodeID(); //将网卡地址写入到mar寄存器
page(0);
reg0c=0xcc; //将网卡设置成正常的模式,跟外部网络连接
reg0d=0xe0;
reg00=0x22; //这时让芯片开始工作
reg07=0xff; //清除所有中断标志位
}
void send_frame(UCHAR xdata * outbuf, UINT len)/*发送一个数据包的命令,长度最小为60字节,最大1514字节*/
{
UCHAR i;
UINT ii;
page(0);
if(len <60)len=60;
txd_buffer_select=!txd_buffer_select;
if (txd_buffer_select)
reg09=0x40 ; //txdwrite highaddress
else
reg09=0x46 ; //txdwrite highaddress
reg08=0x00; //read page address low
reg0b=len> > 8; //read count high
reg0a=len&0xff; //read count low;
reg00=0x12; //write dma, page0
for (ii=0;ii <len;ii++) //for (ii=4;ii <len+4;ii++) //是否加4有待验证
{
reg10=*(outbuf+ii);
}
/* 以下3句为中止dma的操作,可以不要 */
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
for(i=0;i <16;i++) //最多重发16次
{
for(ii=0;ii <1000;ii++) //检查txp为是否为低
{
if ((reg00&0x04)==0) break;
}
if ((reg04&0x01)!=0) break; //表示发送成功
reg00=0x3e;
}
reg07=0xff;
if(txd_buffer_select)
reg04=0x40; //txd packet start;
else
reg04=0x46; //txd packet start;
reg06=len> > 8; //high byte counter
reg05=len&0xff; //low byte counter
reg07=0xff;
reg00=0x3e; //to sendpacket;
free(outbuf);
}
UCHAR xdata * rcve_frame(void)//如果收到一个有效的数据包,返回收到的数据,否则返回NULL
{
UCHAR bnry,curr,next_page;
UINT len, ii;
UCHAR temp;
UCHAR xdata * buf;
page(0);
bnry=reg03; //bnry page have read 读页指针
page(1);
curr=reg07; //curr writepoint 8019写页指针
page(0);
if ((curr==0)) return NULL; //读的过程出错
next_page=bnry;
bnry=bnry++;
if (bnry> 0x7f) bnry=0x4c;
if (bnry!=curr) //此时表示有新的数据包在缓冲区里
{
//读取一包的前4个字节:4字节的8019头部
page(0);
reg09=bnry; //read page address high
reg08=0x00; //read page address low
reg0b=0x00; //read count high
reg0a=4; //read count low;
reg00=0x0a; //read dma
temp = reg10; temp = reg10;
next_page = temp-1; //next page start-1
len = reg10; temp = reg10;
len += temp < <8;
reg0b=0x00; reg0a=0x00; reg00=0x22;//complete dma page 0
// Allocate enough memory to hold the incoming frame
buf = (UCHAR xdata *)malloc(len);
if (buf == NULL)
{
// out of RAM
// Tell 8019 to skip the frame
page(1);
curr=reg07; //page1
page(0); //切换回page0
bnry = curr -1;
if (bnry < 0x4c) bnry =0x7f;
reg03=bnry; //write to bnry
reg07=0xff; //清除中断状态可以不用
return NULL;
}
// This flag keeps track of allocated rcve memory
rcve_buf_allocated = TRUE;
// Call the assembler function to get the incoming frame
reg09=bnry; //read page address high
reg08=4; //read page address low
reg0b=len> > 8; //read count high
reg0a=len&0xff; //read count low;
reg00=0x0a; //read dma
for(ii=0;ii <len;ii++)
{
buf[ii]=reg10;
}
reg0b=0x00; reg0a=0x00; reg00=0x22; //dma complete page0
// Return pointer to start of buffer
bnry=next_page;
if (bnry <0x4c) bnry=0x7f;
reg03=bnry; //write to bnry
reg07=0xff;
return (buf);
}
return NULL;
}
发表时间:2004年5月2日21:04:23