Contiki 2.6
|
00001 #include "rtl8019.h" 00002 #include "debug.h" 00003 #include "avr/pgmspace.h" 00004 #include "rtlregs.h" 00005 00006 #ifndef cbi 00007 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 00008 #endif 00009 #ifndef sbi 00010 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 00011 #endif 00012 00013 #define outp(val, port) do { (port) = (val); } while(0) 00014 #define inp(port) (port) 00015 00016 /***************************************************************************** 00017 * Module Name: Realtek 8019AS Driver 00018 * 00019 * Created By: Louis Beaudoin (www.embedded-creations.com) 00020 * 00021 * Original Release: September 21, 2002 00022 * 00023 * Module Description: 00024 * Provides functions to initialize the Realtek 8019AS, and send and retreive 00025 * packets 00026 * 00027 * November 15, 2002 - Louis Beaudoin 00028 * processRTL8019Interrupt() - bit mask mistake fixed 00029 * 00030 * September 30, 2002 - Louis Beaudoin 00031 * Receive functions modified to handle errors encountered when receiving a 00032 * fast data stream. Functions now manually retreive data instead of 00033 * using the send packet command. Interface improved by checking for 00034 * overruns and data in the buffer internally. 00035 * Corrected the overrun function - overrun flag was not reset after overrun 00036 * Added support for the Imagecraft Compiler 00037 * Added support to communicate with the NIC using general I/O ports 00038 * March 10, 2012 - David Kopf 00039 * Use contiki clock_delay_usec call. 00040 * 00041 *****************************************************************************/ 00042 00043 00044 /***************************************************************************** 00045 * writeRTL( RTL_ADDRESS, RTL_DATA ) 00046 * Args: 1. unsigned char RTL_ADDRESS - register offset of RTL register 00047 * 2. unsigned char RTL_DATA - data to write to register 00048 * Created By: Louis Beaudoin 00049 * Date: September 21, 2002 00050 * Description: Writes byte to RTL8019 register. 00051 * 00052 * Notes - If using the External SRAM Interface, performs a write to 00053 * address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8) 00054 * The address is sent in the non-multiplxed upper address port so 00055 * no latch is required. 00056 * 00057 * If using general I/O ports, the data port is left in the input 00058 * state with pullups enabled 00059 * 00060 *****************************************************************************/ 00061 #if MEMORY_MAPPED_NIC == 1 00062 /*#define writeRTL(RTL_ADDRESS,RTL_DATA) do{ *(volatile unsigned char *) \ 00063 (MEMORY_MAPPED_RTL8019_OFFSET \ 00064 + (((unsigned char)(RTL_ADDRESS)) << 8)) = \ 00065 (unsigned char)(RTL_DATA); } while(0)*/ 00066 #define writeRTL nic_write 00067 #else 00068 00069 00070 void writeRTL(unsigned char address, unsigned char data) 00071 { 00072 // put the address and data in the port registers - data port is output 00073 outp( address, RTL8019_ADDRESS_PORT ); 00074 outp( 0xFF, RTL8019_DATA_DDR ); 00075 outp( data, RTL8019_DATA_PORT ); 00076 00077 // toggle write pin 00078 RTL8019_CLEAR_WRITE; 00079 RTL8019_SET_WRITE; 00080 00081 // set data port back to input with pullups enabled 00082 outp( 0x00, RTL8019_DATA_DDR ); 00083 outp( 0xFF, RTL8019_DATA_PORT ); 00084 } 00085 00086 00087 00088 #endif 00089 void 00090 delay_msec(uint16_t howlong) 00091 { 00092 #if F_CPU>=16000000 00093 while(howlong--) clock_delay_usec(1000); 00094 #elif F_CPU>=8000000 00095 uint16_t i=996; 00096 while(howlong--) {clock_delay_usec(i);i=999;} 00097 #elif F_CPU>=4000000 00098 uint16_t i=992; 00099 while(howlong--) {clock_delay_usec(i);i=999;} 00100 #elif F_CPU>=2000000 00101 uint16_t i=989; 00102 while(howlong--) {clock_delay_usec(i);i=999;} 00103 #else 00104 uint16_t i=983; 00105 while(howlong--) {clock_delay_usec(i);i=999;} 00106 #endif 00107 } 00108 /***************************************************************************** 00109 * readRTL(RTL_ADDRESS) 00110 * Args: unsigned char RTL_ADDRESS - register offset of RTL register 00111 * Created By: Louis Beaudoin 00112 * Date: September 21, 2002 00113 * Description: Reads byte from RTL8019 register 00114 * 00115 * Notes - If using the External SRAM Interface, performs a read from 00116 * address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8) 00117 * The address is sent in the non-multiplxed upper address port so 00118 * no latch is required. 00119 * 00120 * If using general I/O ports, the data port is assumed to already be 00121 * an input, and is left as an input port when done 00122 * 00123 *****************************************************************************/ 00124 #if MEMORY_MAPPED_NIC == 1 00125 /*#define readRTL(RTL_ADDRESS) (*(volatile unsigned char *) \ 00126 (MEMORY_MAPPED_RTL8019_OFFSET \ 00127 + (((unsigned char)(RTL_ADDRESS)) << 8)) )*/ 00128 #define readRTL nic_read 00129 #else 00130 00131 unsigned char readRTL(unsigned char address) 00132 { 00133 unsigned char byte; 00134 00135 // drive the read address 00136 outp( address, RTL8019_ADDRESS_PORT ); 00137 00138 //nop(); 00139 00140 // assert read 00141 RTL8019_CLEAR_READ; 00142 nop(); 00143 00144 // read in the data 00145 byte = inp( RTL8019_DATA_PIN ); 00146 00147 // negate read 00148 RTL8019_SET_READ; 00149 00150 return byte; 00151 } 00152 00153 #endif 00154 00155 00156 00157 /***************************************************************************** 00158 * RTL8019setupPorts(void); 00159 * 00160 * Created By: Louis Beaudoin 00161 * Date: September 21, 2002 00162 * Description: Sets up the ports used for communication with the RTL8019 NIC 00163 * (data bus, address bus, read, write, and reset) 00164 *****************************************************************************/ 00165 void RTL8019setupPorts(void) 00166 { 00167 volatile unsigned char *base = (unsigned char *)0x8300; 00168 00169 #if MEMORY_MAPPED_NIC == 1 00170 // enable external SRAM interface - no wait states 00171 outp(inp(MCUCR) | (1<<SRE), MCUCR); 00172 00173 #else 00174 00175 // make the address port output 00176 outp( 0xFF, RTL8019_ADDRESS_DDR ); 00177 00178 // make the data port input with pull-ups 00179 outp( 0xFF, RTL8019_DATA_PORT ); 00180 00181 // make the control port read and write pins outputs and asserted 00182 //outp( inp(RTL8019_CONTROL_DDR) | (1<<RTL8019_CONTROL_READPIN) | 00183 // (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_DDR ); 00184 sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_READPIN ); 00185 sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_WRITEPIN ); 00186 00187 //outp( inp(RTL8019_CONTROL_PORT) | (1<<RTL8019_CONTROL_READPIN) | 00188 // (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_PORT ); 00189 sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_READPIN ); 00190 sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_WRITEPIN ); 00191 00192 #endif 00193 00194 // enable output pin for Resetting the RTL8019 00195 sbi( RTL8019_RESET_DDR, RTL8019_RESET_PIN ); 00196 00197 00198 00199 00200 00201 } 00202 00203 00204 00205 /***************************************************************************** 00206 * HARD_RESET_RTL8019() 00207 * 00208 * Created By: Louis Beaudoin 00209 * Date: September 21, 2002 00210 * Description: Simply toggles the pin that resets the NIC 00211 *****************************************************************************/ 00212 /*#define HARD_RESET_RTL8019() do{ sbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN); \ 00213 delay_msec(10); \ 00214 cbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN);} \ 00215 while(0)*/ 00216 00217 00218 00219 /***************************************************************************** 00220 * overrun(void); 00221 * 00222 * Created By: Louis Beaudoin 00223 * Date: September 21, 2002 00224 * Description: "Canned" receive buffer overrun function originally from 00225 * a National Semiconductor appnote 00226 * Notes: This function must be called before retreiving packets from 00227 * the NIC if there is a buffer overrun 00228 *****************************************************************************/ 00229 void overrun(void); 00230 00231 00232 00233 00234 //****************************************************************** 00235 //* REALTEK CONTROL REGISTER OFFSETS 00236 //* All offsets in Page 0 unless otherwise specified 00237 //* All functions accessing CR must leave CR in page 0 upon exit 00238 //****************************************************************** 00239 #define CR 0x00 00240 #define PSTART 0x01 00241 #define PAR0 0x01 // Page 1 00242 #define CR9346 0x01 // Page 3 00243 #define PSTOP 0x02 00244 #define BNRY 0x03 00245 #define TSR 0x04 00246 #define TPSR 0x04 00247 #define TBCR0 0x05 00248 #define NCR 0x05 00249 #define TBCR1 0x06 00250 #define ISR 0x07 00251 #define CURR 0x07 // Page 1 00252 #define RSAR0 0x08 00253 #define CRDA0 0x08 00254 #define RSAR1 0x09 00255 #define CRDA1 0x09 00256 #define RBCR0 0x0A 00257 #define RBCR1 0x0B 00258 #define RSR 0x0C 00259 #define RCR 0x0C 00260 #define TCR 0x0D 00261 #define CNTR0 0x0D 00262 #define DCR 0x0E 00263 #define CNTR1 0x0E 00264 #define IMR 0x0F 00265 #define CNTR2 0x0F 00266 #define RDMAPORT 0x10 00267 #define RSTPORT 0x18 00268 00269 00270 /***************************************************************************** 00271 * 00272 * RTL ISR Register Bits 00273 * 00274 *****************************************************************************/ 00275 #define ISR_RST 7 00276 #define ISR_OVW 4 00277 #define ISR_PRX 0 00278 #define ISR_RDC 6 00279 #define ISR_PTX 1 00280 00281 00282 /***************************************************************************** 00283 * 00284 * RTL Register Initialization Values 00285 * 00286 *****************************************************************************/ 00287 // RCR : accept broadcast packets and packets destined to this MAC 00288 // drop short frames and receive errors 00289 #define RCR_INIT 0x04 00290 00291 // TCR : default transmit operation - CRC is generated 00292 #define TCR_INIT 0x00 00293 00294 // DCR : allows send packet to be used for packet retreival 00295 // FIFO threshold: 8-bits (works) 00296 // 8-bit transfer mode 00297 #define DCR_INIT 0x58 00298 00299 // IMR : interrupt enabled for receive and overrun events 00300 #define IMR_INIT 0x11 00301 00302 // buffer boundaries - transmit has 6 256-byte pages 00303 // receive has 26 256-byte pages 00304 // entire available packet buffer space is allocated 00305 #define TXSTART_INIT 0x40 00306 #define RXSTART_INIT 0x46 00307 #define RXSTOP_INIT 0x60 00308 00309 00310 00311 void RTL8019beginPacketSend(unsigned int packetLength) 00312 { 00313 00314 volatile unsigned char *base = (unsigned char *)0x8300; 00315 unsigned int sendPacketLength; 00316 sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH) ? 00317 packetLength : ETHERNET_MIN_PACKET_LENGTH ; 00318 00319 //start the NIC 00320 writeRTL(CR,0x22); 00321 00322 // still transmitting a packet - wait for it to finish 00323 while( readRTL(CR) & 0x04 ); 00324 00325 //load beginning page for transmit buffer 00326 writeRTL(TPSR,TXSTART_INIT); 00327 00328 //set start address for remote DMA operation 00329 writeRTL(RSAR0,0x00); 00330 writeRTL(RSAR1,0x40); 00331 00332 //clear the packet stored interrupt 00333 writeRTL(ISR,(1<<ISR_PTX)); 00334 00335 //load data byte count for remote DMA 00336 writeRTL(RBCR0, (unsigned char)(packetLength)); 00337 writeRTL(RBCR1, (unsigned char)(packetLength>>8)); 00338 00339 writeRTL(TBCR0, (unsigned char)(sendPacketLength)); 00340 writeRTL(TBCR1, (unsigned char)((sendPacketLength)>>8)); 00341 00342 //do remote write operation 00343 writeRTL(CR,0x12); 00344 } 00345 00346 00347 00348 void RTL8019sendPacketData(unsigned char * localBuffer, unsigned int length) 00349 { 00350 unsigned int i; 00351 volatile unsigned char *base = (unsigned char *)0x8300; 00352 for(i=0;i<length;i++) 00353 writeRTL(RDMAPORT, localBuffer[i]); 00354 } 00355 00356 00357 00358 void RTL8019endPacketSend(void) 00359 { 00360 volatile unsigned char *base = (unsigned char *)0x8300; 00361 //send the contents of the transmit buffer onto the network 00362 writeRTL(CR,0x24); 00363 00364 // clear the remote DMA interrupt 00365 writeRTL(ISR, (1<<ISR_RDC)); 00366 } 00367 00368 00369 00370 00371 // pointers to locations in the RTL8019 receive buffer 00372 static unsigned char nextPage; 00373 static unsigned int currentRetreiveAddress; 00374 00375 // location of items in the RTL8019's page header 00376 #define enetpacketstatus 0x00 00377 #define nextblock_ptr 0x01 00378 #define enetpacketLenL 0x02 00379 #define enetpacketLenH 0x03 00380 00381 00382 00383 unsigned int RTL8019beginPacketRetreive(void) 00384 { 00385 volatile unsigned char *base = (unsigned char *)0x8300; 00386 unsigned char i; 00387 unsigned char bnry; 00388 00389 unsigned char pageheader[4]; 00390 unsigned int rxlen; 00391 00392 // check for and handle an overflow 00393 processRTL8019Interrupt(); 00394 00395 // read CURR from page 1 00396 writeRTL(CR,0x62); 00397 i = readRTL(CURR); 00398 00399 // return to page 0 00400 writeRTL(CR,0x22); 00401 00402 // read the boundary register - pointing to the beginning of the packet 00403 bnry = readRTL(BNRY) ; 00404 00405 /* debug_print(PSTR("bnry: ")); 00406 debug_print8(bnry);*/ 00407 00408 /* debug_print(PSTR("RXSTOP_INIT: ")); 00409 debug_print8(RXSTOP_INIT); 00410 debug_print(PSTR("RXSTART_INIT: ")); 00411 debug_print8(RXSTART_INIT);*/ 00412 // return if there is no packet in the buffer 00413 if( bnry == i ) { 00414 return 0; 00415 } 00416 00417 00418 // clear the packet received interrupt flag 00419 writeRTL(ISR, (1<<ISR_PRX)); 00420 00421 00422 // the boundary pointer is invalid, reset the contents of the buffer and exit 00423 if( (bnry >= RXSTOP_INIT) || (bnry < RXSTART_INIT) ) 00424 { 00425 writeRTL(BNRY, RXSTART_INIT); 00426 writeRTL(CR, 0x62); 00427 writeRTL(CURR, RXSTART_INIT); 00428 writeRTL(CR, 0x22); 00429 return 0; 00430 } 00431 00432 // initiate DMA to transfer the RTL8019 packet header 00433 writeRTL(RBCR0, 4); 00434 writeRTL(RBCR1, 0); 00435 writeRTL(RSAR0, 0); 00436 writeRTL(RSAR1, bnry); 00437 writeRTL(CR, 0x0A); 00438 /* debug_print(PSTR("Page header: "));*/ 00439 00440 for(i=0;i<4;i++) { 00441 pageheader[i] = readRTL(RDMAPORT); 00442 /* debug_print8(pageheader[i]);*/ 00443 } 00444 00445 // end the DMA operation 00446 writeRTL(CR, 0x22); 00447 for(i = 0; i <= 20; i++) { 00448 if(readRTL(ISR) & 1<<6) { 00449 break; 00450 } 00451 } 00452 writeRTL(ISR, 1<<6); 00453 00454 00455 00456 rxlen = (pageheader[enetpacketLenH]<<8) + pageheader[enetpacketLenL]; 00457 nextPage = pageheader[nextblock_ptr] ; 00458 00459 currentRetreiveAddress = (bnry<<8) + 4; 00460 00461 /* debug_print(PSTR("nextPage: ")); 00462 debug_print8(nextPage);*/ 00463 00464 // if the nextPage pointer is invalid, the packet is not ready yet - exit 00465 if( (nextPage >= RXSTOP_INIT) || (nextPage < RXSTART_INIT) ) { 00466 /* UDR0 = '0';*/ 00467 return 0; 00468 } 00469 00470 return rxlen-4; 00471 } 00472 00473 00474 void RTL8019retreivePacketData(unsigned char * localBuffer, unsigned int length) 00475 { 00476 unsigned int i; 00477 volatile unsigned char *base = (unsigned char *)0x8300; 00478 // initiate DMA to transfer the data 00479 writeRTL(RBCR0, (unsigned char)length); 00480 writeRTL(RBCR1, (unsigned char)(length>>8)); 00481 writeRTL(RSAR0, (unsigned char)currentRetreiveAddress); 00482 writeRTL(RSAR1, (unsigned char)(currentRetreiveAddress>>8)); 00483 writeRTL(CR, 0x0A); 00484 for(i=0;i<length;i++) 00485 localBuffer[i] = readRTL(RDMAPORT); 00486 00487 // end the DMA operation 00488 writeRTL(CR, 0x22); 00489 for(i = 0; i <= 20; i++) 00490 if(readRTL(ISR) & 1<<6) 00491 break; 00492 writeRTL(ISR, 1<<6); 00493 00494 currentRetreiveAddress += length; 00495 if( currentRetreiveAddress >= 0x6000 ) 00496 currentRetreiveAddress = currentRetreiveAddress - (0x6000-0x4600) ; 00497 } 00498 00499 00500 00501 void RTL8019endPacketRetreive(void) 00502 { 00503 volatile unsigned char *base = (unsigned char *)0x8300; 00504 unsigned char i; 00505 00506 // end the DMA operation 00507 writeRTL(CR, 0x22); 00508 for(i = 0; i <= 20; i++) 00509 if(readRTL(ISR) & 1<<6) 00510 break; 00511 writeRTL(ISR, 1<<6); 00512 00513 // set the boundary register to point to the start of the next packet 00514 writeRTL(BNRY, nextPage); 00515 } 00516 00517 00518 void overrun(void) 00519 { 00520 volatile unsigned char *base = (unsigned char *)0x8300; 00521 unsigned char data_L, resend; 00522 00523 data_L = readRTL(CR); 00524 writeRTL(CR, 0x21); 00525 delay_msec(2); 00526 writeRTL(RBCR0, 0x00); 00527 writeRTL(RBCR1, 0x00); 00528 if(!(data_L & 0x04)) 00529 resend = 0; 00530 else if(data_L & 0x04) 00531 { 00532 data_L = readRTL(ISR); 00533 if((data_L & 0x02) || (data_L & 0x08)) 00534 resend = 0; 00535 else 00536 resend = 1; 00537 } 00538 00539 writeRTL(TCR, 0x02); 00540 writeRTL(CR, 0x22); 00541 writeRTL(BNRY, RXSTART_INIT); 00542 writeRTL(CR, 0x62); 00543 writeRTL(CURR, RXSTART_INIT); 00544 writeRTL(CR, 0x22); 00545 writeRTL(ISR, 0x10); 00546 writeRTL(TCR, TCR_INIT); 00547 00548 writeRTL(ISR, 0xFF); 00549 } 00550 00551 00552 00553 00554 /*! 00555 * \brief Size of a single ring buffer page. 00556 */ 00557 #define NIC_PAGE_SIZE 0x100 00558 00559 /*! 00560 * \brief First ring buffer page address. 00561 */ 00562 #define NIC_START_PAGE 0x40 00563 00564 /*! 00565 * \brief Last ring buffer page address plus 1. 00566 */ 00567 #define NIC_STOP_PAGE 0x60 00568 00569 /*! 00570 * \brief Number of pages in a single transmit buffer. 00571 * 00572 * This should be at least the MTU size. 00573 */ 00574 #define NIC_TX_PAGES 6 00575 00576 /*! 00577 * \brief Number of transmit buffers. 00578 */ 00579 #define NIC_TX_BUFFERS 2 00580 00581 /*! 00582 * \brief Controller memory layout: 00583 * 00584 * 0x4000 - 0x4bff 3k bytes transmit buffer 00585 * 0x4c00 - 0x5fff 5k bytes receive buffer 00586 */ 00587 #define NIC_FIRST_TX_PAGE NIC_START_PAGE 00588 #define NIC_FIRST_RX_PAGE (NIC_FIRST_TX_PAGE + NIC_TX_PAGES * NIC_TX_BUFFERS) 00589 00590 /*! 00591 * \brief Standard sizing information 00592 */ 00593 #define TX_PAGES 12 /* Allow for 2 back-to-back frames */ 00594 00595 static unsigned char mac[6] = {0x00,0x06,0x98,0x01,0x02,0x29}; 00596 void Delay(long nops) 00597 { 00598 volatile long i; 00599 00600 for(i = 0; i < nops; i++) 00601 #ifdef __IMAGECRAFT__ 00602 asm("nop\n"); 00603 #else 00604 asm volatile("nop\n\t"::); 00605 #endif 00606 } 00607 00608 static int NicReset(void) 00609 { 00610 volatile unsigned char *base = (unsigned char *)0x8300; 00611 unsigned char i; 00612 unsigned char j; 00613 00614 for(j = 0; j < 20; j++) { 00615 debug_print(PSTR("SW-Reset...")); 00616 i = nic_read(NIC_RESET); 00617 Delay(500); 00618 nic_write(NIC_RESET, i); 00619 for(i = 0; i < 20; i++) { 00620 Delay(5000); 00621 00622 /* 00623 * ID detection added for version 1.1 boards. 00624 */ 00625 if((nic_read(NIC_PG0_ISR) & NIC_ISR_RST) != 0 && 00626 nic_read(NIC_PG0_RBCR0) == 0x50 && 00627 nic_read(NIC_PG0_RBCR1) == 0x70) { 00628 debug_print(PSTR("OK\r\n")); 00629 return 0; 00630 } 00631 } 00632 debug_print(PSTR("failed\r\n\x07")); 00633 00634 /* 00635 * Toggle the hardware reset line. Since Ethernut version 1.3 the 00636 * hardware reset pin of the nic is no longer connected to bit 4 00637 * on port E, but wired to the board reset line. 00638 */ 00639 if(j == 10) { 00640 debug_print(PSTR("Ethernut 1.1 HW-Reset\r\n")); 00641 sbi(DDRE, 4); 00642 sbi(PORTE, 4); 00643 Delay(100000); 00644 cbi(PORTE, 4); 00645 Delay(250000); 00646 } 00647 } 00648 return -1; 00649 } 00650 00651 void initRTL8019(void) 00652 { 00653 unsigned char i, rb; 00654 volatile unsigned char *base = (unsigned char *)0x8300; 00655 00656 RTL8019setupPorts(); 00657 00658 /*#define nic_write writeRTL 00659 #define nic_read readRTL*/ 00660 /* 00661 * Disable NIC interrupts. 00662 */ 00663 cbi(EIMSK, INT5); 00664 00665 /* if(NicReset(base)) 00666 return -1;*/ 00667 #if 0 00668 /* 00669 * Mask all interrupts and clear any interrupt status flag to set the 00670 * INT pin back to low. 00671 */ 00672 nic_write(NIC_PG0_IMR, 0); 00673 nic_write(NIC_PG0_ISR, 0xff); 00674 00675 /* 00676 * During reset the nic loaded its initial configuration from an 00677 * external eeprom. On the ethernut board we do not have any 00678 * configuration eeprom, but simply tied the eeprom data line to 00679 * high level. So we have to clear some bits in the configuration 00680 * register. Switch to register page 3. 00681 */ 00682 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); 00683 00684 /* 00685 * The nic configuration registers are write protected unless both 00686 * EEM bits are set to 1. 00687 */ 00688 nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); 00689 00690 /* 00691 * Disable sleep and power down. 00692 */ 00693 nic_write(NIC_PG3_CONFIG3, 0); 00694 00695 /* 00696 * Network media had been set to 10Base2 by the virtual EEPROM and 00697 * will be set now to auto detect. This will initiate a link test. 00698 * We don't force 10BaseT, because this would disable the link test. 00699 */ 00700 nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); 00701 00702 /* 00703 * Reenable write protection of the nic configuration registers 00704 * and wait for link test to complete. 00705 */ 00706 nic_write(NIC_PG3_EECR, 0); 00707 /* NutSleep(WAIT500);*/ 00708 00709 delay_msec(500); 00710 00711 00712 00713 00714 /* 00715 * Switch to register page 0 and set data configuration register 00716 * to byte-wide DMA transfers, normal operation (no loopback), 00717 * send command not executed and 8 byte fifo threshold. 00718 */ 00719 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); 00720 nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); 00721 00722 /* 00723 * Clear remote dma byte count register. 00724 */ 00725 nic_write(NIC_PG0_RBCR0, 0); 00726 nic_write(NIC_PG0_RBCR1, 0); 00727 00728 /* 00729 * Temporarily set receiver to monitor mode and transmitter to 00730 * internal loopback mode. Incoming packets will not be stored 00731 * in the nic ring buffer and no data will be send to the network. 00732 */ 00733 nic_write(NIC_PG0_RCR, NIC_RCR_MON); 00734 nic_write(NIC_PG0_TCR, NIC_TCR_LB0); 00735 00736 /* 00737 * Configure the nic's ring buffer page layout. 00738 * NIC_PG0_BNRY: Last page read. 00739 * NIC_PG0_PSTART: First page of receiver buffer. 00740 * NIC_PG0_PSTOP: Last page of receiver buffer. 00741 */ 00742 nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); 00743 nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); 00744 nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); 00745 nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); 00746 00747 /* 00748 * Once again clear interrupt status register. 00749 */ 00750 nic_write(NIC_PG0_ISR, 0xff); 00751 00752 /* 00753 * Switch to register page 1 and copy our MAC address into the nic. 00754 * We are still in stop mode. 00755 */ 00756 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); 00757 for(i = 0; i < 6; i++) 00758 nic_write(NIC_PG1_PAR0 + i, mac[i]); 00759 00760 /* 00761 * Clear multicast filter bits to disable all packets. 00762 */ 00763 for(i = 0; i < 8; i++) 00764 nic_write(NIC_PG1_MAR0 + i, 0); 00765 00766 /* 00767 * Set current page pointer to one page after the boundary pointer. 00768 */ 00769 nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); 00770 00771 /* 00772 * Switch back to register page 0, remaining in stop mode. 00773 */ 00774 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); 00775 00776 /* 00777 * Take receiver out of monitor mode and enable it for accepting 00778 * broadcasts. 00779 */ 00780 nic_write(NIC_PG0_RCR, NIC_RCR_AB); 00781 00782 /* 00783 * Clear all interrupt status flags and enable interrupts. 00784 */ 00785 nic_write(NIC_PG0_ISR, 0xff); 00786 nic_write(NIC_PG0_IMR, NIC_IMR_PRXE | NIC_IMR_PTXE | NIC_IMR_RXEE | 00787 NIC_IMR_TXEE | NIC_IMR_OVWE); 00788 00789 /* 00790 * Fire up the nic by clearing the stop bit and setting the start bit. 00791 * To activate the local receive dma we must also take the nic out of 00792 * the local loopback mode. 00793 */ 00794 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); 00795 nic_write(NIC_PG0_TCR, 0); 00796 00797 /* NutSleep(WAIT500);*/ 00798 delay_msec(500); 00799 00800 00801 00802 00803 00804 #endif /* 0 */ 00805 00806 NicReset(); 00807 00808 debug_print(PSTR("Init controller...")); 00809 nic_write(NIC_PG0_IMR, 0); 00810 nic_write(NIC_PG0_ISR, 0xff); 00811 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); 00812 nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); 00813 nic_write(NIC_PG3_CONFIG3, 0); 00814 nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); 00815 nic_write(NIC_PG3_EECR, 0); 00816 /* Delay(50000);*/ 00817 delay_msec(2000); 00818 00819 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); 00820 nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); 00821 nic_write(NIC_PG0_RBCR0, 0); 00822 nic_write(NIC_PG0_RBCR1, 0); 00823 nic_write(NIC_PG0_RCR, NIC_RCR_MON); 00824 nic_write(NIC_PG0_TCR, NIC_TCR_LB0); 00825 nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); 00826 nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); 00827 nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); 00828 nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); 00829 nic_write(NIC_PG0_ISR, 0xff); 00830 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); 00831 for(i = 0; i < 6; i++) 00832 nic_write(NIC_PG1_PAR0 + i, mac[i]); 00833 for(i = 0; i < 8; i++) 00834 nic_write(NIC_PG1_MAR0 + i, 0); 00835 nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); 00836 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); 00837 nic_write(NIC_PG0_RCR, NIC_RCR_AB); 00838 nic_write(NIC_PG0_ISR, 0xff); 00839 nic_write(NIC_PG0_IMR, 0); 00840 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); 00841 nic_write(NIC_PG0_TCR, 0); 00842 /* Delay(1000000)*/ 00843 delay_msec(2000); 00844 00845 00846 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); 00847 rb = nic_read(NIC_PG3_CONFIG0); 00848 debug_print8(rb); 00849 switch(rb & 0xC0) { 00850 case 0x00: 00851 debug_print(PSTR("RTL8019AS ")); 00852 if(rb & 0x08) 00853 debug_print(PSTR("jumper mode: ")); 00854 if(rb & 0x20) 00855 debug_print(PSTR("AUI ")); 00856 if(rb & 0x10) 00857 debug_print(PSTR("PNP ")); 00858 break; 00859 case 0xC0: 00860 debug_print(PSTR("RTL8019 ")); 00861 if(rb & 0x08) 00862 debug_print(PSTR("jumper mode: ")); 00863 break; 00864 default: 00865 debug_print(PSTR("Unknown chip ")); 00866 debug_print8(rb); 00867 break; 00868 } 00869 if(rb & 0x04) 00870 debug_print(PSTR("BNC\x07 ")); 00871 if(rb & 0x03) 00872 debug_print(PSTR("Failed\x07 ")); 00873 00874 /* rb = nic_read(NIC_PG3_CONFIG1); 00875 debug_print8(rb);*/ 00876 /* NutPrintFormat(0, "IRQ%u ", (rb >> 4) & 7);*/ 00877 /* debug_print("IRQ "); 00878 debug_print8((rb >> 4) & 7);*/ 00879 00880 rb = nic_read(NIC_PG3_CONFIG2); 00881 debug_print8(rb); 00882 switch(rb & 0xC0) { 00883 case 0x00: 00884 debug_print(PSTR("Auto ")); 00885 break; 00886 case 0x40: 00887 debug_print(PSTR("10BaseT ")); 00888 break; 00889 case 0x80: 00890 debug_print(PSTR("10Base5 ")); 00891 break; 00892 case 0xC0: 00893 debug_print(PSTR("10Base2 ")); 00894 break; 00895 } 00896 00897 00898 return; 00899 00900 /* HARD_RESET_RTL8019();*/ 00901 00902 // do soft reset 00903 writeRTL( ISR, readRTL(ISR) ) ; 00904 delay_msec(50); 00905 00906 writeRTL(CR,0x21); // stop the NIC, abort DMA, page 0 00907 delay_msec(2); // make sure nothing is coming in or going out 00908 writeRTL(DCR, DCR_INIT); // 0x58 00909 writeRTL(RBCR0,0x00); 00910 writeRTL(RBCR1,0x00); 00911 writeRTL(RCR,0x04); 00912 writeRTL(TPSR, TXSTART_INIT); 00913 writeRTL(TCR,0x02); 00914 writeRTL(PSTART, RXSTART_INIT); 00915 writeRTL(BNRY, RXSTART_INIT); 00916 writeRTL(PSTOP, RXSTOP_INIT); 00917 writeRTL(CR, 0x61); 00918 delay_msec(2); 00919 writeRTL(CURR, RXSTART_INIT); 00920 00921 writeRTL(PAR0+0, MYMAC_0); 00922 writeRTL(PAR0+1, MYMAC_1); 00923 writeRTL(PAR0+2, MYMAC_2); 00924 writeRTL(PAR0+3, MYMAC_3); 00925 writeRTL(PAR0+4, MYMAC_4); 00926 writeRTL(PAR0+5, MYMAC_5); 00927 00928 writeRTL(CR,0x21); 00929 writeRTL(DCR, DCR_INIT); 00930 writeRTL(CR,0x22); 00931 writeRTL(ISR,0xFF); 00932 writeRTL(IMR, IMR_INIT); 00933 writeRTL(TCR, TCR_INIT); 00934 00935 writeRTL(CR, 0x22); // start the NIC 00936 } 00937 00938 00939 void processRTL8019Interrupt(void) 00940 { 00941 volatile unsigned char *base = (unsigned char *)0x8300; 00942 unsigned char byte = readRTL(ISR); 00943 00944 if( byte & (1<<ISR_OVW) ) 00945 overrun(); 00946 00947 } 00948 00949 /* 00950 unsigned char RTL8019ReceiveEmpty(void) 00951 { 00952 unsigned char temp; 00953 00954 // read CURR from page 1 00955 writeRTL(CR,0x62); 00956 temp = readRTL(CURR); 00957 00958 // return to page 0 00959 writeRTL(CR,0x22); 00960 00961 return ( readRTL(BNRY) == temp ); 00962 00963 }*/