void rtl8019RetreivePacketData(unsigned char * localBuffer, unsigned int length) { unsigned int i; // initiate DMA to transfer the data rtl8019Write(RBCR0, (unsigned char)length); rtl8019Write(RBCR1, (unsigned char)(length>>8)); rtl8019Write(RSAR0, (unsigned char)CurrentRetreiveAddress); rtl8019Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8)); rtl8019Write(CR, (RD0|START)); // transfer packet data for(i=0; i<length; i++) localBuffer[i] = rtl8019Read(RDMAPORT); // end the DMA operation rtl8019Write(CR, (RD2|START)); // wait for remote DMA complete for(i=0; i<20; i++) if(rtl8019Read(ISR) & RDC) break; rtl8019Write(ISR, RDC); // keep track of current address CurrentRetreiveAddress += length; if( CurrentRetreiveAddress >= 0x6000 ) CurrentRetreiveAddress = CurrentRetreiveAddress - (0x6000-0x4600) ; }
void rtl8019ReceiveOverflowRecover(void) { unsigned char data_L, resend; data_L = rtl8019Read(CR); rtl8019Write(CR, 0x21); delay_ms(2); rtl8019Write(RBCR0, 0x00); rtl8019Write(RBCR1, 0x00); if(!(data_L & 0x04)) resend = 0; else if(data_L & 0x04) { data_L = rtl8019Read(ISR); if((data_L & 0x02) || (data_L & 0x08)) resend = 0; else resend = 1; } rtl8019Write(TCR, 0x02); rtl8019Write(CR, 0x22); rtl8019Write(BNRY, RXSTART_INIT); rtl8019Write(CR, 0x62); rtl8019Write(CPR, RXSTART_INIT); rtl8019Write(CR, 0x22); rtl8019Write(ISR, 0x10); rtl8019Write(TCR, TCR_INIT); if(resend) rtl8019Write(CR, 0x26); rtl8019Write(ISR, 0xFF); }
void rtl8019ProcessInterrupt(void) { unsigned char byte = rtl8019Read(ISR); if( byte & OVW ) rtl8019ReceiveOverflowRecover(); }
void rtl8019BeginPacketSend(unsigned int packetLength) { unsigned int sendPacketLength; sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)? (packetLength):ETHERNET_MIN_PACKET_LENGTH; //start the NIC rtl8019Write(CR, (RD2|START)); // still transmitting a packet - wait for it to finish while( rtl8019Read(CR) & TXP ); // load beginning page for transmit buffer rtl8019Write(TPSR,TXSTART_INIT); // set start address for remote DMA operation rtl8019Write(RSAR0,0x00); rtl8019Write(RSAR1,0x40); // clear the packet stored interrupt rtl8019Write(ISR,PTX); // load data byte count for remote DMA rtl8019Write(RBCR0, (unsigned char)(packetLength)); rtl8019Write(RBCR1, (unsigned char)(packetLength>>8)); rtl8019Write(TBCR0, (unsigned char)(sendPacketLength)); rtl8019Write(TBCR1, (unsigned char)((sendPacketLength)>>8)); // do remote write operation rtl8019Write(CR,(RD1|START)); }
static UInt8 read(RomMapperObsonet* rm, UInt16 address) { if ((address & 0x3fe0) == 0x3fe0) { UInt8 value = rtl8019Read(rm->rtl8019, address & 0x1f); // printf("R %d: %.4x %.2x\n", rm->regBank, address & 0x1f, value); return value; } if (address < 0x4000) { // This is reads to 0x6000-0x7FDF, rest are directly mapped return rm->flashPage[address]; } return 0xff; }
void rtl8019EndPacketRetreive(void) { unsigned char i; // end the DMA operation rtl8019Write(CR, (RD2|START)); // wait for remote DMA complete for(i=0; i<20; i++) if(rtl8019Read(ISR) & RDC) break; rtl8019Write(ISR, RDC); // set the boundary register to point to the start of the next packet rtl8019Write(BNRY, NextPage); }
void nicSetMacAddress(u08* macaddr) { u08 tempCR; // switch register pages tempCR = rtl8019Read(CR); rtl8019Write(CR,tempCR|PS0); // write MAC address registers rtl8019Write(PAR0, *macaddr++); rtl8019Write(PAR1, *macaddr++); rtl8019Write(PAR2, *macaddr++); rtl8019Write(PAR3, *macaddr++); rtl8019Write(PAR4, *macaddr++); rtl8019Write(PAR5, *macaddr++); // switch register pages back rtl8019Write(CR,tempCR); }
void nicGetMacAddress(u08* macaddr) { u08 tempCR; // switch register pages tempCR = rtl8019Read(CR); rtl8019Write(CR,tempCR|PS0); // read MAC address registers *macaddr++ = rtl8019Read(PAR0); *macaddr++ = rtl8019Read(PAR1); *macaddr++ = rtl8019Read(PAR2); *macaddr++ = rtl8019Read(PAR3); *macaddr++ = rtl8019Read(PAR4); *macaddr++ = rtl8019Read(PAR5); // switch register pages back rtl8019Write(CR,tempCR); }
void rtl8019RegDump(void) { // unsigned char result; // result = rtl8019Read(TR); // rprintf("Media State: "); // if(!(result & AUTOD)) // rprintf("Autonegotiation\r\n"); // else if(result & RST_B) // rprintf("PHY in Reset \r\n"); // else if(!(result & RST_10B)) // rprintf("10BASE-T \r\n"); // else if(!(result & RST_TXB)) // rprintf("100BASE-T \r\n"); //rprintf("TR regsiter : %x\r\n",result); //result = read_mii(0x10,0); //rprintf("MII regsiter 0x10: %x\r\n",result); rprintf("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n"); rprintfProgStrM(" "); rprintfu08(rtl8019Read(CR)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(BNRY)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(PSTART)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(PSTOP)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(ISR)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(TSR)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(RSR)); rprintfProgStrM(" "); // rprintfu08(rtl8019Read(MEMR)); rprintfProgStrM(" "); // rprintfu08(rtl8019Read(TR)); rprintfProgStrM(" "); // rprintfu08(rtl8019Read(GPI)); rprintfCRLF(); rtl8019Write(CR,rtl8019Read(CR)|PS0); rprintf("Page1: CR PAR CPR\r\n"); rprintfProgStrM(" "); rprintfu08(rtl8019Read(CR)); rprintfProgStrM(" "); rprintfChar(rtl8019Read(PAR0)); rprintfChar(rtl8019Read(PAR1)); rprintfChar(rtl8019Read(PAR2)); rprintfChar(rtl8019Read(PAR3)); rprintfChar(rtl8019Read(PAR4)); rprintfChar(rtl8019Read(PAR5)); rprintfProgStrM(" "); rprintfu08(rtl8019Read(CPR)); rtl8019Write(CR,rtl8019Read(CR)&~PS0); delay_ms(25); }
unsigned int rtl8019BeginPacketRetreive(void) { unsigned char i; unsigned char bnry; unsigned char pageheader[4]; unsigned int rxlen; // check for and handle an overflow rtl8019ProcessInterrupt(); // read CPR from page 1 rtl8019Write(CR,(PS0|RD2|START)); i = rtl8019Read(CPR); // return to page 0 rtl8019Write(CR,(RD2|START)); // read the boundary register - pointing to the beginning of the packet bnry = rtl8019Read(BNRY) ; // return if there is no packet in the buffer if( bnry == i ) return 0; // clear the packet received interrupt flag rtl8019Write(ISR, PRX); // if boundary pointer is invalid if( (bnry >= RXSTOP_INIT) || (bnry < RXSTART_INIT) ) { // reset the contents of the buffer and exit rtl8019Write(BNRY, RXSTART_INIT); rtl8019Write(CR, (PS0|RD2|START)); rtl8019Write(CPR, RXSTART_INIT); rtl8019Write(CR, (RD2|START)); return 0; } // initiate DMA to transfer the RTL8019 packet header rtl8019Write(RBCR0, 4); rtl8019Write(RBCR1, 0); rtl8019Write(RSAR0, 0); rtl8019Write(RSAR1, bnry); rtl8019Write(CR, (RD0|START)); // transfer packet header for(i=0; i<4; i++) pageheader[i] = rtl8019Read(RDMAPORT); // end the DMA operation rtl8019Write(CR, (RD2|START)); // wait for remote DMA complete for(i = 0; i < 20; i++) if(rtl8019Read(ISR) & RDC) break; rtl8019Write(ISR, RDC); rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL]; NextPage = pageheader[PKTHEADER_NEXTPAGE]; CurrentRetreiveAddress = (bnry<<8) + 4; // if the NextPage pointer is invalid, the packet is not ready yet - exit if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) ) return 0; return rxlen-4; }
void rtl8019Init(void) { // setup I/O ports rtl8019SetupPorts(); // do a hard reset sbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN); delay_ms(10); cbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN); // clear interrupt state rtl8019Write( ISR, rtl8019Read(ISR) ); delay_ms(50); // switch to page 3 to load config registers rtl8019Write(CR, (PS0|PS1|RD2|STOP)); // disable EEPROM write protect of config registers rtl8019Write(RTL_EECR, (EEM1|EEM0)); // set network type to 10 Base-T link test rtl8019Write(CONFIG2, 0x20); // disable powerdown and sleep rtl8019Write(CONFIG3, 0); delay_ms(255); // reenable EEPROM write protect rtl8019Write(RTL_EECR, 0); // go back to page 0, stop NIC, abort DMA rtl8019Write(CR, (RD2|STOP)); delay_ms(2); // wait for traffic to complete rtl8019Write(DCR, DCR_INIT); rtl8019Write(RBCR0,0x00); rtl8019Write(RBCR1,0x00); rtl8019Write(RCR, AB); rtl8019Write(TPSR, TXSTART_INIT); rtl8019Write(TCR, LB0); rtl8019Write(PSTART, RXSTART_INIT); rtl8019Write(BNRY, RXSTART_INIT); rtl8019Write(PSTOP, RXSTOP_INIT); rtl8019Write(CR, (PS0|RD2|STOP)); // switch to page 1 delay_ms(2); rtl8019Write(CPR, RXSTART_INIT); // set MAC address rtl8019Write(PAR0, RTL8019_MAC0); rtl8019Write(PAR1, RTL8019_MAC1); rtl8019Write(PAR2, RTL8019_MAC2); rtl8019Write(PAR3, RTL8019_MAC3); rtl8019Write(PAR4, RTL8019_MAC4); rtl8019Write(PAR5, RTL8019_MAC5); // initialize sequence per NE2000 spec rtl8019Write(CR, (RD2|STOP)); rtl8019Write(DCR, DCR_INIT); rtl8019Write(CR, (RD2|START)); rtl8019Write(ISR,0xFF); // clear all interrupts rtl8019Write(IMR, IMR_INIT); rtl8019Write(TCR, TCR_INIT); rtl8019Write(CR, (RD2|START)); // start the NIC }