Enable radio stats in sensor cgi as default
[contiki-2.x.git] / cpu / avr / dev / rtl8019.c
blob559eda53d9608f16b11c6d8405df38c7985006ef
1 #include "rtl8019.h"
2 #include "delay.h"
3 #include "debug.h"
4 #include "avr/pgmspace.h"
5 #include "rtlregs.h"
7 #ifndef cbi
8 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
9 #endif
10 #ifndef sbi
11 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
12 #endif
14 #define outp(val, port) do { (port) = (val); } while(0)
15 #define inp(port) (port)
17 /*****************************************************************************
18 * Module Name: Realtek 8019AS Driver
20 * Created By: Louis Beaudoin (www.embedded-creations.com)
22 * Original Release: September 21, 2002
24 * Module Description:
25 * Provides functions to initialize the Realtek 8019AS, and send and retreive
26 * packets
28 * November 15, 2002 - Louis Beaudoin
29 * processRTL8019Interrupt() - bit mask mistake fixed
31 * September 30, 2002 - Louis Beaudoin
32 * Receive functions modified to handle errors encountered when receiving a
33 * fast data stream. Functions now manually retreive data instead of
34 * using the send packet command. Interface improved by checking for
35 * overruns and data in the buffer internally.
36 * Corrected the overrun function - overrun flag was not reset after overrun
37 * Added support for the Imagecraft Compiler
38 * Added support to communicate with the NIC using general I/O ports
40 *****************************************************************************/
43 /*****************************************************************************
44 * writeRTL( RTL_ADDRESS, RTL_DATA )
45 * Args: 1. unsigned char RTL_ADDRESS - register offset of RTL register
46 * 2. unsigned char RTL_DATA - data to write to register
47 * Created By: Louis Beaudoin
48 * Date: September 21, 2002
49 * Description: Writes byte to RTL8019 register.
51 * Notes - If using the External SRAM Interface, performs a write to
52 * address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8)
53 * The address is sent in the non-multiplxed upper address port so
54 * no latch is required.
56 * If using general I/O ports, the data port is left in the input
57 * state with pullups enabled
59 *****************************************************************************/
60 #if MEMORY_MAPPED_NIC == 1
61 /*#define writeRTL(RTL_ADDRESS,RTL_DATA) do{ *(volatile unsigned char *) \
62 (MEMORY_MAPPED_RTL8019_OFFSET \
63 + (((unsigned char)(RTL_ADDRESS)) << 8)) = \
64 (unsigned char)(RTL_DATA); } while(0)*/
65 #define writeRTL nic_write
66 #else
69 void writeRTL(unsigned char address, unsigned char data)
71 // put the address and data in the port registers - data port is output
72 outp( address, RTL8019_ADDRESS_PORT );
73 outp( 0xFF, RTL8019_DATA_DDR );
74 outp( data, RTL8019_DATA_PORT );
76 // toggle write pin
77 RTL8019_CLEAR_WRITE;
78 RTL8019_SET_WRITE;
80 // set data port back to input with pullups enabled
81 outp( 0x00, RTL8019_DATA_DDR );
82 outp( 0xFF, RTL8019_DATA_PORT );
87 #endif
89 /*****************************************************************************
90 * readRTL(RTL_ADDRESS)
91 * Args: unsigned char RTL_ADDRESS - register offset of RTL register
92 * Created By: Louis Beaudoin
93 * Date: September 21, 2002
94 * Description: Reads byte from RTL8019 register
96 * Notes - If using the External SRAM Interface, performs a read from
97 * address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8)
98 * The address is sent in the non-multiplxed upper address port so
99 * no latch is required.
101 * If using general I/O ports, the data port is assumed to already be
102 * an input, and is left as an input port when done
104 *****************************************************************************/
105 #if MEMORY_MAPPED_NIC == 1
106 /*#define readRTL(RTL_ADDRESS) (*(volatile unsigned char *) \
107 (MEMORY_MAPPED_RTL8019_OFFSET \
108 + (((unsigned char)(RTL_ADDRESS)) << 8)) )*/
109 #define readRTL nic_read
110 #else
112 unsigned char readRTL(unsigned char address)
114 unsigned char byte;
116 // drive the read address
117 outp( address, RTL8019_ADDRESS_PORT );
119 //nop();
121 // assert read
122 RTL8019_CLEAR_READ;
123 nop();
125 // read in the data
126 byte = inp( RTL8019_DATA_PIN );
128 // negate read
129 RTL8019_SET_READ;
131 return byte;
134 #endif
138 /*****************************************************************************
139 * RTL8019setupPorts(void);
141 * Created By: Louis Beaudoin
142 * Date: September 21, 2002
143 * Description: Sets up the ports used for communication with the RTL8019 NIC
144 * (data bus, address bus, read, write, and reset)
145 *****************************************************************************/
146 void RTL8019setupPorts(void)
148 volatile unsigned char *base = (unsigned char *)0x8300;
150 #if MEMORY_MAPPED_NIC == 1
151 // enable external SRAM interface - no wait states
152 outp(inp(MCUCR) | (1<<SRE), MCUCR);
154 #else
156 // make the address port output
157 outp( 0xFF, RTL8019_ADDRESS_DDR );
159 // make the data port input with pull-ups
160 outp( 0xFF, RTL8019_DATA_PORT );
162 // make the control port read and write pins outputs and asserted
163 //outp( inp(RTL8019_CONTROL_DDR) | (1<<RTL8019_CONTROL_READPIN) |
164 // (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_DDR );
165 sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_READPIN );
166 sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_WRITEPIN );
168 //outp( inp(RTL8019_CONTROL_PORT) | (1<<RTL8019_CONTROL_READPIN) |
169 // (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_PORT );
170 sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_READPIN );
171 sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_WRITEPIN );
173 #endif
175 // enable output pin for Resetting the RTL8019
176 sbi( RTL8019_RESET_DDR, RTL8019_RESET_PIN );
186 /*****************************************************************************
187 * HARD_RESET_RTL8019()
189 * Created By: Louis Beaudoin
190 * Date: September 21, 2002
191 * Description: Simply toggles the pin that resets the NIC
192 *****************************************************************************/
193 /*#define HARD_RESET_RTL8019() do{ sbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN); \
194 Delay_10ms(1); \
195 cbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN);} \
196 while(0)*/
200 /*****************************************************************************
201 * overrun(void);
203 * Created By: Louis Beaudoin
204 * Date: September 21, 2002
205 * Description: "Canned" receive buffer overrun function originally from
206 * a National Semiconductor appnote
207 * Notes: This function must be called before retreiving packets from
208 * the NIC if there is a buffer overrun
209 *****************************************************************************/
210 void overrun(void);
215 //******************************************************************
216 //* REALTEK CONTROL REGISTER OFFSETS
217 //* All offsets in Page 0 unless otherwise specified
218 //* All functions accessing CR must leave CR in page 0 upon exit
219 //******************************************************************
220 #define CR 0x00
221 #define PSTART 0x01
222 #define PAR0 0x01 // Page 1
223 #define CR9346 0x01 // Page 3
224 #define PSTOP 0x02
225 #define BNRY 0x03
226 #define TSR 0x04
227 #define TPSR 0x04
228 #define TBCR0 0x05
229 #define NCR 0x05
230 #define TBCR1 0x06
231 #define ISR 0x07
232 #define CURR 0x07 // Page 1
233 #define RSAR0 0x08
234 #define CRDA0 0x08
235 #define RSAR1 0x09
236 #define CRDA1 0x09
237 #define RBCR0 0x0A
238 #define RBCR1 0x0B
239 #define RSR 0x0C
240 #define RCR 0x0C
241 #define TCR 0x0D
242 #define CNTR0 0x0D
243 #define DCR 0x0E
244 #define CNTR1 0x0E
245 #define IMR 0x0F
246 #define CNTR2 0x0F
247 #define RDMAPORT 0x10
248 #define RSTPORT 0x18
251 /*****************************************************************************
253 * RTL ISR Register Bits
255 *****************************************************************************/
256 #define ISR_RST 7
257 #define ISR_OVW 4
258 #define ISR_PRX 0
259 #define ISR_RDC 6
260 #define ISR_PTX 1
263 /*****************************************************************************
265 * RTL Register Initialization Values
267 *****************************************************************************/
268 // RCR : accept broadcast packets and packets destined to this MAC
269 // drop short frames and receive errors
270 #define RCR_INIT 0x04
272 // TCR : default transmit operation - CRC is generated
273 #define TCR_INIT 0x00
275 // DCR : allows send packet to be used for packet retreival
276 // FIFO threshold: 8-bits (works)
277 // 8-bit transfer mode
278 #define DCR_INIT 0x58
280 // IMR : interrupt enabled for receive and overrun events
281 #define IMR_INIT 0x11
283 // buffer boundaries - transmit has 6 256-byte pages
284 // receive has 26 256-byte pages
285 // entire available packet buffer space is allocated
286 #define TXSTART_INIT 0x40
287 #define RXSTART_INIT 0x46
288 #define RXSTOP_INIT 0x60
292 void RTL8019beginPacketSend(unsigned int packetLength)
295 volatile unsigned char *base = (unsigned char *)0x8300;
296 unsigned int sendPacketLength;
297 sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH) ?
298 packetLength : ETHERNET_MIN_PACKET_LENGTH ;
300 //start the NIC
301 writeRTL(CR,0x22);
303 // still transmitting a packet - wait for it to finish
304 while( readRTL(CR) & 0x04 );
306 //load beginning page for transmit buffer
307 writeRTL(TPSR,TXSTART_INIT);
309 //set start address for remote DMA operation
310 writeRTL(RSAR0,0x00);
311 writeRTL(RSAR1,0x40);
313 //clear the packet stored interrupt
314 writeRTL(ISR,(1<<ISR_PTX));
316 //load data byte count for remote DMA
317 writeRTL(RBCR0, (unsigned char)(packetLength));
318 writeRTL(RBCR1, (unsigned char)(packetLength>>8));
320 writeRTL(TBCR0, (unsigned char)(sendPacketLength));
321 writeRTL(TBCR1, (unsigned char)((sendPacketLength)>>8));
323 //do remote write operation
324 writeRTL(CR,0x12);
329 void RTL8019sendPacketData(unsigned char * localBuffer, unsigned int length)
331 unsigned int i;
332 volatile unsigned char *base = (unsigned char *)0x8300;
333 for(i=0;i<length;i++)
334 writeRTL(RDMAPORT, localBuffer[i]);
339 void RTL8019endPacketSend(void)
341 volatile unsigned char *base = (unsigned char *)0x8300;
342 //send the contents of the transmit buffer onto the network
343 writeRTL(CR,0x24);
345 // clear the remote DMA interrupt
346 writeRTL(ISR, (1<<ISR_RDC));
352 // pointers to locations in the RTL8019 receive buffer
353 static unsigned char nextPage;
354 static unsigned int currentRetreiveAddress;
356 // location of items in the RTL8019's page header
357 #define enetpacketstatus 0x00
358 #define nextblock_ptr 0x01
359 #define enetpacketLenL 0x02
360 #define enetpacketLenH 0x03
364 unsigned int RTL8019beginPacketRetreive(void)
366 volatile unsigned char *base = (unsigned char *)0x8300;
367 unsigned char i;
368 unsigned char bnry;
370 unsigned char pageheader[4];
371 unsigned int rxlen;
373 // check for and handle an overflow
374 processRTL8019Interrupt();
376 // read CURR from page 1
377 writeRTL(CR,0x62);
378 i = readRTL(CURR);
380 // return to page 0
381 writeRTL(CR,0x22);
383 // read the boundary register - pointing to the beginning of the packet
384 bnry = readRTL(BNRY) ;
386 /* debug_print(PSTR("bnry: "));
387 debug_print8(bnry);*/
389 /* debug_print(PSTR("RXSTOP_INIT: "));
390 debug_print8(RXSTOP_INIT);
391 debug_print(PSTR("RXSTART_INIT: "));
392 debug_print8(RXSTART_INIT);*/
393 // return if there is no packet in the buffer
394 if( bnry == i ) {
395 return 0;
399 // clear the packet received interrupt flag
400 writeRTL(ISR, (1<<ISR_PRX));
403 // the boundary pointer is invalid, reset the contents of the buffer and exit
404 if( (bnry >= RXSTOP_INIT) || (bnry < RXSTART_INIT) )
406 writeRTL(BNRY, RXSTART_INIT);
407 writeRTL(CR, 0x62);
408 writeRTL(CURR, RXSTART_INIT);
409 writeRTL(CR, 0x22);
410 return 0;
413 // initiate DMA to transfer the RTL8019 packet header
414 writeRTL(RBCR0, 4);
415 writeRTL(RBCR1, 0);
416 writeRTL(RSAR0, 0);
417 writeRTL(RSAR1, bnry);
418 writeRTL(CR, 0x0A);
419 /* debug_print(PSTR("Page header: "));*/
421 for(i=0;i<4;i++) {
422 pageheader[i] = readRTL(RDMAPORT);
423 /* debug_print8(pageheader[i]);*/
426 // end the DMA operation
427 writeRTL(CR, 0x22);
428 for(i = 0; i <= 20; i++) {
429 if(readRTL(ISR) & 1<<6) {
430 break;
433 writeRTL(ISR, 1<<6);
437 rxlen = (pageheader[enetpacketLenH]<<8) + pageheader[enetpacketLenL];
438 nextPage = pageheader[nextblock_ptr] ;
440 currentRetreiveAddress = (bnry<<8) + 4;
442 /* debug_print(PSTR("nextPage: "));
443 debug_print8(nextPage);*/
445 // if the nextPage pointer is invalid, the packet is not ready yet - exit
446 if( (nextPage >= RXSTOP_INIT) || (nextPage < RXSTART_INIT) ) {
447 /* UDR0 = '0';*/
448 return 0;
451 return rxlen-4;
455 void RTL8019retreivePacketData(unsigned char * localBuffer, unsigned int length)
457 unsigned int i;
458 volatile unsigned char *base = (unsigned char *)0x8300;
459 // initiate DMA to transfer the data
460 writeRTL(RBCR0, (unsigned char)length);
461 writeRTL(RBCR1, (unsigned char)(length>>8));
462 writeRTL(RSAR0, (unsigned char)currentRetreiveAddress);
463 writeRTL(RSAR1, (unsigned char)(currentRetreiveAddress>>8));
464 writeRTL(CR, 0x0A);
465 for(i=0;i<length;i++)
466 localBuffer[i] = readRTL(RDMAPORT);
468 // end the DMA operation
469 writeRTL(CR, 0x22);
470 for(i = 0; i <= 20; i++)
471 if(readRTL(ISR) & 1<<6)
472 break;
473 writeRTL(ISR, 1<<6);
475 currentRetreiveAddress += length;
476 if( currentRetreiveAddress >= 0x6000 )
477 currentRetreiveAddress = currentRetreiveAddress - (0x6000-0x4600) ;
482 void RTL8019endPacketRetreive(void)
484 volatile unsigned char *base = (unsigned char *)0x8300;
485 unsigned char i;
487 // end the DMA operation
488 writeRTL(CR, 0x22);
489 for(i = 0; i <= 20; i++)
490 if(readRTL(ISR) & 1<<6)
491 break;
492 writeRTL(ISR, 1<<6);
494 // set the boundary register to point to the start of the next packet
495 writeRTL(BNRY, nextPage);
499 void overrun(void)
501 volatile unsigned char *base = (unsigned char *)0x8300;
502 unsigned char data_L, resend;
504 data_L = readRTL(CR);
505 writeRTL(CR, 0x21);
506 Delay_1ms(2);
507 writeRTL(RBCR0, 0x00);
508 writeRTL(RBCR1, 0x00);
509 if(!(data_L & 0x04))
510 resend = 0;
511 else if(data_L & 0x04)
513 data_L = readRTL(ISR);
514 if((data_L & 0x02) || (data_L & 0x08))
515 resend = 0;
516 else
517 resend = 1;
520 writeRTL(TCR, 0x02);
521 writeRTL(CR, 0x22);
522 writeRTL(BNRY, RXSTART_INIT);
523 writeRTL(CR, 0x62);
524 writeRTL(CURR, RXSTART_INIT);
525 writeRTL(CR, 0x22);
526 writeRTL(ISR, 0x10);
527 writeRTL(TCR, TCR_INIT);
529 writeRTL(ISR, 0xFF);
536 * \brief Size of a single ring buffer page.
538 #define NIC_PAGE_SIZE 0x100
541 * \brief First ring buffer page address.
543 #define NIC_START_PAGE 0x40
546 * \brief Last ring buffer page address plus 1.
548 #define NIC_STOP_PAGE 0x60
551 * \brief Number of pages in a single transmit buffer.
553 * This should be at least the MTU size.
555 #define NIC_TX_PAGES 6
558 * \brief Number of transmit buffers.
560 #define NIC_TX_BUFFERS 2
563 * \brief Controller memory layout:
565 * 0x4000 - 0x4bff 3k bytes transmit buffer
566 * 0x4c00 - 0x5fff 5k bytes receive buffer
568 #define NIC_FIRST_TX_PAGE NIC_START_PAGE
569 #define NIC_FIRST_RX_PAGE (NIC_FIRST_TX_PAGE + NIC_TX_PAGES * NIC_TX_BUFFERS)
572 * \brief Standard sizing information
574 #define TX_PAGES 12 /* Allow for 2 back-to-back frames */
576 static unsigned char mac[6] = {0x00,0x06,0x98,0x01,0x02,0x29};
577 void Delay(long nops)
579 volatile long i;
581 for(i = 0; i < nops; i++)
582 #ifdef __IMAGECRAFT__
583 asm("nop\n");
584 #else
585 asm volatile("nop\n\t"::);
586 #endif
589 static int NicReset(void)
591 volatile unsigned char *base = (unsigned char *)0x8300;
592 unsigned char i;
593 unsigned char j;
595 for(j = 0; j < 20; j++) {
596 debug_print(PSTR("SW-Reset..."));
597 i = nic_read(NIC_RESET);
598 Delay(500);
599 nic_write(NIC_RESET, i);
600 for(i = 0; i < 20; i++) {
601 Delay(5000);
604 * ID detection added for version 1.1 boards.
606 if((nic_read(NIC_PG0_ISR) & NIC_ISR_RST) != 0 &&
607 nic_read(NIC_PG0_RBCR0) == 0x50 &&
608 nic_read(NIC_PG0_RBCR1) == 0x70) {
609 debug_print(PSTR("OK\r\n"));
610 return 0;
613 debug_print(PSTR("failed\r\n\x07"));
616 * Toggle the hardware reset line. Since Ethernut version 1.3 the
617 * hardware reset pin of the nic is no longer connected to bit 4
618 * on port E, but wired to the board reset line.
620 if(j == 10) {
621 debug_print(PSTR("Ethernut 1.1 HW-Reset\r\n"));
622 sbi(DDRE, 4);
623 sbi(PORTE, 4);
624 Delay(100000);
625 cbi(PORTE, 4);
626 Delay(250000);
629 return -1;
632 void initRTL8019(void)
634 unsigned char i, rb;
635 volatile unsigned char *base = (unsigned char *)0x8300;
637 RTL8019setupPorts();
639 /*#define nic_write writeRTL
640 #define nic_read readRTL*/
642 * Disable NIC interrupts.
644 cbi(EIMSK, INT5);
646 /* if(NicReset(base))
647 return -1;*/
648 #if 0
650 * Mask all interrupts and clear any interrupt status flag to set the
651 * INT pin back to low.
653 nic_write(NIC_PG0_IMR, 0);
654 nic_write(NIC_PG0_ISR, 0xff);
657 * During reset the nic loaded its initial configuration from an
658 * external eeprom. On the ethernut board we do not have any
659 * configuration eeprom, but simply tied the eeprom data line to
660 * high level. So we have to clear some bits in the configuration
661 * register. Switch to register page 3.
663 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1);
666 * The nic configuration registers are write protected unless both
667 * EEM bits are set to 1.
669 nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1);
672 * Disable sleep and power down.
674 nic_write(NIC_PG3_CONFIG3, 0);
677 * Network media had been set to 10Base2 by the virtual EEPROM and
678 * will be set now to auto detect. This will initiate a link test.
679 * We don't force 10BaseT, because this would disable the link test.
681 nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB);
684 * Reenable write protection of the nic configuration registers
685 * and wait for link test to complete.
687 nic_write(NIC_PG3_EECR, 0);
688 /* NutSleep(WAIT500);*/
689 Delay_10ms(50);
692 * Switch to register page 0 and set data configuration register
693 * to byte-wide DMA transfers, normal operation (no loopback),
694 * send command not executed and 8 byte fifo threshold.
696 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2);
697 nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1);
700 * Clear remote dma byte count register.
702 nic_write(NIC_PG0_RBCR0, 0);
703 nic_write(NIC_PG0_RBCR1, 0);
706 * Temporarily set receiver to monitor mode and transmitter to
707 * internal loopback mode. Incoming packets will not be stored
708 * in the nic ring buffer and no data will be send to the network.
710 nic_write(NIC_PG0_RCR, NIC_RCR_MON);
711 nic_write(NIC_PG0_TCR, NIC_TCR_LB0);
714 * Configure the nic's ring buffer page layout.
715 * NIC_PG0_BNRY: Last page read.
716 * NIC_PG0_PSTART: First page of receiver buffer.
717 * NIC_PG0_PSTOP: Last page of receiver buffer.
719 nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE);
720 nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1);
721 nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE);
722 nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE);
725 * Once again clear interrupt status register.
727 nic_write(NIC_PG0_ISR, 0xff);
730 * Switch to register page 1 and copy our MAC address into the nic.
731 * We are still in stop mode.
733 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0);
734 for(i = 0; i < 6; i++)
735 nic_write(NIC_PG1_PAR0 + i, mac[i]);
738 * Clear multicast filter bits to disable all packets.
740 for(i = 0; i < 8; i++)
741 nic_write(NIC_PG1_MAR0 + i, 0);
744 * Set current page pointer to one page after the boundary pointer.
746 nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES);
749 * Switch back to register page 0, remaining in stop mode.
751 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2);
754 * Take receiver out of monitor mode and enable it for accepting
755 * broadcasts.
757 nic_write(NIC_PG0_RCR, NIC_RCR_AB);
760 * Clear all interrupt status flags and enable interrupts.
762 nic_write(NIC_PG0_ISR, 0xff);
763 nic_write(NIC_PG0_IMR, NIC_IMR_PRXE | NIC_IMR_PTXE | NIC_IMR_RXEE |
764 NIC_IMR_TXEE | NIC_IMR_OVWE);
767 * Fire up the nic by clearing the stop bit and setting the start bit.
768 * To activate the local receive dma we must also take the nic out of
769 * the local loopback mode.
771 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
772 nic_write(NIC_PG0_TCR, 0);
774 /* NutSleep(WAIT500);*/
775 Delay_10ms(50);
778 #endif /* 0 */
780 NicReset();
782 debug_print(PSTR("Init controller..."));
783 nic_write(NIC_PG0_IMR, 0);
784 nic_write(NIC_PG0_ISR, 0xff);
785 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1);
786 nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1);
787 nic_write(NIC_PG3_CONFIG3, 0);
788 nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB);
789 nic_write(NIC_PG3_EECR, 0);
790 /* Delay(50000);*/
791 Delay_10ms(200);
792 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2);
793 nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1);
794 nic_write(NIC_PG0_RBCR0, 0);
795 nic_write(NIC_PG0_RBCR1, 0);
796 nic_write(NIC_PG0_RCR, NIC_RCR_MON);
797 nic_write(NIC_PG0_TCR, NIC_TCR_LB0);
798 nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE);
799 nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1);
800 nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE);
801 nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE);
802 nic_write(NIC_PG0_ISR, 0xff);
803 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0);
804 for(i = 0; i < 6; i++)
805 nic_write(NIC_PG1_PAR0 + i, mac[i]);
806 for(i = 0; i < 8; i++)
807 nic_write(NIC_PG1_MAR0 + i, 0);
808 nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES);
809 nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2);
810 nic_write(NIC_PG0_RCR, NIC_RCR_AB);
811 nic_write(NIC_PG0_ISR, 0xff);
812 nic_write(NIC_PG0_IMR, 0);
813 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
814 nic_write(NIC_PG0_TCR, 0);
815 /* Delay(1000000)*/
816 Delay_10ms(200);
819 nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1);
820 rb = nic_read(NIC_PG3_CONFIG0);
821 debug_print8(rb);
822 switch(rb & 0xC0) {
823 case 0x00:
824 debug_print(PSTR("RTL8019AS "));
825 if(rb & 0x08)
826 debug_print(PSTR("jumper mode: "));
827 if(rb & 0x20)
828 debug_print(PSTR("AUI "));
829 if(rb & 0x10)
830 debug_print(PSTR("PNP "));
831 break;
832 case 0xC0:
833 debug_print(PSTR("RTL8019 "));
834 if(rb & 0x08)
835 debug_print(PSTR("jumper mode: "));
836 break;
837 default:
838 debug_print(PSTR("Unknown chip "));
839 debug_print8(rb);
840 break;
842 if(rb & 0x04)
843 debug_print(PSTR("BNC\x07 "));
844 if(rb & 0x03)
845 debug_print(PSTR("Failed\x07 "));
847 /* rb = nic_read(NIC_PG3_CONFIG1);
848 debug_print8(rb);*/
849 /* NutPrintFormat(0, "IRQ%u ", (rb >> 4) & 7);*/
850 /* debug_print("IRQ ");
851 debug_print8((rb >> 4) & 7);*/
853 rb = nic_read(NIC_PG3_CONFIG2);
854 debug_print8(rb);
855 switch(rb & 0xC0) {
856 case 0x00:
857 debug_print(PSTR("Auto "));
858 break;
859 case 0x40:
860 debug_print(PSTR("10BaseT "));
861 break;
862 case 0x80:
863 debug_print(PSTR("10Base5 "));
864 break;
865 case 0xC0:
866 debug_print(PSTR("10Base2 "));
867 break;
871 return;
873 /* HARD_RESET_RTL8019();*/
875 // do soft reset
876 writeRTL( ISR, readRTL(ISR) ) ;
877 Delay_10ms(5);
879 writeRTL(CR,0x21); // stop the NIC, abort DMA, page 0
880 Delay_1ms(2); // make sure nothing is coming in or going out
881 writeRTL(DCR, DCR_INIT); // 0x58
882 writeRTL(RBCR0,0x00);
883 writeRTL(RBCR1,0x00);
884 writeRTL(RCR,0x04);
885 writeRTL(TPSR, TXSTART_INIT);
886 writeRTL(TCR,0x02);
887 writeRTL(PSTART, RXSTART_INIT);
888 writeRTL(BNRY, RXSTART_INIT);
889 writeRTL(PSTOP, RXSTOP_INIT);
890 writeRTL(CR, 0x61);
891 Delay_1ms(2);
892 writeRTL(CURR, RXSTART_INIT);
894 writeRTL(PAR0+0, MYMAC_0);
895 writeRTL(PAR0+1, MYMAC_1);
896 writeRTL(PAR0+2, MYMAC_2);
897 writeRTL(PAR0+3, MYMAC_3);
898 writeRTL(PAR0+4, MYMAC_4);
899 writeRTL(PAR0+5, MYMAC_5);
901 writeRTL(CR,0x21);
902 writeRTL(DCR, DCR_INIT);
903 writeRTL(CR,0x22);
904 writeRTL(ISR,0xFF);
905 writeRTL(IMR, IMR_INIT);
906 writeRTL(TCR, TCR_INIT);
908 writeRTL(CR, 0x22); // start the NIC
912 void processRTL8019Interrupt(void)
914 volatile unsigned char *base = (unsigned char *)0x8300;
915 unsigned char byte = readRTL(ISR);
917 if( byte & (1<<ISR_OVW) )
918 overrun();
923 unsigned char RTL8019ReceiveEmpty(void)
925 unsigned char temp;
927 // read CURR from page 1
928 writeRTL(CR,0x62);
929 temp = readRTL(CURR);
931 // return to page 0
932 writeRTL(CR,0x22);
934 return ( readRTL(BNRY) == temp );