📄 etherdev.c
字号:
#include "uip.h"
#include "etherdev.h"
/*RTL8019的复位管脚*/
sbit rst_pin = P1^6;
static void etherdev_delay_ms(unsigned int count);
static unsigned int etherdev_poll(void);
void page( u8_t pagenumber );
void etherdev_reset(void)
{
/*将复位管脚拉高100ms来复位芯片*/
rst_pin = 1;
etherdev_delay_ms(100);
rst_pin = 0;
etherdev_delay_ms(100);
}
/*页面设置函数,pnum为0-3*/
void page(u8_t pnum)
{
u8_t temp;
temp = CR;
temp=temp & (~(PS1|PS0|TXP)); /*TXP位也应该清0,防止发送数据*/
pnum = pnum <<6;
CR = temp | pnum;
}
/*以毫秒计算延时*/
static void etherdev_delay_ms(unsigned int count)
{
for(count *= ETH_DELAY_MULTPLR; count > 0; count--) continue;
return;
}
/*网卡初始化函数*/
void etherdev_init(void)
{
/*先复位芯片*/
etherdev_reset( );
/*先停止收发*/
CR = RD2|STP;
page(0);
/* 40H页到45H页共1536(6x256)个字节为发送缓存,其余为接收缓存*/
/*这样发送缓存可以容纳最长的一个以太网数据帧。*/
/*设置接收缓存的起始和结束地址*/
PSTART = ETH_RX_PAGE_START;
PSTOP = ETH_RX_PAGE_STOP;
/*BNRY指向接收缓存的首页*/
BNRY = ETH_RX_PAGE_START;
/*TPSR,发送缓存区首地址*/
TPSR = ETH_TX_PAGE_START;
RBCR1 = 0x00;
RBCR0 = 0x00;
/*RCR接收配置寄存器1100 1100,*/
/*接收广播包,组播包,目的MAC与本机相同的包,*/
/*接收包不小于64字节,包有接收错误不接收*/
RCR = 0xcc;
/*TCR传输配置寄存器 1110 0000*/
/*普通模式,发送时附加CRC*/
TCR = 0xe0;
/*DCR数据配置寄存器 1100 1000*/
/* 8位数据dma,字节长度的DMA传输*/
DCR = 0xc8;
/*IMR关所有中断*/
IMR = 0x00;
page(1);
/*CURR 指向接收缓存的首页*/
CURR = ETH_RX_PAGE_START;
/*组播地址寄存器*/
MAR0 = 0x00;
MAR1 = 0x41;
MAR2 = 0x00;
MAR3 = 0x00;
MAR4 = 0x00;
MAR5 = 0x00;
MAR6 = 0x00;
MAR7 = 0x00;
/****Write MAC address 以下为写入MAC地址*****/
PAR0 = UIP_ETHADDR0;
PAR1 = UIP_ETHADDR1;
PAR2 = UIP_ETHADDR2;
PAR3 = UIP_ETHADDR3;
PAR4 = UIP_ETHADDR4;
PAR5 = UIP_ETHADDR5;
page(0);
CR = RD2|STA;
/*ISR清所有中断*/
ISR = 0xff;
}
/*网卡发包函数*/
void etherdev_send(void)
{
u16_t i;
u8_t *ptr;
ptr = uip_buf;
page(0);
/*先结束远程DMA*/
CR = RD2 | STA;
/*等待上次发送完成*/
while(CR & TXP) continue;
/*清远程DMA中断标志*/
ISR |= RDC;
/*启动远程写,将数据写到RAM BUFFER中*/
RSAR0 = 0x00;
RSAR1 = ETH_TX_PAGE_START;
RBCR0 = (u8_t)(uip_len & 0xFF);
RBCR1 = (u8_t)(uip_len >> 8 );
CR = RD1 | STA;
/*uIP将要发送的TCP头部数据放到uip_buf中,
同时用uip_appdata指向应用层数据*/
for(i = 0; i < uip_len; i++)
{
if(i == 40 + UIP_LLH_LEN)
{
ptr = (u8_t *)uip_appdata;
}
RDMA_REG = *ptr++;
}
/*等待远程DMA操作完成*/
while(!(ISR & RDC)) continue;
CR = RD2 | STA;
/*配置网卡发送数据包*/
TPSR = ETH_TX_PAGE_START;
if(uip_len < ETH_MIN_PACKET_LEN)
{
uip_len = ETH_MIN_PACKET_LEN;
}
TBCR0 = (u8_t)(uip_len & 0xFF);
TBCR1 = (u8_t)(uip_len >> 8);
CR = RD2|RD1|RD0|TXP|STA;
}
/*网卡收包函数*/
u16_t etherdev_read(void)
{
u16_t len = 0;
u8_t status;
u8_t retransmit = 0;
/*检查接收是否正确*/
if(ISR & PRX)
{
/*检查接收缓存是否满了*/
if(ISR & OVW)
{
CR = RD2|STP;
RBCR0 = 0x00;
RBCR1 = 0x00;
while(!(ISR & RST)) continue;
if(CR & TXP)
{
/*发送失败*/
if(!((ISR & PTX)|| (ISR & TXE)))
{
retransmit = 1;
}
}
TCR = LB0;
CR = RD2|STA;
BNRY = ETH_RX_PAGE_START;
page(1);
CURR = ETH_RX_PAGE_START;
page(0);
/*清中断标志*/
ISR = PRX | OVW;
TCR = 0x00;
if(retransmit)
{
CR = RD2|TXP|STA;
}
}
else
{
u16_t i;
u8_t next_rx_packet;
u8_t current;
ISR = RDC;
/*先读RTL8019添加的4个字节*/
RSAR0 = 0x00;
RSAR1 = BNRY;
RBCR0 = 0x04;
RBCR1 = 0x00;
/*获取本帧数据的长度和下一帧页地址*/
CR = RD0 | STA;
status = RDMA_REG;
next_rx_packet = RDMA_REG;
len = (RDMA_REG); //RDMA);
len += (RDMA_REG<<8);//<< 8;
len -= 4;
/*等待远程DMA操作完成*/
while(!(ISR & RDC)) continue;
CR = RD2 | STA;
if(len <= UIP_BUFSIZE)
{
ISR = RDC;
RSAR0 = 0x04;
RSAR1 = BNRY;
RBCR0 = (u8_t)(len & 0xFF);
RBCR1 = (u8_t)(len >> 8);
CR = RD0 | STA;
/*启动远程读数据*/
for(i = 0; i < len; i++)
{
*(uip_buf + i) = RDMA_REG;
}
while(!(ISR & RDC)) continue;
CR = RD2 | STA;
}
else
{
len = 0;
}
/*更新BNRY*/
BNRY = next_rx_packet;
page(1);
current = CURR;
page(0);
/*RAM BUFFER中没有数据时清PRX*/
if(next_rx_packet == current)
{
ISR = PRX;
}
}
}
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -