📄 rtl8019.c
字号:
for(i = 0; i <= 20; i++) if(readRTL(ISR) & 1<<6) break; writeRTL(ISR, 1<<6); currentRetreiveAddress += length; if( currentRetreiveAddress >= 0x6000 ) currentRetreiveAddress = currentRetreiveAddress - (0x6000-0x4600) ;}void RTL8019endPacketRetreive(void){ volatile unsigned char *base = (unsigned char *)0x8300; unsigned char i; // end the DMA operation writeRTL(CR, 0x22); for(i = 0; i <= 20; i++) if(readRTL(ISR) & 1<<6) break; writeRTL(ISR, 1<<6); // set the boundary register to point to the start of the next packet writeRTL(BNRY, nextPage);}void overrun(void){ volatile unsigned char *base = (unsigned char *)0x8300; unsigned char data_L, resend; data_L = readRTL(CR); writeRTL(CR, 0x21); Delay_1ms(2); writeRTL(RBCR0, 0x00); writeRTL(RBCR1, 0x00); if(!(data_L & 0x04)) resend = 0; else if(data_L & 0x04) { data_L = readRTL(ISR); if((data_L & 0x02) || (data_L & 0x08)) resend = 0; else resend = 1; } writeRTL(TCR, 0x02); writeRTL(CR, 0x22); writeRTL(BNRY, RXSTART_INIT); writeRTL(CR, 0x62); writeRTL(CURR, RXSTART_INIT); writeRTL(CR, 0x22); writeRTL(ISR, 0x10); writeRTL(TCR, TCR_INIT); writeRTL(ISR, 0xFF);}/*! * \brief Size of a single ring buffer page. */#define NIC_PAGE_SIZE 0x100/*! * \brief First ring buffer page address. */#define NIC_START_PAGE 0x40/*! * \brief Last ring buffer page address plus 1. */#define NIC_STOP_PAGE 0x60/*! * \brief Number of pages in a single transmit buffer. * * This should be at least the MTU size. */#define NIC_TX_PAGES 6/*! * \brief Number of transmit buffers. */#define NIC_TX_BUFFERS 2/*! * \brief Controller memory layout: * * 0x4000 - 0x4bff 3k bytes transmit buffer * 0x4c00 - 0x5fff 5k bytes receive buffer */#define NIC_FIRST_TX_PAGE NIC_START_PAGE#define NIC_FIRST_RX_PAGE (NIC_FIRST_TX_PAGE + NIC_TX_PAGES * NIC_TX_BUFFERS)/*! * \brief Standard sizing information */#define TX_PAGES 12 /* Allow for 2 back-to-back frames */static unsigned char mac[6] = {0x00,0x06,0x98,0x01,0x02,0x29};void Delay(long nops){ volatile long i; for(i = 0; i < nops; i++)#ifdef __IMAGECRAFT__ asm("nop\n");#else asm volatile("nop\n\t"::);#endif}static int NicReset(void){volatile unsigned char *base = (unsigned char *)0x8300; unsigned char i; unsigned char j; for(j = 0; j < 20; j++) { debug_print(PSTR("SW-Reset...")); i = nic_read(NIC_RESET); Delay(500); nic_write(NIC_RESET, i); for(i = 0; i < 20; i++) { Delay(5000); /* * ID detection added for version 1.1 boards. */ if((nic_read(NIC_PG0_ISR) & NIC_ISR_RST) != 0 && nic_read(NIC_PG0_RBCR0) == 0x50 && nic_read(NIC_PG0_RBCR1) == 0x70) { debug_print(PSTR("OK\r\n")); return 0; } } debug_print(PSTR("failed\r\n\x07")); /* * Toggle the hardware reset line. Since Ethernut version 1.3 the * hardware reset pin of the nic is no longer connected to bit 4 * on port E, but wired to the board reset line. */ if(j == 10) { debug_print(PSTR("Ethernut 1.1 HW-Reset\r\n")); sbi(DDRE, 4); sbi(PORTE, 4); Delay(100000); cbi(PORTE, 4); Delay(250000); } } return -1;}void initRTL8019(void){ unsigned char i, rb; volatile unsigned char *base = (unsigned char *)0x8300; RTL8019setupPorts(); /*#define nic_write writeRTL #define nic_read readRTL*/ /* * Disable NIC interrupts. */ cbi(EIMSK, INT5); /* if(NicReset(base)) return -1;*/#if 0 /* * Mask all interrupts and clear any interrupt status flag to set the * INT pin back to low. */ nic_write(NIC_PG0_IMR, 0); nic_write(NIC_PG0_ISR, 0xff); /* * During reset the nic loaded its initial configuration from an * external eeprom. On the ethernut board we do not have any * configuration eeprom, but simply tied the eeprom data line to * high level. So we have to clear some bits in the configuration * register. Switch to register page 3. */ nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); /* * The nic configuration registers are write protected unless both * EEM bits are set to 1. */ nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); /* * Disable sleep and power down. */ nic_write(NIC_PG3_CONFIG3, 0); /* * Network media had been set to 10Base2 by the virtual EEPROM and * will be set now to auto detect. This will initiate a link test. * We don't force 10BaseT, because this would disable the link test. */ nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); /* * Reenable write protection of the nic configuration registers * and wait for link test to complete. */ nic_write(NIC_PG3_EECR, 0); /* NutSleep(WAIT500);*/ Delay_10ms(50); /* * Switch to register page 0 and set data configuration register * to byte-wide DMA transfers, normal operation (no loopback), * send command not executed and 8 byte fifo threshold. */ nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); /* * Clear remote dma byte count register. */ nic_write(NIC_PG0_RBCR0, 0); nic_write(NIC_PG0_RBCR1, 0); /* * Temporarily set receiver to monitor mode and transmitter to * internal loopback mode. Incoming packets will not be stored * in the nic ring buffer and no data will be send to the network. */ nic_write(NIC_PG0_RCR, NIC_RCR_MON); nic_write(NIC_PG0_TCR, NIC_TCR_LB0); /* * Configure the nic's ring buffer page layout. * NIC_PG0_BNRY: Last page read. * NIC_PG0_PSTART: First page of receiver buffer. * NIC_PG0_PSTOP: Last page of receiver buffer. */ nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); /* * Once again clear interrupt status register. */ nic_write(NIC_PG0_ISR, 0xff); /* * Switch to register page 1 and copy our MAC address into the nic. * We are still in stop mode. */ nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); for(i = 0; i < 6; i++) nic_write(NIC_PG1_PAR0 + i, mac[i]); /* * Clear multicast filter bits to disable all packets. */ for(i = 0; i < 8; i++) nic_write(NIC_PG1_MAR0 + i, 0); /* * Set current page pointer to one page after the boundary pointer. */ nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); /* * Switch back to register page 0, remaining in stop mode. */ nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); /* * Take receiver out of monitor mode and enable it for accepting * broadcasts. */ nic_write(NIC_PG0_RCR, NIC_RCR_AB); /* * Clear all interrupt status flags and enable interrupts. */ nic_write(NIC_PG0_ISR, 0xff); nic_write(NIC_PG0_IMR, NIC_IMR_PRXE | NIC_IMR_PTXE | NIC_IMR_RXEE | NIC_IMR_TXEE | NIC_IMR_OVWE); /* * Fire up the nic by clearing the stop bit and setting the start bit. * To activate the local receive dma we must also take the nic out of * the local loopback mode. */ nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); nic_write(NIC_PG0_TCR, 0); /* NutSleep(WAIT500);*/ Delay_10ms(50);#endif /* 0 */ NicReset(); debug_print(PSTR("Init controller...")); nic_write(NIC_PG0_IMR, 0); nic_write(NIC_PG0_ISR, 0xff); nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); nic_write(NIC_PG3_CONFIG3, 0); nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); nic_write(NIC_PG3_EECR, 0); /* Delay(50000);*/ Delay_10ms(200); nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); nic_write(NIC_PG0_RBCR0, 0); nic_write(NIC_PG0_RBCR1, 0); nic_write(NIC_PG0_RCR, NIC_RCR_MON); nic_write(NIC_PG0_TCR, NIC_TCR_LB0); nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); nic_write(NIC_PG0_ISR, 0xff); nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); for(i = 0; i < 6; i++) nic_write(NIC_PG1_PAR0 + i, mac[i]); for(i = 0; i < 8; i++) nic_write(NIC_PG1_MAR0 + i, 0); nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); nic_write(NIC_PG0_RCR, NIC_RCR_AB); nic_write(NIC_PG0_ISR, 0xff); nic_write(NIC_PG0_IMR, 0); nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); nic_write(NIC_PG0_TCR, 0); /* Delay(1000000)*/ Delay_10ms(200); nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); rb = nic_read(NIC_PG3_CONFIG0); debug_print8(rb); switch(rb & 0xC0) { case 0x00: debug_print(PSTR("RTL8019AS ")); if(rb & 0x08) debug_print(PSTR("jumper mode: ")); if(rb & 0x20) debug_print(PSTR("AUI ")); if(rb & 0x10) debug_print(PSTR("PNP ")); break; case 0xC0: debug_print(PSTR("RTL8019 ")); if(rb & 0x08) debug_print(PSTR("jumper mode: ")); break; default: debug_print(PSTR("Unknown chip ")); debug_print8(rb); break; } if(rb & 0x04) debug_print(PSTR("BNC\x07 ")); if(rb & 0x03) debug_print(PSTR("Failed\x07 ")); /* rb = nic_read(NIC_PG3_CONFIG1); debug_print8(rb);*/ /* NutPrintFormat(0, "IRQ%u ", (rb >> 4) & 7);*/ /* debug_print("IRQ "); debug_print8((rb >> 4) & 7);*/ rb = nic_read(NIC_PG3_CONFIG2); debug_print8(rb); switch(rb & 0xC0) { case 0x00: debug_print(PSTR("Auto ")); break; case 0x40: debug_print(PSTR("10BaseT ")); break; case 0x80: debug_print(PSTR("10Base5 ")); break; case 0xC0: debug_print(PSTR("10Base2 ")); break; } return; /* HARD_RESET_RTL8019();*/ // do soft reset writeRTL( ISR, readRTL(ISR) ) ; Delay_10ms(5); writeRTL(CR,0x21); // stop the NIC, abort DMA, page 0 Delay_1ms(2); // make sure nothing is coming in or going out writeRTL(DCR, DCR_INIT); // 0x58 writeRTL(RBCR0,0x00); writeRTL(RBCR1,0x00); writeRTL(RCR,0x04); writeRTL(TPSR, TXSTART_INIT); writeRTL(TCR,0x02); writeRTL(PSTART, RXSTART_INIT); writeRTL(BNRY, RXSTART_INIT); writeRTL(PSTOP, RXSTOP_INIT); writeRTL(CR, 0x61); Delay_1ms(2); writeRTL(CURR, RXSTART_INIT); writeRTL(PAR0+0, MYMAC_0); writeRTL(PAR0+1, MYMAC_1); writeRTL(PAR0+2, MYMAC_2); writeRTL(PAR0+3, MYMAC_3); writeRTL(PAR0+4, MYMAC_4); writeRTL(PAR0+5, MYMAC_5); writeRTL(CR,0x21); writeRTL(DCR, DCR_INIT); writeRTL(CR,0x22); writeRTL(ISR,0xFF); writeRTL(IMR, IMR_INIT); writeRTL(TCR, TCR_INIT); writeRTL(CR, 0x22); // start the NIC}void processRTL8019Interrupt(void){ volatile unsigned char *base = (unsigned char *)0x8300; unsigned char byte = readRTL(ISR); if( byte & (1<<ISR_OVW) ) overrun();}/* unsigned char RTL8019ReceiveEmpty(void) { unsigned char temp; // read CURR from page 1 writeRTL(CR,0x62); temp = readRTL(CURR); // return to page 0 writeRTL(CR,0x22); return ( readRTL(BNRY) == temp ); }*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -