📄 rtl8019.c
字号:
/*
*/
#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 + -