⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8019.c

📁 完整的实现RS232与TCP/IP网络协议的转换
💻 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 + -