📄 rtl8019.c
字号:
#include <uip\uip.h>
#include <R8051.H>
#include "rtl8019.h"
#include <serial.h>
sbit RST8019 = P3 ^ 5;
/*****************************************************************************
* writeRTL( RTL_ADDRESS, RTL_DATA )
* Args: 1. unsigned char RTL_ADDRESS - register offset of RTL register
* 2. unsigned char RTL_DATA - data to write to register
* Created By: Louis Beaudoin
* Date: September 21, 2002
* Description: Writes byte to RTL8019 register.
*
* Notes - If using the External SRAM Interface, performs a write to
* address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8)
* The address is sent in the non-multiplxed upper address port so
* no latch is required.
*
* If using general I/O ports, the data port is left in the input
* state with pullups enabled
*
*****************************************************************************/
void writeRTL(unsigned char RTL_ADDRESS, unsigned char ppdata)
{
UBYTE xdata *tmp;
tmp=MEMORY_MAPPED_RTL8019_OFFSET + (((unsigned char)(RTL_ADDRESS)) << 8);
*tmp=ppdata;
}
/*****************************************************************************
* readRTL(RTL_ADDRESS)
* Args: unsigned char RTL_ADDRESS - register offset of RTL register
* Created By: Louis Beaudoin
* Date: September 21, 2002
* Description: Reads byte from RTL8019 register
*
* Notes - If using the External SRAM Interface, performs a read from
* address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8)
* The address is sent in the non-multiplxed upper address port so
* no latch is required.
*
* If using general I/O ports, the data port is assumed to already be
* an input, and is left as an input port when done
*
*****************************************************************************/
unsigned char readRTL(unsigned char RTL_ADDRESS)
{
UBYTE xdata *tmp;
tmp=MEMORY_MAPPED_RTL8019_OFFSET + (((unsigned char)(RTL_ADDRESS)) << 8);
return *tmp;
}
/*****************************************************************************
* RTL8019setupPorts(void);
*
* Created By: Louis Beaudoin
* Date: September 21, 2002
* Description: Sets up the ports used for communication with the RTL8019 NIC
* (data bus, address bus, read, write, and reset)
*****************************************************************************/
void RTL8019setupPorts(void)
{
}
/*****************************************************************************
* HARD_RESET_RTL8019()
*
* Created By: Louis Beaudoin
* Date: September 21, 2002
* Description: Simply toggles the pin that resets the NIC
*****************************************************************************/
void HARD_RESET_RTL8019(void)
{
UWORD COUNT;
for(COUNT=0;COUNT<1000;COUNT++);
RST8019=1;
//Delay_10ms(1);
for(COUNT=0;COUNT<5000;COUNT++);
RST8019=0;
for(COUNT=0;COUNT<2000;COUNT++);
}
/*****************************************************************************
* overrun(void);
*
* Created By: Louis Beaudoin
* Date: September 21, 2002
* Description: "Canned" receive buffer overrun function originally from
* a National Semiconductor appnote
* Notes: This function must be called before retreiving packets from
* the NIC if there is a buffer overrun
*****************************************************************************/
void overrun(void);
//******************************************************************
//* REALTEK CONTROL REGISTER OFFSETS
//* All offsets in Page 0 unless otherwise specified
//* All functions accessing CR must leave CR in page 0 upon exit
//******************************************************************
#define CR 0x00
#define PSTART 0x01
#define PAR0 0x01 // Page 1
#define CR9346 0x01 // Page 3
#define PSTOP 0x02
#define BNRY 0x03
#define TSR 0x04
#define TPSR 0x04
#define TBCR0 0x05
#define NCR 0x05
#define TBCR1 0x06
#define ISR 0x07
#define CURR 0x07 // Page 1
#define RSAR0 0x08
#define CRDA0 0x08
#define RSAR1 0x09
#define CRDA1 0x09
#define RBCR0 0x0A
#define RBCR1 0x0B
#define RSR 0x0C
#define RCR 0x0C
#define TCR 0x0D
#define CNTR0 0x0D
#define DCR 0x0E
#define CNTR1 0x0E
#define IMR 0x0F
#define CNTR2 0x0F
#define RDMAPORT 0x10
#define RSTPORT 0x18
/*****************************************************************************
*
* RTL ISR Register Bits
*
*****************************************************************************/
#define ISR_RST 7
#define ISR_OVW 4
#define ISR_PRX 0
#define ISR_RDC 6
#define ISR_PTX 1
/*****************************************************************************
*
* RTL Register Initialization Values
*
*****************************************************************************/
// RCR : accept broadcast packets and packets destined to this MAC
// drop short frames and receive errors
#define RCR_INIT 0x04
// TCR : default transmit operation - CRC is generated
#define TCR_INIT 0x00
// DCR : allows send packet to be used for packet retreival
// FIFO threshold: 8-bits (works)
// 8-bit transfer mode
#define DCR_INIT 0x58
// IMR : interrupt enabled for receive and overrun events
#define IMR_INIT 0x11
// buffer boundaries - transmit has 6 256-byte pages
// receive has 26 256-byte pages
// entire available packet buffer space is allocated
#define TXSTART_INIT 0x40
#define RXSTART_INIT 0x46
#define RXSTOP_INIT 0x60
void RTL8019beginPacketSend(unsigned int packetLength)
{
unsigned int sendPacketLength;
sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH) ?
packetLength : ETHERNET_MIN_PACKET_LENGTH ;
//start the NIC
writeRTL(CR,0x22);
// still transmitting a packet - wait for it to finish
while( readRTL(CR) & 0x04 );
//load beginning page for transmit buffer
writeRTL(TPSR,TXSTART_INIT);
//set start address for remote DMA operation
writeRTL(RSAR0,0x00);
writeRTL(RSAR1,0x40);
//clear the packet stored interrupt
writeRTL(ISR,(1<<ISR_PTX));
//load data byte count for remote DMA
writeRTL(RBCR0, (unsigned char)(packetLength));
writeRTL(RBCR1, (unsigned char)(packetLength>>8));
writeRTL(TBCR0, (unsigned char)(sendPacketLength));
writeRTL(TBCR1, (unsigned char)((sendPacketLength)>>8));
//do remote write operation
writeRTL(CR,0x12);
}
void RTL8019sendPacketData(unsigned char * localBuffer, unsigned int length)
{
unsigned int i;
for(i=0;i<length;i++)
writeRTL(RDMAPORT, localBuffer[i]);
}
void RTL8019endPacketSend(void)
{
//send the contents of the transmit buffer onto the network
writeRTL(CR,0x24);
// clear the remote DMA interrupt
writeRTL(ISR, (1<<ISR_RDC));
}
//----THE ABOVE IS FOR SEND--------------
//----THE LIST IS FOR RECEIVE-----------
// pointers to locations in the RTL8019 receive buffer
static unsigned char nextPage;
static unsigned int currentRetreiveAddress;
// location of items in the RTL8019's page header
#define enetpacketstatus 0x00
#define nextblock_ptr 0x01
#define enetpacketLenL 0x02
#define enetpacketLenH 0x03
unsigned int RTL8019beginPacketRetreive(void)
{
unsigned char i;
unsigned char bnry;
unsigned char pageheader[4];
unsigned int rxlen;
// check for and handle an overflow
processRTL8019Interrupt();
// read CURR from page 1
writeRTL(CR,0x62);
i = readRTL(CURR);
// return to page 0
writeRTL(CR,0x22);
// read the boundary register - pointing to the beginning of the packet
bnry = readRTL(BNRY) ;
// return if there is no packet in the buffer
if( bnry == i )
return 0;
// clear the packet received interrupt flag
writeRTL(ISR, (1<<ISR_PRX));
// the boundary pointer is invalid, reset the contents of the buffer and exit
if( (bnry >= RXSTOP_INIT) || (bnry < RXSTART_INIT) )
{
writeRTL(BNRY, RXSTART_INIT);
writeRTL(CR, 0x62);
writeRTL(CURR, RXSTART_INIT);
writeRTL(CR, 0x22);
return 0;
}
// initiate DMA to transfer the RTL8019 packet header
writeRTL(RBCR0, 4);
writeRTL(RBCR1, 0);
writeRTL(RSAR0, 0);
writeRTL(RSAR1, bnry);
writeRTL(CR, 0x0A);
for(i=0;i<4;i++)
pageheader[i] = readRTL(RDMAPORT);
// end the DMA operation
writeRTL(CR, 0x22);
for(i = 0; i <= 20; i++)
if(readRTL(ISR) & 1<<6)
break;
writeRTL(ISR, 1<<6);
rxlen = (pageheader[enetpacketLenH]<<8) + pageheader[enetpacketLenL];
nextPage = pageheader[nextblock_ptr] ;
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 RTL8019retreivePacketData(unsigned char * localBuffer, unsigned int length)
{
unsigned int i;
// initiate DMA to transfer the data
writeRTL(RBCR0, (unsigned char)length);
writeRTL(RBCR1, (unsigned char)(length>>8));
writeRTL(RSAR0, (unsigned char)currentRetreiveAddress);
writeRTL(RSAR1, (unsigned char)(currentRetreiveAddress>>8));
writeRTL(CR, 0x0A);
for(i=0;i<length;i++)
localBuffer[i] = readRTL(RDMAPORT);
// end the DMA operation
writeRTL(CR, 0x22);
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)
{
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)
{
unsigned char data_L, resend;
UWORD count;
data_L = readRTL(CR);
writeRTL(CR, 0x21);
// Delay_1ms(2);
for(count=0;count<20000;count++);
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);
}
void initRTL8019(void)
{
// INT8U temp;
UWORD COUNT;
RTL8019setupPorts();
HARD_RESET_RTL8019();
// do soft reset
writeRTL( ISR, readRTL(ISR) ) ;
// Delay_10ms(5);
for(COUNT=0;COUNT<15000;COUNT++);
writeRTL(CR,0x21); // stop the NIC, abort DMA, page 0
// Delay_1ms(2); // make sure nothing is coming in or going out
for(COUNT=0;COUNT<2000;COUNT++);
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);
for(COUNT=0;COUNT<2000;COUNT++);
writeRTL(CURR, RXSTART_INIT);
writeRTL(PAR0+0, UIP_ETHADDR0); //MYMAC_0);
writeRTL(PAR0+1, UIP_ETHADDR1); //MYMAC_1);
writeRTL(PAR0+2, UIP_ETHADDR2); //MYMAC_2);
writeRTL(PAR0+3, UIP_ETHADDR3); //MYMAC_3);
writeRTL(PAR0+4, UIP_ETHADDR4); //MYMAC_4);
writeRTL(PAR0+5, UIP_ETHADDR5); //MYMAC_5);
/*
temp=readRTL(CR+0);
Uart0_printR(&temp,1);
temp=readRTL(PAR0+0);
Uart0_printR(&temp,1);
temp=readRTL(PAR0+1);
Uart0_printR(&temp,1);*/
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)
{
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 );
}*/
void RTl8019_int(void) interrupt 0
{ // Uart0_print("pack in\n");
// OSSemPost(Sem_RecPackage);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -