⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_8019.lst

📁 在89C51上实现TCPIP协议
💻 LST
📖 第 1 页 / 共 3 页
字号:
 185   1              delay_1ms(10);
 186   1              
 187   1      #endif
 188   1              
 189   1              /* copy RAM data to RTL8019AS iRAM with (from MAC to end of data ) */
 190   1              ei_output( EthTxBuf, TX_START_PG << 8, pkLengthInOctets );
 191   1      
 192   1              /* Just send it, and does not check */
 193   1              EN0_TCNTLO = pkLengthInOctets& 0xff;
 194   1              EN0_TCNTHI = pkLengthInOctets>> 8;
 195   1              EN0_TPSR = TX_START_PG;
 196   1              EN_CMD = E8390_NODMA + E8390_TRANS + E8390_START;
 197   1              
 198   1              /* Turn 8390 interrupts back on. */
 199   1              EN0_IMR = ENISR_ALL;
 200   1              return 1;
 201   1      }
 202          
 203          /* copy RAM data to RTL8019AS Internal RAM */ 
 204          void ei_output( BYTE *buf, WORD StartAddr, WORD Count )
 205          {
 206   1              word loop;
 207   1              
 208   1              EN0_ISR = ENISR_RDC;
 209   1              /* Now the normal output. */
 210   1              EN0_RCNTLO = Count & 0xff;
 211   1              EN0_RCNTHI = Count >> 8;
 212   1              EN0_RSARLO = StartAddr & 0xFF;
 213   1              EN0_RSARHI = StartAddr >> 8;
 214   1              EN_CMD = E8390_RWRITE + E8390_START + E8390_PAGE0;
 215   1              for(loop=0;loop < Count;loop++){
 216   2              EN_DATA = *buf++;
 217   2              }
 218   1              EN0_ISR = ENISR_RDC;    /* Ack intr. to Remote DMA */
 219   1      }
 220          
 221          void ei_receive(void) reentrant /* maybe reentrant... */
 222          {
 223   1              word pkt_len, current_offset;
 224   1      
 225   1              byte rx_pkt=0;
 226   1              byte rxing_page, this_frame, next_frame;
 227   1              
 228   1              while ( ++rx_pkt < 10) { 
 229   2                      /* Get the Receive Page, CURR */
 230   2                      EN_CMD = EN_NODMA + EN_PAGE1 + EN_START;  
 231   2                      rxing_page = EN1_CURPAG;
 232   2                      EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
 233   2                      
 234   2                      /* Remove one frame from the ring.  Boundary is always a page behind. */
 235   2                      this_frame = EN0_BOUNDARY + 1;
 236   2                      
 237   2                      if (this_frame >= RX_STOP_PG)
 238   2                              this_frame = RX_START_PG;
C51 COMPILER V7.07   DRV_8019                                                              04/20/2004 18:04:40 PAGE 5   

 239   2                      
 240   2                      if (this_frame == rxing_page)   /* Read all the frames? */
 241   2                              break;                          /* Done for now */
 242   2                      
 243   2                      current_offset = (word)(this_frame << 8);
 244   2                      
 245   2                      /* Get the header of this packet */
 246   2                      ethernet_get_8390_hdr( current_offset, 4);
 247   2                      pkt_len = (word)(ethernet_8390_hdr[3]<<8) + ethernet_8390_hdr[2] - 4;
 248   2      
 249   2                      next_frame = this_frame + 1 + ((pkt_len+4)>>8);
 250   2                      //print(" | this : ") ; putb_ser( this_frame ) ;
 251   2                      //print(" | next : ") ; putb_ser( next_frame ) ;
 252   2                      //print(" | 8390_hdr[1] : ") ; putb_ser( ethernet_8390_hdr[1] ) ;
 253   2                      //print("\r\n");
 254   2              
 255   2                      if ( ethernet_8390_hdr[1] != next_frame 
 256   2                              && ethernet_8390_hdr[1] != next_frame + 1
 257   2                              && ethernet_8390_hdr[1] != next_frame - (RX_STOP_PG-RX_START_PG) 
 258   2                              && ethernet_8390_hdr[1] != next_frame + 1 - (RX_STOP_PG-RX_START_PG) ) {
 259   3                              current_page = rxing_page;
 260   3                              EN0_BOUNDARY = current_page-1;
 261   3                              continue;
 262   3                      }
 263   2      
 264   2                      if ( pkt_len > MAX_PACKET_SIZE || pkt_len < MIN_PACKET_SIZE ) {
 265   3                              //print("\n\rBogus packet size..");
 266   3                      }
 267   2                      else if ((ethernet_8390_hdr[0] & 0x0f) == ENRSR_RXOK) {
 268   3                              //print("\r\nhdr len =");
 269   3                              //putb_ser(ethernet_8390_hdr[3]);
 270   3                              //putb_ser(ethernet_8390_hdr[2]);
 271   3                              
 272   3                              /* If RxBuffer is full, then break */
 273   3                              if ( EthRxBufWrPtr == EthRxBufRdPtr ) 
 274   3                                      break;
 275   3                              ei_input( EthRxBuf[EthRxBufWrPtr], current_offset + 4, pkt_len );
 276   3                              EthRxBufWrPtr++;
 277   3                              if ( EthRxBufWrPtr == NBUF ) EthRxBufWrPtr = 0;
 278   3                      }
 279   2                      
 280   2                      next_frame = ethernet_8390_hdr[1];
 281   2                      
 282   2                      /* This _should_ never happen: it's here for avoiding bad clones. */
 283   2                      if (next_frame >= RX_STOP_PG) { /* next frame inconsistency */
 284   3                              next_frame = RX_START_PG;
 285   3                      }
 286   2                      current_page = next_frame;
 287   2                      EN0_BOUNDARY = next_frame-1;
 288   2              }
 289   1      
 290   1              /* We used to also ack ENISR_OVER here, but that would sometimes mask
 291   1          a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
 292   1          EN0_ISR = ENISR_RX+ENISR_RX_ERR;
 293   1      }
 294          
 295          //void ei_input(byte *buf, word StartAddr, word Count)
 296          void ei_input(byte *buf, word StartAddr, word Count) reentrant
 297          {
 298   1          word loop;
 299   1              
 300   1          EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
C51 COMPILER V7.07   DRV_8019                                                              04/20/2004 18:04:40 PAGE 6   

 301   1          /* Set Remote byte count */
 302   1          EN0_RCNTLO = (byte)(Count & 0xff);   /*  Low  byte of tx byte count  */
 303   1          EN0_RCNTHI = (byte)(Count >> 8);    /*  High byte of tx byte count  Transmit byte count register */
 304   1      
 305   1          /* Set Remote Start Address */
 306   1          EN0_RSARLO = (byte)(StartAddr & 0xff);     /*LSB Remote start address reg  */
 307   1          EN0_RSARHI = (byte)(StartAddr >> 8);     /*  MSB Remote start address reg  */
 308   1                      
 309   1          EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
 310   1          for(loop=0;loop < Count;loop++){
 311   2              *buf++ = EN_DATA; 
 312   2          }
 313   1          EN0_ISR = ENISR_RDC;        /* Ack intr. to Remote DMA */
 314   1      }
 315          
 316          //void ethernet_get_8390_hdr( word StartAddr, word Count)
 317          void ethernet_get_8390_hdr( word StartAddr, word Count) reentrant
 318          {
 319   1          word loop;
 320   1              
 321   1          EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
 322   1          /* Set Remote byte count */
 323   1          EN0_RCNTLO = (byte)(Count & 0xff);   /*  Low  byte of tx byte count  */
 324   1          EN0_RCNTHI = (byte)(Count >> 8);    /*  High byte of tx byte count  Transmit byte count register */
 325   1      
 326   1          /* Set Remote Start Address */
 327   1          EN0_RSARLO = (byte)(StartAddr & 0xff);     /*LSB Remote start address reg  */
 328   1          EN0_RSARHI = (byte)(StartAddr >> 8);     /*  MSB Remote start address reg  */
 329   1                      
 330   1          EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
 331   1          for(loop=0;loop < Count;loop++){
 332   2              ethernet_8390_hdr[loop] = EN_DATA;
 333   2          }
 334   1          EN0_ISR = ENISR_RDC;        /* Ack intr. to Remote DMA */
 335   1      }
 336          
 337          void ei_rx_overrun( void )
 338          {
 339   1              byte was_txing, must_resend = 0;
 340   1      
 341   1              //print_int("OVER");
 342   1              /* Record whether a Tx was in progress 
 343   1                 and then issue the stop command.     */
 344   1              
 345   1              was_txing = EN_CMD & EN_TRANS;
 346   1              EN_CMD = EN_NODMA + EN_PAGE0 + EN_STOP;
 347   1              
 348   1              delay_1ms(2);   /* I don't know exactly time yet.. at least 2ms */
 349   1      
 350   1              /** Reset RBCR[01] back to zero as per magic incantation. */
 351   1              EN0_RCNTLO = 0x00;
 352   1              EN0_RCNTHI = 0x00;
 353   1      
 354   1              /* See if any Tx was interrupted or not. According to NS, this
 355   1                 step is vital, and skipping it will cause no end of havoc. */
 356   1              if (was_txing) { 
 357   2                      if (!(EN0_ISR & (ENISR_TX + ENISR_TX_ERR))) must_resend = 1;
 358   2              }
 359   1      
 360   1              /* Have to enter loopback mode and then restart the NIC before
 361   1                you are allowed to slurp packets up off the ring.      */
 362   1              EN0_TXCR = E8390_TXOFF;
C51 COMPILER V7.07   DRV_8019                                                              04/20/2004 18:04:40 PAGE 7   

 363   1              EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
 364   1      
 365   1              /* Clear the Rx ring of all the debris(颇祈), and ack the interrupt.    */
 366   1              ei_receive();
 367   1              EN0_ISR = ENISR_OVER;
 368   1              
 369   1              /* Leave loopback mode, and resend any packet that got stopped.  */
 370   1              EN0_TXCR = E8390_TXCONFIG;
 371   1              if (must_resend) EN_CMD = EN_NODMA + EN_PAGE0 + EN_START + EN_TRANS;
 372   1              
 373   1      }
 374              
 375          void ethernet_register_test(void)   /* All Register test */
 376          {
 377   1          byte i,read,write;
 378   1          
 379   1          print("\n\r------------------------------------------------------------------------");
 380   1          print("\n\rAddr       Page0         Page1         Page2         Page3");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -