www.pudn.com > TcpIpOn8051.rar > 8019DRV.C


/*------------------------------------------------------------------------------ 
8019drv.C 
 
Copyright 1995-1999 Keil Software, Inc. 
------------------------------------------------------------------------------*/ 
 
#include                 /* special function register declarations   */ 
#include "public.h"               /* for the intended 8051 derivative         */ 
#include "8019drv.h" 
#include "ether.h" 
 
void page(BYTE pagenumber); 
void readmynodeid(void); 
void writemynodeid(void); 
void initNIC(void); 
void rtl8019as_rst(void); 
void ne2000init(void); 
void send_packet(netcard *txdnet,WORD length); 
bit recv_packet(netcard *rxdnet); 
 
extern void delay_ms(BYTE sec); 
/*------------------------------------------------ 
The main C function.  Program execution starts 
here after stack initialization. 
------------------------------------------------*/ 
void page(BYTE pagenumber) 
{ 
        BYTE data temp; 
	temp=reg00;				//command register 
	temp=temp&0x3b; 
	pagenumber=pagenumber <<6; 
	temp=temp | pagenumber; 
	reg00=temp; 
} 
 
void readmynodeid(void) 
{ 
	BYTE data i,temp; 
	u protocal;				//ÁÙʱ±äÁ¿ 
	page(0); 
	reg09=0;				//¼Ä´æÆ÷RSAR1 dma read highaddress=0 
	reg08=0;				//RSAR0 dma read lowaddress=0; 
	reg0b=0;				//RBCR1 read count high 
	reg0a=12;				//RBCR0 count low 
	reg00=0x0a;				//dma read and start 
	for (i=0;i<6;i++) 
	{ 
		temp=reg10;			//¶Áȡһ¸ö×Ö½Ú 
		if (i % 2==0) 
		{ 
			protocal.bytes.high=temp; 
		} 
		else {protocal.bytes.low=temp;mypara.mynodeid[i/2].word=protocal.word;} 
 
		temp=reg10;			//¶Áȡһ¸öÖØ¸´µÄ×Ö½Ú£¬Õâ¸ö×Ö½Ú±»¶ªÆú 
	} 
} 
 
void writemynodeid(void) 
{ 
	page(1); 
	reg01=mypara.mynodeid[0].bytes.high; 
	reg02=mypara.mynodeid[0].bytes.low; 
	reg03=mypara.mynodeid[1].bytes.high; 
	reg04=mypara.mynodeid[1].bytes.low; 
	reg05=mypara.mynodeid[2].bytes.high; 
	reg06=mypara.mynodeid[2].bytes.low; 
 
} 
 
void initNIC(void) 
{ 
	readmynodeid(); 
	writemynodeid(); 
	txd_buffer_select=0; 
} 
 
