共2条
1/1 1 跳转至页
TCP,IP,uip,2200 学习TCP/IP,想把uip弄到2200的板子上,弄了2天也不成!
问
请弄过的兄弟指点一下,需要注意些什么?
调试看从8019读出的都是0505,不知道什么原因。第一次接触,请各位多指点
谢谢! 答 1: 搞过的兄弟说一下吧? 答 2: 8019的驱动对不对啊?8019的驱动对不对啊?
8019的远程DMA设置成8位还是16位啊? 答 3: DMA为16位,板上2210的A1接到8019的A0上的 答 4: 8019驱动的问题看看能不能读写寄存器 答 5: 读写寄存器的函数都是周工用的 我试了一下,在8019初始化函数中,每写一次寄存器后,就读相应寄存器,将读出的数用串口送出来,但是读出的和写进的不一样,我想周工的函数不会有问题的,不知道怎么回事? 答 6: dma改成8位也不行,读出来的都是0x04;郁闷 答 7: 读写和初始化函数void WriteToNet(uint8 ADDR_16,uint8 WRITEDATA)
{
(*((volatile unsigned short *) NET_BASE_ADDR+ADDR_16)) =WRITEDATA;
}
uint8 ReadFromNet(uint8 ADDR_16)
{
uint8 temp;
temp=(*((volatile unsigned short *)NET_BASE_ADDR+ADDR_16));//0x83400000
return (temp);
}
void etherdev_init()
{
uint8 i;
uint8 j;
//PINSEL0 = 0x00000005; // 设置所有管脚连接GPIO
//PINSEL1 = 0x00000000;
//IODIR=IODIR|(NET_DATA+NET_CS+NET_WR+NET_ALE+NET_RD+NET_RST);
//IOSET=NET_DATA+NET_CS+NET_WR+NET_ALE+NET_RD+NET_RST;
IODIR=IODIR|NET_RST;
IOCLR=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOSET=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOCLR=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
WriteToNet(0x1f,0x00);
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
/**********************************************************************
1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
位: 7 6 5 4 3 2 1 0
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
0 0 1 : 读网卡内存
0 1 0 : 写网卡内存
0 1 1 : 发送网卡数据包
1 * * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP: 这两个位用来启动命令或停止命令
1 0 启动命令
0 1 停止命令
//============================================
********************************************************/
WriteToNet(0x00,0x21); //使芯片处于停止模式,这时进行寄存器设置
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
} //延时10毫秒,确保芯片进入停止模式
page(0);
WriteToNet(0x0a,0x00); //清rbcr0
WriteToNet(0x0b,0x00); //清rbcr1
WriteToNet(0x0c, 0xe0); //RCR,监视模式,不接收数据包
WriteToNet(0x0d, 0xe2); //TCR,loop back模式
page(0);
WriteToNet(0x01,0x4c); //PSTART=0X4C
WriteToNet(0x02,0x80); //PSTOP=0X80
WriteToNet(0x03,0x4c); //bnry=0x4c;
page(0);
WriteToNet(0x04,0x40); //TPSR,发送起始页寄存器
WriteToNet(0x07,0xff); //清除所有中断标志位,中断状态寄存器
WriteToNet(0x0f,0x11); //中断屏蔽寄存器清0,禁止中断
WriteToNet(0x0e,0xca); // 数据配置寄存器,8位dma方式 16 0xcb
page(1);
WriteToNet(0x07,0x4d); //curr=0x4d
WriteToNet(0x08,0x00);
WriteToNet(0x09,0x00);
WriteToNet(0x0a,0x00);
WriteToNet(0x0b,0x00);
WriteToNet(0x0c,0x00);
WriteToNet(0x0d,0x00);
WriteToNet(0x0e,0x00);
WriteToNet(0x0f,0x00);
WriteToNet(0x00,0x22); //这时让芯片开始工作
SetMacID(); //将芯片物理地址写入到MAR寄存器
page(0);
WriteToNet(0x0c,0xcc); //将芯片设置成正常模式,跟外部网络连接
WriteToNet(0x0d,0xe0);
WriteToNet(0x00,0x22); //启动芯片开始工作
WriteToNet(0x07,0xff); //清除所有中断标志位
}
答 8: re改成这样,试试:
void WriteToNet(uint8 ADDR_16,uint8 WRITEDATA)
{
(*((volatile unsigned short *) NET_BASE_ADDR+(ADDR_16<<1))) =WRITEDATA;
}
uint8 ReadFromNet(uint8 ADDR_16)
{
uint8 temp;
temp=(*((volatile unsigned short *)NET_BASE_ADDR+(ADDR_16<<1)));//0x83400000
return (temp);
}
答 9: 不用这样写吧?我看过汇编的,因为NET_BASE_ADDR是unsigned short型的,所以ADS会把
ADD_16左移一位后再加给NET_BASE_ADDR的的 答 10: re以下是我改写的,已经成功应用,DMA为8位。你参考一下。
#define NET_BASE_ADDR 0x83400000
/* 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 BYTE DT_XDATA InSending;
/* receive head information */
/*struct RTLReceiveHeader
{
BYTE ReceiveStatus;
BYTE NextPacketStartPage;
BYTE PacketSizeLow;
BYTE PacketSizeHigh;
}Head;for some unknown resean Head must be a gloal value. */
static BYTE DT_XDATA Head[4];
/****************************************************************************
* 名称:WriteToNet()
* 功能:把数据写入RTL8019AS
* 入口参数: ADDR 写入地址
WRITEDATA 写入数据
* 出口参数:无
****************************************************************************/
void WriteReg(BYTE ADDR_16,BYTE WRITEDATA)
{
*((volatile unsigned char *) NET_BASE_ADDR+(ADDR_16<<1))=WRITEDATA;//0x83400000
}
/****************************************************************************
* 名称:ReadFromNet()
* 功能:从RTL8019AS把数据读出
* 入口参数: ADDR 读出地址
* 出口参数: READDATA 读出数据
****************************************************************************/
BYTE ReadReg(BYTE ADDR_16)
{
BYTE temp;
temp=*((volatile unsigned char *)NET_BASE_ADDR+(ADDR_16<<1));//0x83400000
return (temp);
}
/**********************************************************************
**函数原型: void page(uchar pagenumber)
**入口参数:?uchar pagenumber: 要切换的页
**出口参数: 无
**返 回 值: 无
**说 明: 选择页,可选择0,1,2三页,第四页ne000兼容芯片保留
************************************************************************/
void RTLPage(BYTE pagenumber)
{
BYTE temp;
temp=ReadReg(0);//command register
temp=temp&0x3B ;//注意txp位不能要
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
WriteReg(0,temp);
}
#define page RTLPage
#define WriteToNet WriteReg
/* reset rtl8019 and init registers, LocalMacAddr is MAC address */
void RTLInit(BYTE LocalMACAddr[]) REENTRANT_MUL
{
BYTE i;
BYTE j;
IODIR=IODIR|GPIO_NET_RST;
IOCLR=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOSET=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOCLR=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
WriteToNet(0x1f,0x00);
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
/**********************************************************************
1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
位: 7 6 5 4 3 2 1 0
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
0 0 1 : 读网卡内存
0 1 0 : 写网卡内存
0 1 1 : 发送网卡数据包
1 * * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP: 这两个位用来启动命令或停止命令
1 0 启动命令
0 1 停止命令
//============================================
********************************************************/
WriteToNet(0x00,0x21); //使芯片处于停止模式,这时进行寄存器设置
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
} //延时10毫秒,确保芯片进入停止模式
page(0);
WriteToNet(0x0a,0x00); //清rbcr0
WriteToNet(0x0b,0x00); //清rbcr1
WriteToNet(0x0c, 0xe0); //RCR,监视模式,不接收数据包
WriteToNet(0x0d, 0xe2); //TCR,loop back模式
page(0);
WriteToNet(0x01,0x4c); //PSTART=0X4C
WriteToNet(0x02,0x80); //PSTOP=0X80
WriteToNet(0x03,0x4c); //bnry=0x4c;
page(0);
WriteToNet(0x04,0x40); //TPSR,发送起始页寄存器
WriteToNet(0x07,0xff); //清除所有中断标志位,中断状态寄存器
WriteToNet(0x0f,0x11); //中断屏蔽寄存器清0,禁止中断
WriteToNet(0x0e,0xc8); // 数据配置寄存器,8位dma方式
page(1);
WriteToNet(0x07,0x4d); //curr=0x4d
WriteToNet(0x08,0x00);
WriteToNet(0x09,0x00);
WriteToNet(0x0a,0x00);
WriteToNet(0x0b,0x00);
WriteToNet(0x0c,0x00);
WriteToNet(0x0d,0x00);
WriteToNet(0x0e,0x00);
WriteToNet(0x0f,0x00);
WriteToNet(0x00,0x22); //这时让芯片开始工作
page(1);
WriteReg(0x01,LocalMACAddr[0]);
WriteReg(0x02,LocalMACAddr[1]);
WriteReg(0x03,LocalMACAddr[2]);
WriteReg(0x04,LocalMACAddr[3]);
WriteReg(0x05,LocalMACAddr[4]);
WriteReg(0x06,LocalMACAddr[5]);
page(0);
WriteToNet(0x0c,0xcc); //将芯片设置成正常模式,跟外部网络连接
WriteToNet(0x0d,0xe0);
WriteToNet(0x00,0x22); //启动芯片开始工作
WriteToNet(0x07,0xff); //清除所有中断标志位
}
/* write buffer to rlt ram */
void RTLWriteRam(WORD address, WORD size, BYTE * buff) REENTRANT_SIG
{
BYTE *Endp;
BYTE PrePage; /* store page */
PrePage = ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(BYTE)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)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(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
}
/* read rlt ram data to buffer */
void RTLReadRam(WORD address,WORD size,BYTE DT_XDATA * buff) REENTRANT_MUL
{
BYTE DT_XDATA * Endp;
BYTE PrePage; /* store page */
PrePage = ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(BYTE)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)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. */
BOOL RTLSendPacket(void DT_XDATA * buffer,WORD size) REENTRANT_SIG
{
BYTE PrePage;
BYTE LastSendStartPage; /*上次发送使用的开始页*/
BYTE CurrSendStartPage; /*本次发送使用的开始页*/
/* 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 */
RTLPage(2);
LastSendStartPage = ReadReg(TPSR_RPAGE2);
if(LastSendStartPage == SEND_START_PAGE0)
{
CurrSendStartPage = SEND_START_PAGE1;
}
else
{
CurrSendStartPage = SEND_START_PAGE0;
}
RTLWriteRam((WORD)(((WORD)CurrSendStartPage)<<8),size,buffer); //数据写进发送起始RAM
/* wait for last time trasmition to complete */
while((ReadReg(CR) & CR_TXP) == CR_TXP);
/* write trasmit start page and size */
RTLPage(0);
WriteReg(TPSR_WPAGE0,CurrSendStartPage); /* TPSR */ //发送起始地址寄存器置位
WriteReg(TBCRL_WPAGE0,(BYTE)size);/*low */
WriteReg(TBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff)); /*high*/
WriteReg(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_TXP | CR_START_COMMAND));
InSending = FALSE;
return TRUE;
}
/* call this function to receive a ethernet packet from RTL8019.
return value:
NULL: no packet CAN receive yet.
not NULL:
a address point to MemHead. This Head contain merory
Imformation(memory start address, memory end address ...) of
received packet. Memory is allocated by function 'MemAllocate(WORD size)'.
a example of struct SMemHead is:
struct SMemHead
{
BOOL used; // if in using
BYTE DT_XDATA *pStart; // the start address of memory
BYTE DT_XDATA *pEnd;
};
You CAN use your own struct SMemHead and MemAllocat function in your project.
*/
struct SMemHead DT_XDATA * RTLReceivePacket(void) REENTRANT_SIG
{
BYTE curr,bnry;
WORD address;
WORD PacketSize;
struct SMemHead DT_XDATA *MemHead;
BYTE ii;
/* if send is running don't crrupt RTL register*/
if(InSending == TRUE)
{
return NULL;
}
MemHead = NULL;
Disable_IRQ();
RTLPage(0);
ii=ReadReg(ISR_RPAGE0); //读取中断状态
if((ii&0x90)!=0) //如果复位或益出就重新初试化
{
RTLInit(EtherAddr); //重新初始化
Enable_IRQ();
return NULL;
}
bnry = ReadReg(BNRY_RPAGE0);
RTLPage(1);
curr = ReadReg(CURR_RPAGE1);
RTLPage(0);
if(curr == 0){
Enable_IRQ();
return NULL;
}
bnry++;
if(bnry >= RECEIVE_STOP_PAGE)
{
bnry = RECEIVE_START_PAGE;
}
/* check if there is packets to read */
if(bnry == curr){
Enable_IRQ();
return NULL;
}
/*
* read a packet
*/
/* read packet head imformation */
address = ((WORD)bnry)<<8;
RTLReadRam(address,4,Head);
/* check rsr, if isn't a good packet no read */
if(Head[0] & RSR_RECEIVE_NO_ERROR)
{
/* this is a good packet */
/* packet size, sub 4 bytes, this 4 byte is MAC checksum */
PacketSize = ((WORD)Head[3])*256 + Head[2] - 4;
/* allocate buffer and read packet into buffer */
if((MemHead = MemAllocate(PacketSize)) != NULL)
{
/* if packet is put from bnry+1 to receive_stop_page and receive
start page to next packet startpage, that is if bnry+1 > next
packet start page and next start page != receive_start_page,
we need read by two times. the first time from bnry+1 to receive
_stop_page, the second time from receive start page to next packet
startpage.
*/
address += 4;
if(bnry > Head[1] && Head[1] != RECEIVE_START_PAGE)
{
RTLReadRam(address,(WORD)((((WORD)RECEIVE_STOP_PAGE)<<8) - address),(BYTE *)MemHead->pStart); /* read from rtl */
RTLReadRam((WORD)(((WORD)RECEIVE_START_PAGE)<<8),(WORD)(PacketSize - ((((WORD)RECEIVE_STOP_PAGE)<<8) - address)),
(BYTE *)MemHead->pStart + ((((WORD)RECEIVE_STOP_PAGE)<<8) - address)); /* read from rtl */
}
else
{
RTLReadRam(address,PacketSize,(BYTE *)MemHead->pStart); /* read from rtl */
}
}
}
/* reset bnry */
bnry = Head[1] - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
WriteReg(BNRY_WPAGE0,bnry);
WriteReg(ISR_WPAGE0,0xFF); /* write FF to clear up all interrupt status */
Enable_IRQ();
return MemHead;
} 答 11: 谢谢pengyuchun! 我把寄存器的读写函数都和你用的一样了,可还是不行,写进和读出就是不一样,ping都不能实现。我可真够蠢的,真想踹自己两脚,可惜踹不上。 答 12: 能否把程序email给我?谢谢!
调试看从8019读出的都是0505,不知道什么原因。第一次接触,请各位多指点
谢谢! 答 1: 搞过的兄弟说一下吧? 答 2: 8019的驱动对不对啊?8019的驱动对不对啊?
8019的远程DMA设置成8位还是16位啊? 答 3: DMA为16位,板上2210的A1接到8019的A0上的 答 4: 8019驱动的问题看看能不能读写寄存器 答 5: 读写寄存器的函数都是周工用的 我试了一下,在8019初始化函数中,每写一次寄存器后,就读相应寄存器,将读出的数用串口送出来,但是读出的和写进的不一样,我想周工的函数不会有问题的,不知道怎么回事? 答 6: dma改成8位也不行,读出来的都是0x04;郁闷 答 7: 读写和初始化函数void WriteToNet(uint8 ADDR_16,uint8 WRITEDATA)
{
(*((volatile unsigned short *) NET_BASE_ADDR+ADDR_16)) =WRITEDATA;
}
uint8 ReadFromNet(uint8 ADDR_16)
{
uint8 temp;
temp=(*((volatile unsigned short *)NET_BASE_ADDR+ADDR_16));//0x83400000
return (temp);
}
void etherdev_init()
{
uint8 i;
uint8 j;
//PINSEL0 = 0x00000005; // 设置所有管脚连接GPIO
//PINSEL1 = 0x00000000;
//IODIR=IODIR|(NET_DATA+NET_CS+NET_WR+NET_ALE+NET_RD+NET_RST);
//IOSET=NET_DATA+NET_CS+NET_WR+NET_ALE+NET_RD+NET_RST;
IODIR=IODIR|NET_RST;
IOCLR=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOSET=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOCLR=NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
WriteToNet(0x1f,0x00);
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
/**********************************************************************
1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
位: 7 6 5 4 3 2 1 0
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
0 0 1 : 读网卡内存
0 1 0 : 写网卡内存
0 1 1 : 发送网卡数据包
1 * * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP: 这两个位用来启动命令或停止命令
1 0 启动命令
0 1 停止命令
//============================================
********************************************************/
WriteToNet(0x00,0x21); //使芯片处于停止模式,这时进行寄存器设置
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
} //延时10毫秒,确保芯片进入停止模式
page(0);
WriteToNet(0x0a,0x00); //清rbcr0
WriteToNet(0x0b,0x00); //清rbcr1
WriteToNet(0x0c, 0xe0); //RCR,监视模式,不接收数据包
WriteToNet(0x0d, 0xe2); //TCR,loop back模式
page(0);
WriteToNet(0x01,0x4c); //PSTART=0X4C
WriteToNet(0x02,0x80); //PSTOP=0X80
WriteToNet(0x03,0x4c); //bnry=0x4c;
page(0);
WriteToNet(0x04,0x40); //TPSR,发送起始页寄存器
WriteToNet(0x07,0xff); //清除所有中断标志位,中断状态寄存器
WriteToNet(0x0f,0x11); //中断屏蔽寄存器清0,禁止中断
WriteToNet(0x0e,0xca); // 数据配置寄存器,8位dma方式 16 0xcb
page(1);
WriteToNet(0x07,0x4d); //curr=0x4d
WriteToNet(0x08,0x00);
WriteToNet(0x09,0x00);
WriteToNet(0x0a,0x00);
WriteToNet(0x0b,0x00);
WriteToNet(0x0c,0x00);
WriteToNet(0x0d,0x00);
WriteToNet(0x0e,0x00);
WriteToNet(0x0f,0x00);
WriteToNet(0x00,0x22); //这时让芯片开始工作
SetMacID(); //将芯片物理地址写入到MAR寄存器
page(0);
WriteToNet(0x0c,0xcc); //将芯片设置成正常模式,跟外部网络连接
WriteToNet(0x0d,0xe0);
WriteToNet(0x00,0x22); //启动芯片开始工作
WriteToNet(0x07,0xff); //清除所有中断标志位
}
答 8: re改成这样,试试:
void WriteToNet(uint8 ADDR_16,uint8 WRITEDATA)
{
(*((volatile unsigned short *) NET_BASE_ADDR+(ADDR_16<<1))) =WRITEDATA;
}
uint8 ReadFromNet(uint8 ADDR_16)
{
uint8 temp;
temp=(*((volatile unsigned short *)NET_BASE_ADDR+(ADDR_16<<1)));//0x83400000
return (temp);
}
答 9: 不用这样写吧?我看过汇编的,因为NET_BASE_ADDR是unsigned short型的,所以ADS会把
ADD_16左移一位后再加给NET_BASE_ADDR的的 答 10: re以下是我改写的,已经成功应用,DMA为8位。你参考一下。
#define NET_BASE_ADDR 0x83400000
/* 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 BYTE DT_XDATA InSending;
/* receive head information */
/*struct RTLReceiveHeader
{
BYTE ReceiveStatus;
BYTE NextPacketStartPage;
BYTE PacketSizeLow;
BYTE PacketSizeHigh;
}Head;for some unknown resean Head must be a gloal value. */
static BYTE DT_XDATA Head[4];
/****************************************************************************
* 名称:WriteToNet()
* 功能:把数据写入RTL8019AS
* 入口参数: ADDR 写入地址
WRITEDATA 写入数据
* 出口参数:无
****************************************************************************/
void WriteReg(BYTE ADDR_16,BYTE WRITEDATA)
{
*((volatile unsigned char *) NET_BASE_ADDR+(ADDR_16<<1))=WRITEDATA;//0x83400000
}
/****************************************************************************
* 名称:ReadFromNet()
* 功能:从RTL8019AS把数据读出
* 入口参数: ADDR 读出地址
* 出口参数: READDATA 读出数据
****************************************************************************/
BYTE ReadReg(BYTE ADDR_16)
{
BYTE temp;
temp=*((volatile unsigned char *)NET_BASE_ADDR+(ADDR_16<<1));//0x83400000
return (temp);
}
/**********************************************************************
**函数原型: void page(uchar pagenumber)
**入口参数:?uchar pagenumber: 要切换的页
**出口参数: 无
**返 回 值: 无
**说 明: 选择页,可选择0,1,2三页,第四页ne000兼容芯片保留
************************************************************************/
void RTLPage(BYTE pagenumber)
{
BYTE temp;
temp=ReadReg(0);//command register
temp=temp&0x3B ;//注意txp位不能要
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
WriteReg(0,temp);
}
#define page RTLPage
#define WriteToNet WriteReg
/* reset rtl8019 and init registers, LocalMacAddr is MAC address */
void RTLInit(BYTE LocalMACAddr[]) REENTRANT_MUL
{
BYTE i;
BYTE j;
IODIR=IODIR|GPIO_NET_RST;
IOCLR=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOSET=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOCLR=GPIO_NET_RST;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
WriteToNet(0x1f,0x00);
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
/**********************************************************************
1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
位: 7 6 5 4 3 2 1 0
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
0 0 1 : 读网卡内存
0 1 0 : 写网卡内存
0 1 1 : 发送网卡数据包
1 * * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP: 这两个位用来启动命令或停止命令
1 0 启动命令
0 1 停止命令
//============================================
********************************************************/
WriteToNet(0x00,0x21); //使芯片处于停止模式,这时进行寄存器设置
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
} //延时10毫秒,确保芯片进入停止模式
page(0);
WriteToNet(0x0a,0x00); //清rbcr0
WriteToNet(0x0b,0x00); //清rbcr1
WriteToNet(0x0c, 0xe0); //RCR,监视模式,不接收数据包
WriteToNet(0x0d, 0xe2); //TCR,loop back模式
page(0);
WriteToNet(0x01,0x4c); //PSTART=0X4C
WriteToNet(0x02,0x80); //PSTOP=0X80
WriteToNet(0x03,0x4c); //bnry=0x4c;
page(0);
WriteToNet(0x04,0x40); //TPSR,发送起始页寄存器
WriteToNet(0x07,0xff); //清除所有中断标志位,中断状态寄存器
WriteToNet(0x0f,0x11); //中断屏蔽寄存器清0,禁止中断
WriteToNet(0x0e,0xc8); // 数据配置寄存器,8位dma方式
page(1);
WriteToNet(0x07,0x4d); //curr=0x4d
WriteToNet(0x08,0x00);
WriteToNet(0x09,0x00);
WriteToNet(0x0a,0x00);
WriteToNet(0x0b,0x00);
WriteToNet(0x0c,0x00);
WriteToNet(0x0d,0x00);
WriteToNet(0x0e,0x00);
WriteToNet(0x0f,0x00);
WriteToNet(0x00,0x22); //这时让芯片开始工作
page(1);
WriteReg(0x01,LocalMACAddr[0]);
WriteReg(0x02,LocalMACAddr[1]);
WriteReg(0x03,LocalMACAddr[2]);
WriteReg(0x04,LocalMACAddr[3]);
WriteReg(0x05,LocalMACAddr[4]);
WriteReg(0x06,LocalMACAddr[5]);
page(0);
WriteToNet(0x0c,0xcc); //将芯片设置成正常模式,跟外部网络连接
WriteToNet(0x0d,0xe0);
WriteToNet(0x00,0x22); //启动芯片开始工作
WriteToNet(0x07,0xff); //清除所有中断标志位
}
/* write buffer to rlt ram */
void RTLWriteRam(WORD address, WORD size, BYTE * buff) REENTRANT_SIG
{
BYTE *Endp;
BYTE PrePage; /* store page */
PrePage = ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(BYTE)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)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(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
}
/* read rlt ram data to buffer */
void RTLReadRam(WORD address,WORD size,BYTE DT_XDATA * buff) REENTRANT_MUL
{
BYTE DT_XDATA * Endp;
BYTE PrePage; /* store page */
PrePage = ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(BYTE)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)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. */
BOOL RTLSendPacket(void DT_XDATA * buffer,WORD size) REENTRANT_SIG
{
BYTE PrePage;
BYTE LastSendStartPage; /*上次发送使用的开始页*/
BYTE CurrSendStartPage; /*本次发送使用的开始页*/
/* 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 */
RTLPage(2);
LastSendStartPage = ReadReg(TPSR_RPAGE2);
if(LastSendStartPage == SEND_START_PAGE0)
{
CurrSendStartPage = SEND_START_PAGE1;
}
else
{
CurrSendStartPage = SEND_START_PAGE0;
}
RTLWriteRam((WORD)(((WORD)CurrSendStartPage)<<8),size,buffer); //数据写进发送起始RAM
/* wait for last time trasmition to complete */
while((ReadReg(CR) & CR_TXP) == CR_TXP);
/* write trasmit start page and size */
RTLPage(0);
WriteReg(TPSR_WPAGE0,CurrSendStartPage); /* TPSR */ //发送起始地址寄存器置位
WriteReg(TBCRL_WPAGE0,(BYTE)size);/*low */
WriteReg(TBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff)); /*high*/
WriteReg(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_TXP | CR_START_COMMAND));
InSending = FALSE;
return TRUE;
}
/* call this function to receive a ethernet packet from RTL8019.
return value:
NULL: no packet CAN receive yet.
not NULL:
a address point to MemHead. This Head contain merory
Imformation(memory start address, memory end address ...) of
received packet. Memory is allocated by function 'MemAllocate(WORD size)'.
a example of struct SMemHead is:
struct SMemHead
{
BOOL used; // if in using
BYTE DT_XDATA *pStart; // the start address of memory
BYTE DT_XDATA *pEnd;
};
You CAN use your own struct SMemHead and MemAllocat function in your project.
*/
struct SMemHead DT_XDATA * RTLReceivePacket(void) REENTRANT_SIG
{
BYTE curr,bnry;
WORD address;
WORD PacketSize;
struct SMemHead DT_XDATA *MemHead;
BYTE ii;
/* if send is running don't crrupt RTL register*/
if(InSending == TRUE)
{
return NULL;
}
MemHead = NULL;
Disable_IRQ();
RTLPage(0);
ii=ReadReg(ISR_RPAGE0); //读取中断状态
if((ii&0x90)!=0) //如果复位或益出就重新初试化
{
RTLInit(EtherAddr); //重新初始化
Enable_IRQ();
return NULL;
}
bnry = ReadReg(BNRY_RPAGE0);
RTLPage(1);
curr = ReadReg(CURR_RPAGE1);
RTLPage(0);
if(curr == 0){
Enable_IRQ();
return NULL;
}
bnry++;
if(bnry >= RECEIVE_STOP_PAGE)
{
bnry = RECEIVE_START_PAGE;
}
/* check if there is packets to read */
if(bnry == curr){
Enable_IRQ();
return NULL;
}
/*
* read a packet
*/
/* read packet head imformation */
address = ((WORD)bnry)<<8;
RTLReadRam(address,4,Head);
/* check rsr, if isn't a good packet no read */
if(Head[0] & RSR_RECEIVE_NO_ERROR)
{
/* this is a good packet */
/* packet size, sub 4 bytes, this 4 byte is MAC checksum */
PacketSize = ((WORD)Head[3])*256 + Head[2] - 4;
/* allocate buffer and read packet into buffer */
if((MemHead = MemAllocate(PacketSize)) != NULL)
{
/* if packet is put from bnry+1 to receive_stop_page and receive
start page to next packet startpage, that is if bnry+1 > next
packet start page and next start page != receive_start_page,
we need read by two times. the first time from bnry+1 to receive
_stop_page, the second time from receive start page to next packet
startpage.
*/
address += 4;
if(bnry > Head[1] && Head[1] != RECEIVE_START_PAGE)
{
RTLReadRam(address,(WORD)((((WORD)RECEIVE_STOP_PAGE)<<8) - address),(BYTE *)MemHead->pStart); /* read from rtl */
RTLReadRam((WORD)(((WORD)RECEIVE_START_PAGE)<<8),(WORD)(PacketSize - ((((WORD)RECEIVE_STOP_PAGE)<<8) - address)),
(BYTE *)MemHead->pStart + ((((WORD)RECEIVE_STOP_PAGE)<<8) - address)); /* read from rtl */
}
else
{
RTLReadRam(address,PacketSize,(BYTE *)MemHead->pStart); /* read from rtl */
}
}
}
/* reset bnry */
bnry = Head[1] - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
WriteReg(BNRY_WPAGE0,bnry);
WriteReg(ISR_WPAGE0,0xFF); /* write FF to clear up all interrupt status */
Enable_IRQ();
return MemHead;
} 答 11: 谢谢pengyuchun! 我把寄存器的读写函数都和你用的一样了,可还是不行,写进和读出就是不一样,ping都不能实现。我可真够蠢的,真想踹自己两脚,可惜踹不上。 答 12: 能否把程序email给我?谢谢!
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |