rtl8019.c.svn-base

来自「数字广播系统的开发源码」· SVN-BASE 代码 · 共 670 行 · 第 1/2 页

SVN-BASE
670
字号
/*
*/
#include "reg51.h"
#include "config.h"
#include "GloblDef.h"
#include "TCPIPmem.h"
#include "RTL8019.h"
#include <stdio.h>
#include <absacc.h>

#define RTLBaseAddr 0x8000
//ARP Test
unsigned char xdata TestPacket[42];

/* 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);
        */
        /*
        //方法三,结果:发送时灯不亮
        RTLAddr = RTLBaseAddr + chPort;
        (*((volatile BYTE xdata *)RTLAddr)) = chValue;
         chWriteRegTmp = *(volatile unsigned char *)(RTLAddr); */
        /*
        //方法四:XBYTE方式,结果:发送时灯亮,但没有数据出去,热复位不成功
        RTLAddr = RTLBaseAddr + chPort;
        ((unsigned char volatile xdata *) 0)[RTLAddr] = chValue;
        chWriteRegTmp = ((unsigned char volatile xdata *) 0)[RTLAddr]; */
        /*
        //方法五:类似XBYTE方式,结果:同方法四
        RTLAddr = RTLBaseAddr + chPort;
        *(unsigned char volatile xdata *)(RTLAddr) = chValue;
        chWriteRegTmp = *(unsigned char volatile xdata *)(RTLAddr); */
        /*
        //方法六:类方法五,只是CHAR->int,结果:发送灯亮,仍没数据出去,热复位不成功
        RTLAddr = RTLBaseAddr + chPort;
        *(unsigned int volatile xdata *)(RTLAddr) = chValue;
        chWriteRegTmp = *(unsigned int volatile xdata *)(RTLAddr); */
        /*
        //方法七:结果同方法二
        RTLAddr = RTLBaseAddr + chPort;
        (*(volatile unsigned char *)(RTLAddr)) = chValue;
        chWriteRegTmp  = (*(volatile unsigned char *)(RTLAddr)); */

        //方法八:
        RTLAddr = RTLBaseAddr + chPort;
        *((unsigned char volatile xdata *)((volatile unsigned int *)RTLAddr)) = chValue;
        chWriteRegTmp = *((unsigned char volatile xdata *)((volatile unsigned int *)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
	 */

        /*
        //方法二,结果:发送时灯不亮
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *(volatile unsigned char *)(RTLAddr);
         */
        /*
        //方法三,结果:发送时灯不亮
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *(volatile unsigned char *)(RTLAddr);
        */
        /*
        //方法四:XBYTE方式,结果:发送时灯亮,但没有数据出去,热复位不成功
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp  = ((unsigned char volatile xdata *) 0)[RTLAddr];*/
        /*
        //方法五:类似XBYTE方式,结果:同方法四
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *(unsigned char volatile xdata *)(RTLAddr);*/
        /*
        //方法六:类方法五,只是CHAR->int,结果:发送灯亮,仍没数据出去,热复位不成功
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *(unsigned int volatile xdata *)(RTLAddr);*/
        /*
        //方法七:
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = (*(volatile unsigned char *)(RTLAddr));*/

        //方法八:
        RTLAddr = RTLBaseAddr + chPort;
        chReadRegTmp = *((unsigned char volatile xdata *)((volatile unsigned int *)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()
{
	unsigned char chRTLInitTmp = 0;
	unsigned int i;

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

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

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

        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
        chRTLInitTmp = ReadReg(0x07);
        chRTLInitTmp = ReadReg(0x0f);
        //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)

⌨️ 快捷键说明

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