本人花了半个多月的时间,对RTL8019AS上的控制状态寄存器进行了仔细的琢磨,终于有了点心得体会,在这里和大家共享! 本人是在周立功的EASYARM2200上做的实验的: 下面是RTL8019AS的相关源代码: ---------------------------------------------------------------------
#include "config.h" #include "LPC2294.h" #include "general.h"
#define INT_N 0x00000080 #define NET_RST 0x00000040 #define NET_BASE_ADDR 0x83400000
//{0x52,0x54,0x4c,0x19,0xf7,0x44}
#define The_PAR0 0x52 #define The_PAR1 0x54 #define The_PAR2 0x4C #define The_PAR3 0x19 #define The_PAR4 0xF7 #define The_PAR5 0x44
uint8 Tx_Buff_Page = 0x46;
void WriteToNet(uint8 ADDR_16, uint16 WRITEDATA) { (*((volatile unsigned short *)NET_BASE_ADDR + ADDR_16)) = WRITEDATA; //0x83400000 return; }
uint16 ReadFromNet(uint8 ADDR_16) { uint16 temp_uint16;
temp_uint16 = (*((volatile unsigned short *)NET_BASE_ADDR + ADDR_16)); //0x83400000
return temp_uint16; }
void SetPage(uint8 pagenumber) { uint8 temp_uint8;
temp_uint8 = ReadFromNet(0); //command register temp_uint8 = temp_uint8 & 0x3B; //注意txp位不能要 pagenumber = pagenumber << 6; temp_uint8 = temp_uint8 | pagenumber; WriteToNet(0, temp_uint8);
return; }
void InitNic(void) { int temp_i; PINSEL0 = PINSEL0 & ~0x0000F000; IO0DIR = (IO0DIR & ~INT_N) | NET_RST; IO0CLR = NET_RST; for (temp_i = 0; temp_i < 40000; temp_i++);
IO0SET = NET_RST; for (temp_i = 0; temp_i < 40000; temp_i++);
IO0CLR = NET_RST; for (temp_i = 0; temp_i < 40000; temp_i++);
WriteToNet(0x1F, 0x00); for (temp_i = 0; temp_i < 40000; temp_i++); WriteToNet(0x00, 0x21); //使芯片处于停止模式,这时进行寄存器设置 for (temp_i = 0; temp_i < 40000; temp_i++);
SetPage(0); ///////////////////////////////////////////// WriteToNet(0x0F, 0x00); WriteToNet(0x07, 0xFF); /////////////////////////////////// WriteToNet(0x0E, 0xCB); //DCR ??? //WriteToNet(0x0E, 0xDB); WriteToNet(0x0C, 0xE0); //RCR ??? WriteToNet(0x0D, 0xE0); //TCR ??? /////////////////////////////////// WriteToNet(0x01, 0x4C); WriteToNet(0x02, 0x80); WriteToNet(0x03, 0x4C);
WriteToNet(0x09, 0x40); WriteToNet(0x08, 0x00); WriteToNet(0x0B, 0x00); WriteToNet(0x0A, 0x00);
WriteToNet(0x04, 0x40); WriteToNet(0x06, 0x00); WriteToNet(0x05, 0x00); ///////////////////////////////////////////// SetPage(1); ///////////////////////////////////////////// //||判断是否错误的计数???|| //WriteToNet(0x07, 0x4D); WriteToNet(0x07, 0x4C); //||************************|| /////////////////////////////////// WriteToNet(0x01, The_PAR0); WriteToNet(0x02, The_PAR1); WriteToNet(0x03, The_PAR2); WriteToNet(0x04, The_PAR3); WriteToNet(0x05, The_PAR4); WriteToNet(0x06, The_PAR5); /////////////////////////////////// WriteToNet(0x08, 0x00); WriteToNet(0x09, 0x00); WriteToNet(0x0A, 0x00); WriteToNet(0x0B, 0x00); WriteToNet(0x0C, 0x00); WriteToNet(0x0D, 0x00); WriteToNet(0x0E, 0x00); WriteToNet(0x0F, 0x00); ///////////////////////////////////////////// SetPage(0); WriteToNet(0x0C, 0xC4); //RCR ??? WriteToNet(0x07, 0xFF); WriteToNet(0x00, 0x22);
Tx_Buff_Page = 0x46;
return; }
void Send_Packet(uint16 * buf, uint32 len) { uint32 temp_len; int temp_i, temp_j;
if (len < 60) len = 60; if (len & 1) len++; temp_len = len >> 1; if (Tx_Buff_Page == 0x40) Tx_Buff_Page = 0x46; else Tx_Buff_Page = 0x40;
SetPage(0); //切换至第0页
WriteToNet(0x09, Tx_Buff_Page); //设置发送页地址 WriteToNet(0x08, 0x00); //写入RSAR0 WriteToNet(0x0b, len >> 8); //写入RSCR1 WriteToNet(0x0a, len & 0xFF); //写入RSCR0 WriteToNet(0x00, 0x12); //启动DMA写write dma, page0
for (temp_i = 0; temp_i < temp_len; temp_i++) WriteToNet(0x10, *buf++); //||判断是否是多余的操作???|| //WriteToNet(0x0b, 0x00); //WriteToNet(0x0a, 0x00); //WriteToNet(0x00, 0x22); //结束或放弃DMA操作 //||**************************|| WriteToNet(0x04, Tx_Buff_Page); //txd packet start; WriteToNet(0x06, len >> 8); //high byte counter WriteToNet(0x05, len & 0xFF); //low byte counter
WriteToNet(0x07, 0xFF); //||是否有多余的位???|| //WriteToNet(0x00, 0x3E); //to sendpacket; WriteToNet(0x00, 0x26); //||********************|| for (temp_i = 0; temp_i < 6; temp_i++) //最多重发6次 { for (temp_j = 0; temp_j < 1000; temp_j++) { if ((ReadFromNet(0) & 0x04) == 0) //检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃 break; }
if (ReadFromNet(0x04) & 0x01) //表示发送成功,判断发送状态寄存器TSR,决定是否出错 break;
//||是否有多余的位???|| //WriteToNet(0x00,0x3E); //to sendpacket; WriteToNet(0x00, 0x26); //||********************|| } WriteToNet(0x07, 0xFF); return; }
int Rec_Packet(uint16 * buf) { uint8 temp_BNRY, temp_CURR; uint16 temp_buf0, temp_buf1; uint32 temp_len; uint8 temp_uint8; int temp_i;
SetPage(0); /* temp_uint8 = ReadFromNet(0x07); //读取中断状态 if (temp_uint8 & 0xAC) { InitNic(); return -1; } */
temp_BNRY = ReadFromNet(0x03); //bnry page have read 读页指针 SetPage(1); temp_CURR = ReadFromNet(0x07); //curr writepoint 8019写页指针 SetPage(0);
//||判断是否多余的操作???|| //temp_BNRY++; //bnry++; //if (temp_BNRY > 0x7F) // temp_BNRY = 0x4C; //||************************|| if (temp_BNRY != temp_CURR) //此时表示有新的数据包在缓冲区里 { WriteToNet(0x09, temp_BNRY); //RSAR1写入读页地址的高字节 WriteToNet(0x08, 0x00); //RSAR0写入读页地址的低字节 WriteToNet(0x0b, 0x00); //RSCR1写入读取字节计数高字节 WriteToNet(0x0a, 0x04); //RSCR0写入读取字节计数低字节 WriteToNet(0x00, 0x0a); //启动Remote DMA读操作
temp_buf0 = ReadFromNet(0x10); temp_buf1 = ReadFromNet(0x10);
//||判断是否是多余的操作???|| //WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节 //WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节 //WriteToNet(0x00,0x22); //结束或放弃DMA操作 //||**************************||
temp_buf1 = temp_buf1 - 4; if (((temp_buf0 & 0x0001) == 0) || ((temp_buf0 & 0xFF00) < 0x4C00) || ((temp_buf0 & 0xFF00) > 0x7F00) || ( temp_buf1 > 0x0600)) { SetPage(1); temp_CURR = ReadFromNet(0x07); //page1读取CURR的值 SetPage(0); //切换回page0 //||判断是否多余的操作???|| //temp_BNRY = temp_CURR - 1; //把bnry恢复为下16K中的空余部分 //if (temp_BNRY < 0x4C) // temp_BNRY = 0x7F; temp_BNRY = temp_CURR; //||************************|| WriteToNet(0x03, temp_BNRY); //把BNRY恢复到指向下一帧write to bnry WriteToNet(0x07, 0x7F); //清除中断标志
return -1; } else //表示数据包是完好的.读取剩下的数据 { if (temp_buf1 & 1) temp_buf1++; temp_len = temp_buf1 >> 1;
WriteToNet(0x09, temp_BNRY); //RSAR1写入读页地址的高字节//read page address high WriteToNet(0x08, 0x04); //RSAR0写入读页地址的低字节//read page address low WriteToNet(0x0b, temp_buf1 >> 8); //RSCR1写入读取字节计数高字节//read count high WriteToNet(0x0a, temp_buf1 & 0xFF); //RSCR0写入读取字节计数低字节//read count low; WriteToNet(0x00, 0x0a); //启动Remote DMA读操作 for (temp_i = 0; temp_i < temp_len; temp_i++) *buf++ = ReadFromNet(0x10);
//||判断是否是多余的操作???|| //WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节//read count high //WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节//read count low; //WriteToNet(0x00,0x22); //结束或放弃DMA操作//结束或放弃DMA //||**************************||
//||判断是否是多余的操作???|| //temp_BNRY = (temp_buf0 >> 8) - 1; //if (temp_BNRY < 0x4C) // temp_BNRY = 0x7F; temp_BNRY = (temp_buf0 >> 8); //||**************************|| WriteToNet(0x03, temp_BNRY); WriteToNet(0x07, 0x7F);
return temp_buf1; } } else return 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////// int Rec_Packet_0(uint16 * buf) { uint8 temp_BNRY, temp_CURR; uint16 temp_buf0, temp_buf1; uint32 temp_len; uint8 temp_uint8; int temp_i;
SetPage(0); /* temp_uint8 = ReadFromNet(0x07); //读取中断状态 if (temp_uint8 & 0xAC) { InitNic(); return -1; } */
temp_BNRY = ReadFromNet(0x03); //bnry page have read 读页指针 SetPage(1); temp_CURR = ReadFromNet(0x07); //curr writepoint 8019写页指针 SetPage(0);
//||判断是否多余的操作???|| //temp_BNRY++; //bnry++; //if (temp_BNRY > 0x7F) // temp_BNRY = 0x4C; //||************************|| if (temp_BNRY != temp_CURR) //此时表示有新的数据包在缓冲区里 { //WriteToNet(0x0B, 0x0F); WriteToNet(0x00, 0x1A); //WriteToNet(0x09, temp_BNRY); //RSAR1写入读页地址的高字节 //WriteToNet(0x08, 0x00); //RSAR0写入读页地址的低字节 //WriteToNet(0x0b, 0x00); //RSCR1写入读取字节计数高字节 //WriteToNet(0x0a, 0x04); //RSCR0写入读取字节计数低字节 //WriteToNet(0x00, 0x0a); //启动Remote DMA读操作
temp_buf0 = ReadFromNet(0x10); temp_buf1 = ReadFromNet(0x10);
//||判断是否是多余的操作???|| //WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节 //WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节 //WriteToNet(0x00,0x22); //结束或放弃DMA操作 //||**************************||
//temp_buf1 = temp_buf1 - 4; if (((temp_buf0 & 0x0001) == 0) || ((temp_buf0 & 0xFF00) < 0x4C00) || ((temp_buf0 & 0xFF00) > 0x7F00) || ( temp_buf1 > 0x0600)) { WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节 WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节 WriteToNet(0x00,0x22); //结束或放弃DMA操作 SetPage(1); temp_CURR = ReadFromNet(0x07); //page1读取CURR的值 SetPage(0); //切换回page0 //||判断是否多余的操作???|| //temp_BNRY = temp_CURR - 1; //把bnry恢复为下16K中的空余部分 //if (temp_BNRY < 0x4C) // temp_BNRY = 0x7F; temp_BNRY = temp_CURR; //||************************|| WriteToNet(0x03, temp_BNRY); //把BNRY恢复到指向下一帧write to bnry WriteToNet(0x07, 0xFF); //清除中断标志
return -1; } else //表示数据包是完好的.读取剩下的数据 { if (temp_buf1 & 1) temp_buf1++; temp_len = temp_buf1 >> 1;
//WriteToNet(0x09, temp_BNRY); //RSAR1写入读页地址的高字节//read page address high //WriteToNet(0x08, 0x04); //RSAR0写入读页地址的低字节//read page address low //WriteToNet(0x0b, temp_buf1 >> 8); //RSCR1写入读取字节计数高字节//read count high //WriteToNet(0x0a, temp_buf1 & 0xFF); //RSCR0写入读取字节计数低字节//read count low; //WriteToNet(0x00, 0x0a); //启动Remote DMA读操作 for (temp_i = 0; temp_i < temp_len; temp_i++) *buf++ = ReadFromNet(0x10);
//||判断是否是多余的操作???|| //WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节//read count high //WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节//read count low; //WriteToNet(0x00,0x22); //结束或放弃DMA操作//结束或放弃DMA //||**************************||
//||判断是否是多余的操作???|| //temp_BNRY = (temp_buf0 >> 8) - 1; //if (temp_BNRY < 0x4C) // temp_BNRY = 0x7F; //temp_BNRY = (temp_buf0 >> 8); //||**************************|| //WriteToNet(0x03, temp_BNRY); WriteToNet(0x07, 0xFF);
return temp_buf1; } } else return 0; }
///////////////////////////////////////////////////////////////////////////////////////////////////////
--------------------------------------------------------------------- |