#include //#include //#include //#include #include #include //BYTE efp; //WORD len; sbit HW_RESET=P2^7; int number; BYTE mymac[MACLEN]; typedef struct { /* NIC hardware packet ```*/ BYTE stat; /* Error status */ BYTE next; /* Pointer to next block */ WORD len; /* Length of this frame incl. CRC */ } NICHDR; NICHDR nichdr; WORD put_ethernet(void *efp,WORD len); WORD get_ethernet(void *efp); void delay_ms(int number); void resetnic(); void getnic(WORD addr,BYTE buf[],WORD len); void putnic(WORD addr,BYTE buf[],WORD len); BYTE nicwrap(BYTE page); //*************************************************** // 接收数据包,将8019中的数据包读入指定的数据包缓冲区pkt,帧头读入nichdr结构中 // 全局变量 nichdr // 全局变量 next_packet // 返回:如果接收到数据包,返回数据包长度len,(该长度为减去校验和长度) // 否则 : 0 // get packet into buffer,return length (excel CRC ),or 0 if no available //*************************************************** WORD get_ethernet(void *efp) { WORD current_offset; BYTE curr_page; BYTE bnry; if (EN0_ISR &0x10) resetnic(); /* Get the Receive Page, CURR */ EN_CMD = EN_NODMA + EN_PAGE1 + EN_START; curr_page = EN1_CURPAG; EN_CMD = EN_NODMA + EN_PAGE0 + EN_START; bnry=EN0_BOUNDARY+1; /* Get the BOUNDARY Register */ if (bnry>RX_Stop_PG) bnry=RX_START_PG; /* Remove one frame from the ring. Boundary is always a page behind. */ // if (curr_page==0) return (0); if (bnry!=curr_page) { current_offset = (WORD)(bnry << 8); /* Get the header of this packet */ //memset(&nichdr,0xee,sizeof(nichdr)); getnic(current_offset, (BYTE *)&nichdr,sizeof(nichdr)); nichdr.len=(nichdr.len/256)+((nichdr.len %256)<<8); //keil c 在结构中使用该方法时,编译器编译的不正确(keil c bug) // nichdr.len=(nichdr.len>>8)&0xff+(nichdr.len&0xff)<<8; if ((nichdr.stat &0x01) && nichdr.len>=MINFRAMEC && nichdr.len<=MAXFRAMEC) getnic(current_offset+sizeof(nichdr),(BYTE *)efp,nichdr.len-sizeof(nichdr)); if (nichdr.next>=RX_START_PG && nichdr.next>8); putnic(TX_START_PG<<8,(BYTE *)efp,len); EN_CMD=EN_NODMA+EN_PAGE0+EN_TRANS; } return(len); } //************************************************************* // reset nic (ne2000 compact 8019as) //************************************************************* void resetnic() { HW_RESET = 1; /* Hardware RESET. when EN_RESET = 0; is Software */ delay_ms(10); HW_RESET = 0; delay_ms(10); EN_CMD = EN_PAGE0 + EN_NODMA + EN_Stop; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */ delay_ms(4); //EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_BOS; /* ?FIFO treshold 8byte !!,normal operation, byte transfer mode selection */ /* Clear the remote byte count registers. */ EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS; EN0_RCNTHI = 0x00; /* MSB remote byte count reg */ EN0_RCNTLO = 0x00; /* LSB remote byte count reg */ EN0_RXCR = E8390_RXOFF; /* RX configuration reg Monitor mode (no packet receive) */ EN0_TXCR = E8390_TXOFF; /* TX configuration reg set internal loopback mode */ EN0_TPSR = NE_START_PG; EN0_STARTPG = RX_START_PG ; /* DMA START PAGE 46h */ /* Starting page of ring buffer. First page of Rx ring buffer 46h*/ EN0_StopPG = NE_Stop_PG; /* Ending page +1 of ring buffer */ EN0_BOUNDARY = RX_START_PG; /* Boundary page of ring buffer */ EN0_ISR = 0xff; /* INTerrupt stauts reg */ EN0_IMR = 0; /* INTerrupt mask reg = Disable all Interrupt */ EN_CMD = EN_PAGE1 + EN_NODMA+EN_Stop; delay_ms(4); EN1_PAR0 = mymac[0]; EN1_PAR1 = mymac[1]; EN1_PAR2 = mymac[2]; EN1_PAR3 = mymac[3]; EN1_PAR4 = mymac[4]; EN1_PAR5 = mymac[5]; /* Initialize the multicast list to accept-all. If we enable multicast the higher levels can do the filtering. multicast filter mask array (8 bytes) */ EN1_MAR0 = 0xff; EN1_MAR1 = 0xff; EN1_MAR2 = 0xff; EN1_MAR3 = 0xff; EN1_MAR4 = 0xff; EN1_MAR5 = 0xff; EN1_MAR6 = 0xff; EN1_MAR7 = 0xff; EN1_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */ EN_CMD = EN_PAGE0 + EN_NODMA ; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */ EN0_RXCR = ENRXCR_RXCONFIG; /* rx on(broadcasts, no multicast,errors 04*/ EN0_TXCR = ENTXCR_TXCONFIG; /* xmit on. */ EN0_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */ /* It must be cleared after power up. */ EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */ EN_CMD = EN_PAGE0 + EN_NODMA + EN_START; } //******************************************* // get a packet form a given address in NIC's RAM // DMA READ // //******************************************* void getnic(WORD addr, BYTE buf[],WORD len) { EN0_ISR=ENISR_RDC; //clear remote dma interrupt flag EN0_RCNTLO = (BYTE)(len&0xff); // read length low EN0_RCNTHI = (BYTE)(len>>8); // read length high EN0_RSARLO=(BYTE)(addr &0xff); // read address low EN0_RSARHI=(BYTE)(addr>>8); // read address high EN_CMD=EN_RREAD+EN_START+EN_PAGE0; // do dma read while (len--) *buf++=EN_DATA; } //******************************************* // put a packet into a given address in NIC's RAM // DMA Write // //******************************************* void putnic(WORD addr, BYTE buf[],WORD len) { len+=len&0x01; EN0_ISR=ENISR_RDC; //clear remote dma interrupt flag EN0_RCNTLO = (BYTE)(len&0xff); EN0_RCNTHI = (BYTE)(len>>8); EN0_RSARLO=(BYTE)(addr &0xff); EN0_RSARHI=(BYTE)(addr>>8); EN_CMD=EN_RWRITE+EN_START+EN_PAGE0; while (len--) EN_DATA=*buf++; len=10000; while ((len && (EN0_ISR & ENISR_RDC))==0) len--; } //*************************************** // wrap an rx page number //*************************************** BYTE nicwrap(BYTE page) { if (page>=RX_Stop_PG) page+=RX_START_PG-RX_Stop_PG; else if(pagee.ptype = pcol; //memcpy(efp->e.dest, dest, MACLEN); // memcpy(efp->e.srce, srce, MACLEN); dlen += sizeof(ETHERHDR); return(dlen); } /* Do TCP-style checksum. Improved algorithm is from RFC 1071 */ WORD csum(void *dp, WORD count) { register LWORD total=0L; register WORD n, *p, carries; n = count / 2; p = (WORD *)dp; while (n--) total += *p++; if (count & 1) total += (*(BYTE *)p)<<8; while ((carries=(WORD)(total>>16))!=0) total = (total & 0xffffL) + carries; return((WORD)total); }