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

📄 rtl8019.c

📁 Contiki是一个开源
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "rtl8019.h"#include "delay.h"#include "debug.h"#include "avr/pgmspace.h"#include "rtlregs.h"#ifndef cbi#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#endif#ifndef sbi#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#endif#define outp(val, port) do { (port) = (val); } while(0)#define inp(port) (port)/******************************************************************************  Module Name:       Realtek 8019AS Driver**  Created By:        Louis Beaudoin (www.embedded-creations.com)**  Original Release:  September 21, 2002**  Module Description:*  Provides functions to initialize the Realtek 8019AS, and send and retreive*  packets**  November 15, 2002 - Louis Beaudoin*    processRTL8019Interrupt() - bit mask mistake fixed**  September 30, 2002 - Louis Beaudoin*    Receive functions modified to handle errors encountered when receiving a*      fast data stream.  Functions now manually retreive data instead of*      using the send packet command.  Interface improved by checking for*      overruns and data in the buffer internally.*    Corrected the overrun function - overrun flag was not reset after overrun*    Added support for the Imagecraft Compiler*    Added support to communicate with the NIC using general I/O ports******************************************************************************//******************************************************************************  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******************************************************************************/#if MEMORY_MAPPED_NIC == 1/*#define writeRTL(RTL_ADDRESS,RTL_DATA) do{ *(volatile unsigned char *) \                             (MEMORY_MAPPED_RTL8019_OFFSET \                             + (((unsigned char)(RTL_ADDRESS)) << 8)) = \                             (unsigned char)(RTL_DATA); } while(0)*/#define writeRTL nic_write#elsevoid writeRTL(unsigned char address, unsigned char data){    // put the address and data in the port registers - data port is output    outp( address, RTL8019_ADDRESS_PORT );    outp( 0xFF, RTL8019_DATA_DDR );    outp( data, RTL8019_DATA_PORT );    	// toggle write pin    RTL8019_CLEAR_WRITE;    RTL8019_SET_WRITE;    	// set data port back to input with pullups enabled    outp( 0x00, RTL8019_DATA_DDR );    outp( 0xFF, RTL8019_DATA_PORT );}#endif/******************************************************************************  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******************************************************************************/#if MEMORY_MAPPED_NIC == 1/*#define readRTL(RTL_ADDRESS) (*(volatile unsigned char *) \                       (MEMORY_MAPPED_RTL8019_OFFSET \                       + (((unsigned char)(RTL_ADDRESS)) << 8)) )*/#define readRTL nic_read#elseunsigned char readRTL(unsigned char address){   unsigned char byte;      // drive the read address   outp( address, RTL8019_ADDRESS_PORT );       //nop();      // assert read   RTL8019_CLEAR_READ;   nop();      // read in the data   byte = inp( RTL8019_DATA_PIN );   // negate read   RTL8019_SET_READ;   return byte;}#endif/******************************************************************************  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){volatile unsigned char *base = (unsigned char *)0x8300;#if MEMORY_MAPPED_NIC == 1  	// enable external SRAM interface - no wait states  	outp(inp(MCUCR) | (1<<SRE), MCUCR);#else    // make the address port output    outp( 0xFF, RTL8019_ADDRESS_DDR );        // make the data port input with pull-ups    outp( 0xFF, RTL8019_DATA_PORT );	// make the control port read and write pins outputs and asserted	//outp( inp(RTL8019_CONTROL_DDR) | (1<<RTL8019_CONTROL_READPIN) |	//          (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_DDR );	sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_READPIN );	sbi( RTL8019_CONTROL_DDR, RTL8019_CONTROL_WRITEPIN );	          	//outp( inp(RTL8019_CONTROL_PORT) | (1<<RTL8019_CONTROL_READPIN) |	//          (1<<RTL8019_CONTROL_WRITEPIN), RTL8019_CONTROL_PORT );	sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_READPIN );	sbi( RTL8019_CONTROL_PORT, RTL8019_CONTROL_WRITEPIN );#endif	// enable output pin for Resetting the RTL8019	sbi( RTL8019_RESET_DDR, RTL8019_RESET_PIN );			}/******************************************************************************  HARD_RESET_RTL8019()**  Created By:  Louis Beaudoin*  Date:        September 21, 2002*  Description: Simply toggles the pin that resets the NIC*****************************************************************************//*#define HARD_RESET_RTL8019() do{ sbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN); \                                Delay_10ms(1); \                                cbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN);} \                                while(0)*//******************************************************************************  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    	0x60void RTL8019beginPacketSend(unsigned int packetLength){  volatile unsigned char *base = (unsigned char *)0x8300;	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;	volatile unsigned char *base = (unsigned char *)0x8300;	for(i=0;i<length;i++)		writeRTL(RDMAPORT, localBuffer[i]);}void RTL8019endPacketSend(void){  volatile unsigned char *base = (unsigned char *)0x8300;	//send the contents of the transmit buffer onto the network	writeRTL(CR,0x24);		// clear the remote DMA interrupt	writeRTL(ISR, (1<<ISR_RDC));}// pointers to locations in the RTL8019 receive bufferstatic 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		  0x03unsigned int RTL8019beginPacketRetreive(void){  volatile unsigned char *base = (unsigned char *)0x8300;	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) ;	/*	debug_print(PSTR("bnry: "));		debug_print8(bnry);*/	/*	debug_print(PSTR("RXSTOP_INIT: "));	debug_print8(RXSTOP_INIT);	debug_print(PSTR("RXSTART_INIT: "));	debug_print8(RXSTART_INIT);*/	// 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);    /*    	debug_print(PSTR("Page header: "));*/	for(i=0;i<4;i++) {	  pageheader[i] = readRTL(RDMAPORT);	  /*	  debug_print8(pageheader[i]);*/	}		// 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;	/*	debug_print(PSTR("nextPage: "));		debug_print8(nextPage);*/		// if the nextPage pointer is invalid, the packet is not ready yet - exit	if( (nextPage >= RXSTOP_INIT) || (nextPage < RXSTART_INIT) ) {	  /*	  UDR0 = '0';*/	  return 0;	}        return rxlen-4;}void RTL8019retreivePacketData(unsigned char * localBuffer, unsigned int length){	unsigned int i;	volatile unsigned char *base = (unsigned char *)0x8300;	// 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -