00001 /*############################################################################## 00002 00003 nIP - nano IP stack 00004 00005 Copyright (C) 2005 - 00006 Andreas Dittrich, dittrich@informatik.hu-berlin.de 00007 Jon Kowal, kowal@informatik.hu-berlin.de 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License 00011 as published by the Free Software Foundation; either version 2 00012 of the License, or (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 00023 ##############################################################################*/ 00024 00025 /** @file rtl8019.c 00026 * 00027 * Driver for one RTL8019 network interface card, (or probably any other NE2000 00028 * compatible card). 00029 * 00030 * The driver interface is designed to work with the nIP internet stack and 00031 * relies on its special memory management. 00032 * 00033 *@note This driver is written to be used with just one NIC at a time but may be 00034 * adapted easily to work with several cards simulaneously. For that the static 00035 * configuration of the address and data ports, the interrupt and the MAC 00036 * address would have to be moved from rtl8019.h to a dynamically configurable 00037 * space. Also the global rtl_net_if pointer variable will have to be moved 00038 * locally into the driver functions and be resolved there using the function 00039 * nip_net_if_ptr(). 00040 */ 00041 00042 #include <avr/io.h> 00043 #include <avr/interrupt.h> 00044 #include "nip_init.h" 00045 #include NIP_ARCH_FILE(rtl8019.h) 00046 #include "nip_types.h" 00047 #include "dispatcher.h" 00048 #include "net/net_if.h" 00049 #include "net/ethernet.h" 00050 00051 #if (NIP_RTL_ENABLE == 1) 00052 00053 // mac address 00054 //uint8_t rtl_mac_addr[] = { 0x00, 0x20, 0x18, 0xB1, 0x06, 0x31 }; 00055 00056 /** @note this driver is currently written to support one ethernet adapter only. 00057 * It can easily be adapted for use with several adapters though, by moving the 00058 * global rtl_net_if pointer variable into all driver functions and have to 00059 * pointer be resolved locally, depending on the given net_if_id variable. The 00060 * rtl_next_packet variable would have to be handled on a per-interface basis.*/ 00061 nip_net_if_id_t rtl_net_if_id = NIP_NET_NO_IF; 00062 nip_net_if_t *rtl_net_if; 00063 uint8_t rtl_next_packet; 00064 00065 //Routinen zum ansteuern der Netzwerkkarte 00066 00067 //Prototype 00068 void WriteRTL (unsigned char,unsigned char); 00069 unsigned char ReadRTL (unsigned char); 00070 void Write_Ethernet_Init (unsigned int Packet_Length); 00071 void Write_Ethernet_Buffer (unsigned char *buffer, unsigned int bufferlen); 00072 void Write_Ethernet_Terminate (unsigned int bufferlen); 00073 int Read_Ethernet_Init (void); 00074 void Read_Ethernet_Terminate (unsigned int count); 00075 void Read_Ethernet_Byte (unsigned char *buffer, unsigned int count); 00076 00077 00078 00079 /** nIP interface to enable rtl8019 network interface 00080 * @todo check interface flags. Enable IRQ. 00081 * @todo set correct return value 00082 */ 00083 nip_success_t nip_rtl_open( nip_net_if_id_t net_if_id ) 00084 { 00085 uint8_t tmp; /* variable used for all kinds of char-purposes */ 00086 unsigned int a; 00087 unsigned long i = 0; 00088 nip_phy_if_t *phy_conf; 00089 00090 // disable AVR interrupt line 00091 RTL_DISABLE_INT(); 00092 00093 // get network interface configuration 00094 rtl_net_if = nip_net_if_ptr( net_if_id ); 00095 phy_conf = &rtl_net_if->phy_conf; 00096 00097 00098 //Set Addr Port Direction = Output 00099 DATA_ADDR_RLT = OUTPUT; 00100 00101 //Set all Addrport High 00102 ADDR_PORT_RLT = OUTPUT; 00103 //set Data Port Direction = Input 00104 DATA_CTRL_RLT = INPUT; 00105 00106 //Set Reset Pin Low 00107 RTL_RESET_OFF(); 00108 00109 //added by holgi 00110 //meine Karten laufen nur wenn man hier noch ca. 100ms wartet 00111 //wait a long time 00112 while (i < 60000 * 5) i++; 00113 //end added by holgi 00114 00115 RTL_CLEAR_ISR(); 00116 00117 ReadRTL (RTL_RSTPORT); 00118 WriteRTL(RTL_RSTPORT , 0xFF); 00119 00120 00121 //wait a short time, at least 1.6ms 00122 while (a < 1000) 00123 { 00124 a++; 00125 } 00126 00127 // Put NIC in stop mode 00128 WriteRTL (RTL_CR , ( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE )); 00129 00130 // wait until RST bit of status Register is cleared 00131 do 00132 { 00133 tmp = ReadRTL( RTL_ISR ); 00134 } while ( (tmp & 0x80) == 0 ); 00135 00136 // Check Board ID 00137 tmp = ReadRTL( RTL_8019ID0 ); //should be 0x50 00138 if ( tmp != 0x50 ) return NIP_ERROR; 00139 tmp = ReadRTL( RTL_8019ID1 ); //should be 0x70 00140 if ( tmp != 0x70 ) return NIP_ERROR; 00141 00142 00143 00144 /* //wait a short time 00145 a = 0; 00146 while (a < 1000) 00147 { 00148 a++; 00149 } 00150 */ 00151 /* ************************************************************************* * 00152 * Standard Configuration * 00153 * ************************************************************************* */ 00154 00155 00156 WriteRTL (RTL_DCR , DCRVAL); 00157 WriteRTL (RTL_RBCR0 , 0x00); 00158 WriteRTL (RTL_RBCR1 , 0x00); 00159 #if defined( ETH_NIC_CHECK_MAC ) 00160 WriteRTL (RTL_RCR , 0xDF/*RCRVAL_CHECK_PHY*/); 00161 #else 00162 WriteRTL (RTL_RCR , RCRVAL_IGN_PHY); 00163 #endif 00164 00165 // set loopback mode 00166 WriteRTL (RTL_TCR , 0x02); 00167 // configure receive buffer ring 00168 WriteRTL (RTL_TPSR , RTL_RXSTART); 00169 WriteRTL (RTL_PSTART, RTL_RXSTART); 00170 WriteRTL (RTL_BNRY , RTL_RXSTART); 00171 WriteRTL (RTL_PSTOP , RTL_RXSTOP); 00172 00173 // clear interrupt status register 00174 RTL_CLEAR_ISR(); 00175 00176 /* ************************************************************************* * 00177 * Configure interrupt behaviour through Interrupt Mask Register (IMR) * 00178 * ************************************************************************* */ 00179 00180 // add interrupt for packet reception (PRX) 00181 tmp = RTL_ISR_PRX; 00182 00183 /* add receive buffer overwrite interrupt (OVW). The buffer may overrun because 00184 * we missed previous packet reception interrupts. The OVW interrupt is to make 00185 * sure we finally empty the buffer. 00186 */ 00187 tmp |= RTL_ISR_OVW; 00188 00189 // add receive error interrupt (RXE) for logging purpose 00190 if ( phy_conf->flags & NIP_PHY_IFF_CNT_RXE ) tmp |= RTL_ISR_RXE; 00191 00192 // add transmit error interrupt (TXE) for logging purpose 00193 if ( phy_conf->flags & NIP_PHY_IFF_CNT_TXE ) tmp |= RTL_ISR_TXE; 00194 00195 // write Interrupt Mask Register 00196 WriteRTL (RTL_CR , ( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00197 WriteRTL (RTL_IMR , tmp); 00198 00199 00200 00201 00202 /* ************************************************************************* * 00203 * Configure Physical Address * 00204 * ************************************************************************* */ 00205 00206 00207 // Read MAC address from Realtek's EEPROM. The EEPROM is mapped 00208 // to address 0x00 of the Realtek RAM, so that's the address we're trying 00209 // to read from, using Remote DMA. 00210 // set remote start address 00211 00212 WriteRTL( RTL_RSAR0, 0x00 ); 00213 WriteRTL( RTL_RSAR1, 0x00 ); 00214 00215 // Set the Remote DMA Byte Count to 6 00216 WriteRTL( RTL_RBCR0, 0x0C ); 00217 WriteRTL( RTL_RBCR1, 0x00 ); 00218 00219 // Issue the Remote DMA read command and switch to register page 1 which will be 00220 // needed to access the PAR registers to store the MAC address in. 00221 WriteRTL (RTL_CR ,RTL_CR_START | RTL_CR_RD_REMOTE_READ | RTL_CR_SELECT_PAGE1 ); 00222 00223 // Read 6 Bytes and write to Physical-Address-Registers (PAR) 00224 tmp = 0; 00225 do{ 00226 // read byte 00227 phy_conf->hw_addr[tmp] = ReadRTL ( RTL_RDMAPORT ); 00228 phy_conf->hw_brdcst_addr[tmp] = 0xFF; 00229 // advance to next byte 00230 ReadRTL ( RTL_RDMAPORT ); 00231 #if defined( ETH_PHY_CHECK_MAC ) 00232 // write byte to PAR 00233 WriteRTL ((RTL_PAR0 + tmp), phy_conf->hw_addr[tmp]); 00234 #endif 00235 // set multicast mask to receive all multicasts 00236 /// @todo set multicast mask depending on group membership 00237 WriteRTL ((RTL_MAR0 + tmp), 0xFF ); 00238 }while (++tmp < 6); 00239 00240 00241 // Set current page 00242 rtl_next_packet = RTL_RXSTART ; 00243 WriteRTL (RTL_CURR , rtl_next_packet ); 00244 00245 // Configure and activate AVR interrupt line 00246 RTL_CONFIGURE_INT(); 00247 RTL_ENABLE_INT(); 00248 00249 // Put NIC in start mode 00250 WriteRTL (RTL_CR ,( RTL_CR_START | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00251 00252 // Remove NIC from loopback mode 00253 WriteRTL (RTL_TCR , TCRVAL); 00254 00255 // NIC is now ready to receive and transmit packets 00256 00257 return NIP_SUCCESS; 00258 } 00259 00260 00261 /** Initialize reading new packat from network interface. 00262 * 00263 * Before reading a packet from the RTL8019 buffer, 4 bytes have to be read 00264 * which include status information and packet length. 00265 * 00266 * @return NIP_E_OK or NIP_E_NO_PACKET 00267 */ 00268 nip_success_t nip_rtl_read_init ( nip_net_if_id_t net_if_id ) 00269 { 00270 #if DEBUG_CALLS 00271 print("---- Read_Ethernet_Init --------------------------\n"); 00272 #endif 00273 uint8_t tmp, tmp1, sreg; 00274 nip_phy_if_t *phy_conf = &rtl_net_if->phy_conf; 00275 // make sure the following operations aren't interrupted 00276 sreg = SREG; 00277 cli(); 00278 00279 // Read Buffer pointer registers. The Boundary Register (BNRY) holds a 00280 // pointer to the last page that has been read. The Current Page 00281 // Register (CURR) points to the page address of the first receive 00282 // buffer page. If both registers are equal, no new packet data is 00283 // available. 00284 00285 WriteRTL ( RTL_CR ,( RTL_CR_START | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE1 )); 00286 tmp1 = ReadRTL(RTL_CURR); //auslesen NIC Register curr 00287 00288 WriteRTL ( RTL_CR ,( RTL_CR_START | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00289 tmp = ReadRTL(RTL_BNRY); //auslesen NIC Register bnry 00290 00291 if ( tmp1 == tmp ) 00292 { 00293 // queue empty 00294 SREG = sreg; 00295 return NIP_ERROR; 00296 } 00297 00298 WriteRTL( RTL_RSAR0, 0x00 ); 00299 WriteRTL( RTL_RSAR1, tmp ); 00300 00301 WriteRTL( RTL_RBCR0, 0x04 ); 00302 WriteRTL( RTL_RBCR1, 0x00 ); 00303 00304 WriteRTL ( RTL_CR ,( RTL_CR_START | RTL_CR_RD_REMOTE_READ | RTL_CR_SELECT_PAGE0 )); 00305 00306 //WriteRTL( RTL_CR ,( RTL_CR_START | RTL_CR_RD_SEND_PACKET )); 00307 tmp = ReadRTL ( RTL_RDMAPORT ); // content of Receive Status Register (RSR) 00308 rtl_next_packet = ReadRTL ( RTL_RDMAPORT ); // pointer to next packet in buffer 00309 tmp = ReadRTL ( RTL_RDMAPORT ); // packet length (LSB) 00310 tmp1 = ReadRTL( RTL_RDMAPORT ); // packet length (MSB) 00311 00312 phy_conf->rx_bytes = (tmp1<<8) + tmp - RTL_ETHER_TRAILER_SIZE; 00313 phy_conf->rx_pos = 4; 00314 00315 // WriteRTL ( RTL_CR ,( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00316 00317 SREG = sreg; 00318 return NIP_SUCCESS; 00319 } 00320 00321 /** Copy number of bytes from NIC memory into buffer. If buffer is NULL the read 00322 * bytes will be discarded. That effect is usually used when discarding a packet. 00323 * 00324 * You have to call nip_rtl_read_init() once per packet before doing any read 00325 * operations. 00326 */ 00327 uint16_t nip_rtl_read ( nip_net_if_id_t net_if_id, uint8_t *buffer, uint16_t count) 00328 { 00329 uint8_t sreg = SREG; 00330 cli(); 00331 #if DEBUG_NIC 00332 printf("Read %d Bytes from Network Interface\n",count); 00333 #endif 00334 00335 uint16_t ctr; 00336 nip_phy_if_t *phy_conf = &rtl_net_if->phy_conf; 00337 00338 // Jump to set current position in receive buffer 00339 00340 WriteRTL( RTL_RSAR0, phy_conf->rx_pos & 0x00FF ); 00341 WriteRTL( RTL_RSAR1, ReadRTL(RTL_BNRY) + ( (phy_conf->rx_pos&0xFF00) >> 8 )); 00342 00343 WriteRTL( RTL_RBCR0, count ); 00344 WriteRTL( RTL_RBCR1, count >> 8 ); 00345 00346 WriteRTL ( RTL_CR ,( RTL_CR_START | RTL_CR_RD_REMOTE_READ | RTL_CR_SELECT_PAGE0 )); 00347 00348 //Der Datenport wir auf input gesetzt vom NIC zum IC lesen 00349 DATA_CTRL_RLT = INPUT; 00350 //write Adress to Port 00351 ADDR_PORT_RLT = RTL_RDMAPORT; 00352 00353 //Daten in den Buffer uebernehmen 00354 for(ctr=0; ctr<count && phy_conf->rx_bytes > 0; ctr++) 00355 { 00356 //set read Pin to Low 00357 RTL_RD_OFF(); 00358 //wait a short time 00359 nop(); 00360 nop(); 00361 //read from port rtldata 00362 if ( buffer != NULL ) 00363 buffer[ctr] = DATA_PORT_RLT_READ; 00364 //set Read Pin to High 00365 RTL_RD_ON(); 00366 //read from RTL complete 00367 00368 //decrement packet byte count 00369 phy_conf->rx_bytes--; 00370 00371 // packet has been read completely 00372 if ( phy_conf->rx_bytes == 0 ) 00373 { 00374 // Update boundary register. This should be done after having read a 00375 // packet which we assume to have happened after all bytes were read. 00376 if ( rtl_next_packet < RTL_RXSTART ) 00377 WriteRTL (RTL_BNRY , RTL_RXSTOP - 1 ); 00378 else 00379 WriteRTL (RTL_BNRY , rtl_next_packet ); 00380 00381 ctr++; 00382 break; 00383 } 00384 } 00385 phy_conf->rx_pos += ctr; 00386 // WriteRTL ( RTL_CR ,( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00387 00388 SREG = sreg; 00389 00390 return ctr; 00391 } 00392 00393 /** Initialize transmission of Ethernet packet. If all header data is complete 00394 * the header will be written to packet buffer. If daddr is NULL, ARP will be 00395 * called to initiate address resolution. 00396 * @param net_if_id 00397 * @param ll_target_addr ip address of local link target 00398 * @param type ethernet type 00399 * @param daddr pointer to array with destination MAC address 00400 * @param saddr pointer to array with source MAC address 00401 * @param len size of packet to be sent 00402 * */ 00403 nip_error_t nip_rtl_send_init( nip_net_if_id_t net_if_id, void *ll_target_addr, 00404 uint16_t type, void *daddr, void *saddr, uint16_t len) 00405 { 00406 nip_phy_if_t *phy_conf = &rtl_net_if->phy_conf; 00407 uint8_t sreg; 00408 // if there are untransmitted bytes, assume the device is busy transmitting 00409 // another packet. 00410 if ( phy_conf->tx_bytes > 0 ) 00411 return NIP_E_DEV_BUSY; 00412 00413 // make sure the following operations aren't interrupted 00414 sreg = SREG; 00415 cli(); 00416 00417 len += 14; // add ethernet header length 00418 00419 // configure Ethernet transmission 00420 phy_conf->tx_bytes = len ; 00421 phy_conf->tx_pos = 0 ; 00422 if ( len < RTL_ETHER_MIN_SIZE ) 00423 len = RTL_ETHER_MIN_SIZE; 00424 00425 WriteRTL ( RTL_TPSR , RTL_TXSTART ); 00426 /* WriteRTL ( RTL_RSAR0, 0x00 ); 00427 WriteRTL ( RTL_RSAR1, RTL_TXSTART ); 00428 // WriteRTL ( RTL_ISR , (1<<PRX|1<<PTX|1<<RXE|1<<TXE|1<<OVW|1<<CNT|1<<RDC|1<<RST)); 00429 WriteRTL ( RTL_RBCR0, ( len & 0x00ff )); 00430 WriteRTL ( RTL_RBCR1, ( len & 0xff00 ) >>8 );*/ 00431 00432 // WriteRTL ( RTL_CR , ( RTL_CR_START | RTL_CR_RD_REMOTE_WRITE )); 00433 WriteRTL ( RTL_TBCR0, ( len & 0x00ff ) ); 00434 WriteRTL ( RTL_TBCR1, ( len & 0xff00 ) >>8 ); 00435 00436 // Build and send Ethernet Header 00437 nip_rtl_send( net_if_id, daddr, 6 ); 00438 nip_rtl_send( net_if_id, saddr, 6 ); 00439 nip_rtl_send( net_if_id, (uint8_t*)&type , 2 ); 00440 00441 SREG = sreg; 00442 00443 return NIP_E_OK; 00444 } 00445 00446 uint16_t nip_rtl_send( nip_net_if_id_t net_if_id, uint8_t* buffer, uint16_t count) 00447 { 00448 nip_phy_if_t *phy_conf = &rtl_net_if->phy_conf; 00449 uint16_t ctr = phy_conf->tx_pos + phy_conf->tx_bytes; 00450 uint8_t sreg; 00451 00452 // make sure the following operations aren't interrupted 00453 sreg = SREG; 00454 cli(); 00455 00456 if ( ctr < RTL_ETHER_MIN_SIZE) 00457 ctr = RTL_ETHER_MIN_SIZE; 00458 00459 WriteRTL ( RTL_CR , ( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00460 // WriteRTL ( RTL_CR , ( RTL_CR_START | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00461 00462 WriteRTL ( RTL_RSAR0, (phy_conf->tx_pos & 0x00FF) ); 00463 WriteRTL ( RTL_RSAR1, RTL_TXSTART + ((phy_conf->tx_pos&0xFF00)>>8)); 00464 WriteRTL ( RTL_RBCR0, ( ctr & 0x00ff ) ); 00465 WriteRTL ( RTL_RBCR1, ( ctr & 0xff00 ) >>8 ); 00466 00467 WriteRTL ( RTL_CR , ( RTL_CR_START | RTL_CR_RD_REMOTE_WRITE | RTL_CR_SELECT_PAGE0 )); 00468 00469 //Der Datenport wir auf output gesetzt vom IC zum NIC schreiben 00470 DATA_CTRL_RLT = OUTPUT; 00471 //write Adress to Port 00472 ADDR_PORT_RLT = RTL_RDMAPORT; 00473 00474 for ( ctr = 0; ; ) 00475 { 00476 // break, if count bytes have been sent and end of transmission has not 00477 // been reached 00478 if ( ctr == count && phy_conf->tx_bytes != 0 ) break; 00479 00480 // break, if end of transmission has been reached and no padding is 00481 // necessary 00482 if ( phy_conf->tx_bytes == 0 && ++phy_conf->tx_pos >= RTL_ETHER_MIN_SIZE ) break; 00483 00484 // write data to DMA channel 00485 if ( phy_conf->tx_bytes > 0 ) 00486 { 00487 phy_conf->tx_bytes--; 00488 // write Buffer-Data to Port 00489 DATA_PORT_RLT_WRITE = buffer[ctr]; 00490 ctr++; 00491 } else 00492 { 00493 // write Padding to Port 00494 DATA_PORT_RLT_WRITE = 0x00; 00495 } 00496 00497 //set write Pin to Low 00498 RTL_WR_OFF(); 00499 //wait a short time 00500 nop(); 00501 nop(); 00502 00503 //set write Pin to High 00504 RTL_WR_ON(); 00505 //write to RTL complete 00506 00507 } 00508 00509 phy_conf->tx_pos += ctr; 00510 00511 //loop_until_bit_is_set(ReadRTL(isr),rdc); 00512 ///@todo timeout might be needed in rare cases (if transmission failed) 00513 ///@todo check if the following line is needed 00514 //while ((ReadRTL(RTL_ISR) & RTL_ISR_RDC) == 0) {} 00515 00516 // terminate session if necessary 00517 if ( phy_conf->tx_bytes == 0 ) 00518 { 00519 00520 WriteRTL (RTL_CR,( RTL_CR_TRANSMIT_PACKET | RTL_CR_RD_ABORT_CMPLTE )); 00521 00522 } 00523 // WriteRTL ( RTL_CR , ( RTL_CR_STOP | RTL_CR_RD_ABORT_CMPLTE | RTL_CR_SELECT_PAGE0 )); 00524 00525 SREG = sreg; 00526 return ctr; 00527 } 00528 00529 00530 /** nIP interface to disable rtl8019 network interface 00531 * @todo disable network interface and irq. 00532 * @todo set correct return value 00533 */ 00534 nip_success_t nip_rtl_close( nip_net_if_id_t net_if_id ) 00535 { 00536 00537 return NIP_SUCCESS; 00538 } 00539 00540 00541 #ifdef RTL_INTERRUPT 00542 00543 /** Interrupt Service Routine to handle interrupt requests from network interface. 00544 * 00545 * @todo Unterbrechbare Interrupts verwenden: void RTL_INTERRUPT (void)__attribute__((interrupt)); 00546 * 00547 */ 00548 00549 ISR( RTL_INTERRUPT ) 00550 { 00551 uint8_t isr = 0; 00552 00553 // don't handle interrupt if network interface has not been configured 00554 if ( rtl_net_if_id == NIP_NET_NO_IF ) return; 00555 00556 // read Interrupt Status Register (ISR) 00557 isr = ReadRTL(RTL_ISR); 00558 00559 // check receive buffer overwrite 00560 if ( isr & RTL_ISR_OVW ) 00561 { 00562 /// @todo Handle overwrites according to developer guide 00563 NIP_PHY_LOG_OVW( rtl_net_if ); 00564 } 00565 00566 // check for receive errors 00567 if ( isr & RTL_ISR_RXE ) NIP_PHY_LOG_RXE( rtl_net_if ); 00568 00569 // check for transmit errors 00570 if ( isr & RTL_ISR_TXE ) NIP_PHY_LOG_TXE( rtl_net_if ); 00571 00572 // check for reset interrupt 00573 if ( isr & RTL_ISR_RST ) 00574 { 00575 // TODO do something? 00576 } 00577 00578 // check for packet reception 00579 if ( isr & RTL_ISR_PRX ) 00580 { 00581 // notify dispatcher and execute if not already running 00582 nip_disp_notify_if( rtl_net_if_id, NIP_DISP_IF_ETH_R ); 00583 // nip_dispatcher( ); 00584 } 00585 00586 00587 //Zuruecksetzen der Interrupt Bits des NIC 00588 RTL_CLEAR_ISR(); 00589 00590 } 00591 00592 #endif /* RTL_INTERRUPT*/ 00593 00594 00595 //############################################################################ 00596 // Schreibt ein Byte in ein angegebenes Register der Netzwerkkarte 00597 void WriteRTL (unsigned char rtl_addr,unsigned char rtl_data) 00598 //############################################################################ 00599 { 00600 //Der Datenport wird auf output gesetzt vom IC zum NIC schreiben 00601 DATA_CTRL_RLT = OUTPUT; 00602 //write Adress to Port 00603 ADDR_PORT_RLT = rtl_addr; 00604 //write Data to Port 00605 DATA_PORT_RLT_WRITE = rtl_data; 00606 //set write Pin to Low 00607 RTL_WR_OFF(); 00608 //wait a short time 00609 nop(); //gib mal ein bisschen GAS Ulrich ;) 00610 nop(); 00611 00612 //set write Pin to High 00613 RTL_WR_ON(); 00614 //write to RTL complete 00615 } 00616 00617 00618 //############################################################################ 00619 // Auslesen eines Byte von einen angegebenes Register der Netzwerkkarte 00620 unsigned char ReadRTL (unsigned char rtl_addr) 00621 //############################################################################ 00622 { 00623 unsigned char rtl_data; 00624 //Der Datenport wir auf input gesetzt vom NIC zum IC lesen 00625 DATA_CTRL_RLT = INPUT; 00626 //write Adress to Port 00627 ADDR_PORT_RLT = rtl_addr; 00628 //set read Pin to Low 00629 RTL_RD_OFF(); 00630 //wait a short time 00631 nop(); 00632 nop(); 00633 00634 //read from port rtldata 00635 rtl_data = DATA_PORT_RLT_READ; 00636 //set Read Pin to High 00637 RTL_RD_ON(); 00638 //read from RTL complete 00639 return (rtl_data); 00640 } 00641 00642 00643 /* 00644 //############################################################################ 00645 void Write_Ethernet_Terminate (unsigned int bufferlen) 00646 //############################################################################ 00647 { 00648 #if DEBUG_CALLS 00649 print("---- Write_Ethernet_Terminate --------------------\n"); 00650 #endif 00651 00652 #if DEBUG_NIC 00653 printf("Padding: %d Bytes", 00654 bufferlen<RTL_ETHER_MIN_SIZE ? RTL_ETHER_MIN_SIZE-bufferlen : 0); 00655 #endif 00656 00657 unsigned char ctr; 00658 if (bufferlen < RTL_ETHER_MIN_SIZE) 00659 { 00660 for (ctr = bufferlen; ctr < RTL_ETHER_MIN_SIZE; ctr++){ 00661 //write Data to Port 00662 DATA_PORT_RLT_WRITE = 0x00; 00663 #if DEBUG_NIC && DEBUG_VERBOSE 00664 printf("__"); 00665 #endif 00666 //set write Pin to Low 00667 RTL_WR_OFF(); 00668 //wait a short time 00669 nop(); //gib mal ein bisschen GAS Ulrich ;) Holgi 00670 nop(); 00671 00672 //set write Pin to High 00673 RTL_WR_ON(); 00674 //write to RTL complete 00675 } 00676 } 00677 #if DEBUG_NIC 00678 print(".\n"); 00679 #endif 00680 00681 //loop_until_bit_is_set(ReadRTL(isr),rdc); 00682 while ((ReadRTL(RTL_ISR) & RTL_ISR_RDC) == 0) {} 00683 00684 if (bufferlen<RTL_ETHER_MIN_SIZE) bufferlen = RTL_ETHER_MIN_SIZE; 00685 00686 WriteRTL (RTL_TBCR0,(bufferlen & 0x00ff)); 00687 WriteRTL (RTL_TBCR1,(bufferlen & 0xff00) >>8); 00688 WriteRTL (RTL_CR,( RTL_CR_TRANSMIT_PACKET | RTL_CR_RD_ABORT_CMPLTE )); 00689 00690 00691 00692 //Globale Interrupts einschalten 00693 // sei(); 00694 } 00695 */ 00696 00697 /* 00698 //############################################################################ 00699 void Read_Ethernet_Terminate (unsigned int count) 00700 //############################################################################ 00701 00702 { 00703 #if DEBUG_CALLS 00704 print("---- Read_Ethernet_Terminate ---------------------\n"); 00705 #endif 00706 unsigned int ctr; 00707 unsigned char tmp = 0; 00708 #if DEBUG_NIC 00709 printf("Drop remaining %d Bytes and terminate reading.\n",count); 00710 #endif 00711 00712 for(ctr=0; ctr<(count+RTL_ETHER_TRAILER_SIZE); ctr++) 00713 { 00714 00715 //set read Pin to Low 00716 RTL_RD_OFF(); 00717 //wait a short time 00718 nop(); 00719 nop(); 00720 //read from port rtldata 00721 tmp = DATA_PORT_RLT_READ; 00722 //set Read Pin to High 00723 RTL_RD_ON(); 00724 //read from RTL complete 00725 00726 #if DEBUG_NIC && DEBUG_VERBOSE 00727 printf("%02x", tmp); 00728 #endif 00729 00730 } 00731 #if DEBUG_NIC && DEBUG_VERBOSE 00732 print("\n"); 00733 #endif 00734 00735 tmp = tmp & RTL_ISR_RDC; 00736 00737 if ( tmp != 64 ) 00738 { 00739 ReadRTL(RTL_ISR); 00740 } 00741 00742 }*/ 00743 00744 #endif /* (NIP_RTL_ENABLE == 1) */