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

📄 rtl8019.c

📁 51单片机下的RTL8019网络芯片的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*/
#include "reg51.h"
#include "config.h"
#include "GloblDef.h"
#include "TCPIPmem.h"
#include "RTL8019.h"
#include <stdio.h>
#include <absacc.h>

#define RTLBaseAddr 0x8000

/* to prevent call RTLSendPacket() when RTLSendPackt() is already is called, InSending
is used. example when process run in RTLSendPacket() and a interrupt ocurr then call
RTLSendPacket again, then the Register would have changed when interrupt return. */
static unsigned char xdata InSending;

static unsigned char xdata StartPageOfPacket;
/* receive head information */
/*struct RTLReceiveHeader
{
	unsigned char ReceiveStatus;
	unsigned char NextPacketStartPage;
	unsigned char PacketSizeLow;
	unsigned char PacketSizeHigh;
}Head;for some unknown resean Head must be a gloal value. */
static unsigned char xdata Head[4];

/* last trasmit start page */
static unsigned char xdata LastSendStartPage;

/****************************************************************************
* 名称:WriteReg()
* 功能:把数据写入RTL8019AS
* 入口参数:	chPort		写入地址
                chValue         写入数据
* 出口参数:无
****************************************************************************/
void  WriteReg(unsigned char chPort,unsigned char chValue)
{
        unsigned char xdata chWriteRegTmp = 0;
        volatile unsigned int RTLAddr = 0;

        /*
        //方法一
	(*((volatile unsigned short *) RTLBaseAddr + chPort)) = chValue;
        //to debug
        chWriteRegTmp = (*((volatile unsigned short *) RTLBaseAddr + chPort));
        */
        //方法二
        RTLAddr = RTLBaseAddr + chPort;
        *(volatile unsigned char *)(RTLAddr) = chValue;
        //to debug
        chWriteRegTmp = *(volatile unsigned char *)(RTLAddr);


}

/****************************************************************************
* 名称:ReadReg()
* 功能:从RTL8019AS把数据读出
* 入口参数:	chPort          读出地址
* 出口参数:	Read读出数据
****************************************************************************/
unsigned char ReadReg(unsigned char chPort)
{
        unsigned char xdata chReadRegTmp = 0;
        volatile unsigned int RTLAddr = 0;
        /*
	//方法一
	chReadRegTmp = (*((volatile unsigned short *)RTLBaseAddr + chPort));//0x83400000
	return (chReadRegTmp); */

        //方法二
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *(volatile unsigned char *)(RTLAddr);
        return chReadRegTmp;

}
/**********************************************************************
**函数原型:    void  RTLPage(unsigned char chPageNum)
**入口参数:?    unsigned char chPageNum: 要切换的页
**出口参数:	无
**返 回 值:	无
**说    明:	选择页,可选择0,1,2三页,第四页ne000兼容芯片保留,
set bit 7-6 in CR, CR_TXP must be 0(if 1 the packet is retrasmit)
************************************************************************/
void RTLPage(unsigned char chPageNum)
{
	unsigned char chTmp;
	chTmp= ReadReg(0x00);//command register
	chTmp = chTmp & 0x3B ;//注意txp位不能要
	chPageNum = chPageNum << 6;
	chTmp = chTmp | chPageNum;
	WriteReg(0x00,chTmp);
}

