⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etherdev.c

📁 移植uIP1.0到51单片机上的版本mcu_netV1.00 uIP ARP / ICMP / TCP协议的完全移植
💻 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 + -