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;ii bytes.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;ii etherframe.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*/