void rtl8019as_rst(void) 
{ 
	BYTE a; 
	a=P1; 
	P1=a&0xfb; 
	//P1^2=0; 
} 
/*------------------------ 
ne2000Íø¿¨³õʼ»¯ 
------------------------*/ 
void ne2000init(void) 
{ 
    //rtl8019as_rst();		//Íø¿¨¸´Î» 
 
    reg00=0x21;				//Ñ¡ÔñÒ³0µÄ¼Ä´æÆ÷£¬Íø¿¨Í£Ö¹ÔËÐУ¬ÒòΪ»¹Ã»Óгõʼ»¯¡£ 
    delay_ms(10);			//ÑÓʱ10ºÁÃë,È·±£Ð¾Æ¬½øÈëֹͣģʽ 
							//ʹоƬ´¦ÓÚmonºÍloopbackģʽ,¸úÍâ²¿ÍøÂç¶Ï¿ª 
    page(0); 
    reg01=0x4c;				//PSTART ½ÓÊÕ»º³åÇøµÄÆðʼҳµÄµØÖ· 
    reg02=0x80;				//PSTOP ½ÓÊÕ»º³åÇøµÄ½áÊøÒ³µØÖ·¡££¨¸ÃÒ³²»ÓÃÓÚ½ÓÊ 
							//ʹÓÃ0x40-0x4BÎªÍø¿¨µÄ·¢ËÍ»º³åÇø£¬¹²12Ò³£¬¸ÕºÃ¿ÉÒÔ´æ´¢2¸ö×î´óµÄÒÔÌ«Íø°ü¡£ 
							//ʹÓÃ0x4c£­0x7fÎªÍø¿¨µÄ½ÓÊÕ»º³åÇø£¬¹²52Ò³¡£ 
    reg03=0x4c;				//BNRY Ö¸Ïò×îºóÒ»¸öÒѾ­¶ÁÈ¡µÄÒ³£¨¶ÁÖ¸Õ룩 
    reg04=0x40;				//TPSR Ϊ·¢ËÍÒ³µÄÆðʼҳµØÖ·¡£³õʼ»¯ÎªÖ¸ÏòµÚÒ»¸ö·¢ËÍ»º³åÇøµÄÒ³£¬0x40 
    reg0c=0xcc;				//RCR ½ÓÊÕÅäÖüĴæÆ÷£¬ÉèÖÃΪʹÓýÓÊÕ»º³åÇø£¬½ö½ÓÊÕ×Ô¼ºµÄµØÖ·µÄÊý¾Ý°ü 
							//£¨ÒÔ¼°¹ã²¥µØÖ·Êý¾Ý°ü£©ºÍ¶àµã²¥Ë͵ØÖ·°ü£¬Ð¡ÓÚ64×ֽڵİü¶ªÆú 
    //reg0c=0x1f; 
    reg0d=0xe0;				//TCR ·¢ËÍÅäÖüĴæÆ÷£¬ÆôÓÃcrc×Ô¶¯Éú³ÉºÍ×Ô¶¯Ð£Ñ飬¹¤×÷ÔÚÕý³£Ä£Ê½¡£ 
    reg0e=0xc8;				//DCR Êý¾ÝÅäÖüĴæÆ÷£¬ÉèÖÃΪʹÓÃFIFO»º´æ£¬ÆÕͨģʽ£¬8λÊý¾Ý´«Êäģʽ 
							//×Ö½Ú˳ÐòΪ¸ßλ×Ö½ÚÔÚǰ£¬µÍλ×Ö½ÚÔÚºó 
    reg0a=0x00;				//RBCR0,Remote Byte Count Register 
    reg0b=0x00;				//RBCR1,Remote Byte Count Register 
 
    reg07=0xFF;				//Çå³ýËùÓÐÖжϱê־λ 
    reg0f=0x00;				//IMR disable all interrupt 
 
    page(1);				//Ñ¡ÔñÒ³1µÄ¼Ä´æÆ÷ 
    reg07=0x4D;				//CURRÊÇÍø¿¨Ð´ÄÚ´æµÄÖ¸Õë¡£ËüÖ¸Ïòµ±Ç°ÕýÔÚдµÄÒ³µÄÏÂÒ»Ò³ 
    reg08=0xff;				//MAR0 
    reg09=0xff;				//MAR1 
    reg0a=0xff;				//MAR2 
    reg0b=0xff;				//MAR3 
    reg0c=0xff;				//MAR4 
    reg0d=0xff;				//MAR5 
    reg0e=0xff;				//MAR6 
    reg0f=0xff;				//MAR7 
 
//    initNIC();				//³õʼ»¯MACµØÖ·ºÍÍøÂçÏà¹Ø²ÎÊý 
 
	//½«Íø¿¨ÉèÖóÉÕý³£µÄģʽ,¸úÍâ²¿ÍøÂçÁ¬½Ó 
    page(0); 
    reg0c=0xCC;				//RCR 
    reg0d=0xE0;				//TCR 
    reg00=0x22;				//ÕâʱÈÃоƬ¿ªÊ¼¹¤×÷? 
    reg07=0xFF;				//Çå³ýËùÓÐÖжϱê־λ 
} 
/*---------------------------------------------------------------- 
ne2000·¢°ü×Ó³ÌÐò 
·¢ËÍÒ»¸öÊý¾Ý°üµÄÃüÁî,³¤¶È×îСΪ60×Ö½Ú 
×î´ó1514×Ö½ÚÐèÒª·¢Ë͵ÄÊý¾Ý°üÒªÏÈ´æ·ÅÔÚtxdnet»º³åÇø 
-----------------------------------------------------------------*/ 
void send_packet(netcard *txdnet,WORD length) 
{ 
    BYTE i; 
    WORD ii; 
 
    page(0); 
    if(length<60) length=60; 
    for(i=0;i<3;i++) 
		txdnet->etherframe.sourcenodeid[i]=mypara.mynodeid[i].word; 
    txd_buffer_select=!txd_buffer_select; 
    if(txd_buffer_select) 
        reg09=0x40 ;		//txdwrite highaddress,send buffer 0 
    else 
        reg09=0x46 ;		//txdwrite highaddress,send buffer 1 
    reg08=0x00;				//read page address low 
    reg0b=length>>8;		//read count high 
    reg0a=length&0xFF;		//read count low 
    reg00=0x12;				//write dma, page0 
 
    for(ii=4;iibytes.bytebuf[ii]; 
 
    for(i=0;i<6;i++){                   //×î¶àÖØ·¢6´Î 
        for(ii=0;ii<1000;ii++)          //¼ì²étxpΪÊÇ·ñΪµÍ 
            if((reg00&0x04)==0) break; 
 
        if((reg04&0x01)!=0) break;      //±íʾ·¢Ëͳɹ¦ 
 
        reg00=0x3E; 
    } 
 
    if(txd_buffer_select) reg04=0x40;   //txd packet start send buffer 0; 
    else reg04=0x46;		//txd packet start send buffer 1; 
 
    reg06=length>>8;		//high byte counter 
    reg05=length&0xFF;		//low byte counter 
 
    reg00=0x3E;				//to sendpacket; 
} 
 
bit recv_packet(netcard *rxdnet)//ne2000ÊÕ°ü×Ó³ÌÐò 
{ 
    BYTE i; 
    WORD ii; 
    BYTE bnry,curr; 
 
    page(0); 
    reg07=0xFF; 
    bnry=reg03;				//bnry page have read ¶ÁÒ³Ö¸Õë 
    page(1); 
    curr=reg07;				//curr writepoint 8019дҳָÕë 
    page(0); 
    if(curr==0) 
        return 0;			//¶ÁµÄ¹ý³Ì³ö´í 
    bnry=bnry+1; 
    if(bnry>0x7F) bnry=0x4C; 
    if(bnry!=curr){			//´Ëʱ±íʾÓÐеÄÊý¾Ý°üÔÚ»º³åÇøÀï 
    //¶Áȡһ°üµÄǰ18¸ö×Ö½Ú:4×Ö½ÚµÄ8019Í·²¿,6×Ö½ÚÄ¿µÄµØÖ·,6×Ö½ÚÔ­µØÖ·,2×Ö½ÚЭÒé 
    //ÔÚÈκβÙ×÷¶¼×îºÃ·µ»Øpage0 
        page(0); 
        reg09=bnry;			//read page address high 
        reg08=0x00;			//read page address low 
        reg0b=0x00;			//read count high 
        reg0a=18;			//read count low 
        reg00=0x0A;			//read dma 
        for(i=0;i<18;i++) 
            rxdnet->bytes.bytebuf[i]=reg10; 
        i=rxdnet->bytes.bytebuf[3];     //½«³¤¶È×ֶεĸߵÍ×Ö½Úµôת 
        rxdnet->bytes.bytebuf[3]=rxdnet->bytes.bytebuf[2]; 
        rxdnet->bytes.bytebuf[2]=i; 
        rxdnet->etherframe.length=rxdnet->etherframe.length-4; //È¥µô4¸ö×Ö½ÚµÄCRC 
        //±íʾ¶ÁÈëµÄÊý¾Ý°üÓÐЧ 
        if(((rxdnet->bytes.bytebuf[0]&0x01)==0)||(rxdnet->bytes.bytebuf[1]>0x7F)||(rxdnet->bytes.bytebuf[1]<0x4C)||(rxdnet->bytes.bytebuf[2]>0x06)) 
		{ 
            //½ÓÊÕ״̬´íÎó,»òÕßnext_page_start´íÎó»òÕß³¤¶È´íÎó,½«¶ªÆúËùÓÐÊý¾Ý°ü 
            page(1); 
            curr=reg07;		//current page 
            if((curr>0x7f)||(curr<0x4c)) curr=0x4d; 
            reg07=curr; 
            page(0);		//Çл»»Øpage0 
            bnry=curr-1; 
            if(bnry<0x4C) bnry=0x7F; 
            reg03=bnry;		//write to bnry 
            return 0; 
        } 
        else{				//±íʾÊý¾Ý°üÊÇÍêºÃµÄ.¶ÁȡʣϵÄÊý¾Ý 
            if((rxdnet->etherframe.protocal==0x0800)||(rxdnet->etherframe.protocal==0x0806)){ 
							//ЭÒéΪIP»òARP²Å½ÓÊÕ 
                reg09=bnry;	//read page address high 
                reg08=4;	//read page address low 
                reg0b=rxdnet->etherframe.length>>8;     //read count high 
                reg0a=rxdnet->etherframe.length&0xFF;   //read count low 
                reg00=0x0A;	//read dma 
                for(ii=4;iietherframe.length+4;ii++) 
                    rxdnet->bytes.bytebuf[ii]=reg10; 
            } 
            bnry=rxdnet->bytes.bytebuf[1]-1;//next page start-1 
            if(bnry<0x4C) bnry=0x7F; 
            reg03=bnry;		//write to bnry 
            return 1;		//have new packet 
        } 
    } 
    return 0; 
} 
 
/*EOF*/