/* reset rtl8019 and init registers, MacAddr is MAC address */
void RTL8019Init() reentrant
{
	unsigned char chRTLInitTmp = 0;
	unsigned int i = 0;

	/* after hardware reset a longdelay is necessary for rtl to self-initial */
	//在RSTDRV从高电平回到低电平之后的100MS时,在对RTL8019做读写操作,以确保完全复位
    P35 = 1;
	delay(200);
	P35 = 0;
	delay(200);

	/* reset: write to reset prot */
    WriteReg(0x1f,0xdd);
    chRTLInitTmp = ReadReg(0x1f);
    delay(200);

	/* init RTL registers*/
	WriteReg(0x00,0x21);
    chRTLInitTmp = ReadReg(0x00);
    delay(200);

    RTLPage(0);
    //WriteReg(0x0a,0x00);    //清RBCR0
    //WriteReg(0x0b,0x00);    //清RBCR1
    //WriteReg(0x0c,0xe0);    //RCR,监视模式,不接收数据报
    //WriteReg(0x0d,0xe2);    //TCR,loopback模式

	WriteReg(0x01,0x4c);	/* Pstart	*/
	WriteReg(0x02,0x80);	/* Pstop	*/
	WriteReg(0x03,0x4c);	/* BNRY		*/
	WriteReg(0x04,0x40);	/* TPSR		*/

    //WriteReg(0x0c,0xcc);    //RCR,
    //WriteReg(0x0d,0xe0);    //TCR,

    //WriteReg(0x07,0xFF);	/* ISR: Interrupt Status Register,write FF to clear up all interrupt status */
    //WriteReg(0x0f,0x00);	/* IMR: Interrupt Mask Register,屏蔽掉所有中断 */
    WriteReg(0x0e,0xC8);	/* DCR: Data Configuration Register*/

	//WriteReg(0x0c,0xCE);	/* RCR:  */
	//WriteReg(0x0d,0xE0);	/* TCR:  */

    RTLPage(1);
	WriteReg(0x07,0x4d); //CURR,设置为指向当前正在写的页的下一页

	// MAR0
	WriteReg(0x08,0x00);
	WriteReg(0x09,0x41);
	WriteReg(0x0a,0x00);
	WriteReg(0x0b,0x80);
	WriteReg(0x0c,0x00);
	WriteReg(0x0d,0x00);
	WriteReg(0x0e,0x00);
	WriteReg(0x0f,0x00);

	// set phisical address
    WriteReg(0x01,0x52);
    WriteReg(0x02,0x54);
    WriteReg(0x03,0x4c);
    WriteReg(0x06,0x30);
    WriteReg(0x05,0x2e);
    WriteReg(0x04,0x2f);
    /*

    //To debug
    RTLPage(0);
    chRTLInitTmp = ReadReg(0x08);
    chRTLInitTmp = ReadReg(0x09);
    chRTLInitTmp = ReadReg(0x0a);
    chRTLInitTmp = ReadReg(0x0b);
    chRTLInitTmp = ReadReg(0x0c);
    chRTLInitTmp = ReadReg(0x0d);
    chRTLInitTmp = ReadReg(0x0e);
    chRTLInitTmp = ReadReg(0x0f);
    //for(i = 0;i < 20000;i++);
    chRTLInitTmp = ReadReg(0x03);
    chRTLInitTmp = ReadReg(0x01);
    chRTLInitTmp = ReadReg(0x02);
    chRTLInitTmp = ReadReg(0x06);
    chRTLInitTmp = ReadReg(0x05);
    chRTLInitTmp = ReadReg(0x04);

    RTLPage(1);
    //MAR0~7
    chRTLInitTmp = ReadReg(0x08);
    chRTLInitTmp = ReadReg(0x09);
    chRTLInitTmp = ReadReg(0x0a);
    chRTLInitTmp = ReadReg(0x0b);
    chRTLInitTmp = ReadReg(0x0c);
    chRTLInitTmp = ReadReg(0x0d);
    chRTLInitTmp = ReadReg(0x0e);
    chRTLInitTmp = ReadReg(0x0f);
    //for(i = 0;i < 20000;i++);
    //PAR0~5
    chRTLInitTmp = ReadReg(0x03);
    chRTLInitTmp = ReadReg(0x01);
    chRTLInitTmp = ReadReg(0x02);
    chRTLInitTmp = ReadReg(0x06);
    chRTLInitTmp = ReadReg(0x05);
    chRTLInitTmp = ReadReg(0x04); */

	/* transimit start page */
	LastSendStartPage = SEND_START_PAGE0;
	StartPageOfPacket = RECEIVE_START_PAGE + 1;

	/* in the beginning, no packet is in sending */
	InSending = FALSE;

	RTLPage(0);
	/* initial over, start command and receive */
    WriteReg(0x0c,0xcc);                //将芯片置于正常模式,跟外部网络连接
    WriteReg(0x0d,0xe0);
    WriteReg(0x07,0xFF);
    chRTLInitTmp = ReadReg(0x07);       //清除所有中断标志位
    //(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
	WriteReg(0x00,0x22);
}

/* write buffer to rlt ram */
void RTLWriteRam(unsigned int address, unsigned int size, unsigned char xdata * buff) reentrant
{
	unsigned char xdata *Endp;
	unsigned char PrePage;	// store page
	PrePage = ReadReg(0x00);//CR
	RTLPage(0);
	WriteReg(RSARH_WPAGE0,(unsigned char)((address>>8)&0x00ff));
	WriteReg(RSARL_WPAGE0,(unsigned char)address);
	WriteReg(RBCRH_WPAGE0,(unsigned char)((size>>8)&0x00ff));
	WriteReg(RBCRL_WPAGE0,(unsigned char)size);
	WriteReg(CR,(0x00 | CR_REMOTE_WRITE | CR_START_COMMAND));
	for(Endp = buff + size; buff < Endp;)
	{
		WriteReg(REMOTE_DMA_PORT,*(buff++));
	}
	/* complete dma */
	WriteReg(RBCRH_WPAGE0,0);
	WriteReg(RBCRL_WPAGE0,0);
	WriteReg(0x00,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
	//printf("RTL8019AS初始化完成!");
}

/* read rlt ram data to buffer */
void RTLReadRam(unsigned int address,unsigned int size,unsigned char xdata * buff) reentrant
{
	unsigned char xdata * Endp;
	unsigned char PrePage;	/* store page */

	PrePage = ReadReg(CR);
	RTLPage(0);
	WriteReg(RSARH_WPAGE0,(unsigned char)((address>>8)&0x00ff));
	WriteReg(RSARL_WPAGE0,(unsigned char)address);
	WriteReg(RBCRH_WPAGE0,(unsigned char)((size>>8)&0x00ff));
	WriteReg(RBCRL_WPAGE0,(unsigned char)size);
	WriteReg(CR,(0x00 | CR_REMOTE_READ | CR_START_COMMAND));
	for(Endp = buff + size; buff < Endp;)
	{
		*(buff++) = ReadReg(REMOTE_DMA_PORT);
	}
	/* complete dma */
	WriteReg(RBCRH_WPAGE0,0);
	WriteReg(RBCRL_WPAGE0,0);
	WriteReg(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
}
/* call this function to send a packet by RTL8019. packet store in ram
starts at 'buffer' and its size is 'size'. 'size' should not large than
MAX_PACKET_SIZE or the excess data will be discard. */
unsigned char RTLSendPacket(unsigned char xdata * buffer,unsigned int size) reentrant
{
	unsigned char StartPage;
	unsigned char PrePage;

	/* if send is already running */
	if(InSending == TRUE)
		return FALSE;
	else
		InSending = TRUE;
	/* store page */
	PrePage = ReadReg(CR);

	/* check pakcet size */
	if(size < MIN_PACKET_SIZE)
	{
		size = MIN_PACKET_SIZE;
	}
	else
	{
		if(size > MAX_PACKET_SIZE)
			size = MAX_PACKET_SIZE;
	}

	/* write packet to ram */
	if(LastSendStartPage == SEND_START_PAGE0)
	{
		StartPage = SEND_START_PAGE1;
		LastSendStartPage = SEND_START_PAGE1;
	}
	else
	{
		StartPage = SEND_START_PAGE0;
		LastSendStartPage = SEND_START_PAGE0;
	}
	RTLWriteRam((unsigned int)(((unsigned int)StartPage)<<8),size,buffer);

⌨️ 快捷键说明

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