导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→求助,8019网卡驱动问题[zlinghe]

 *第37260篇: 求助,8019网卡驱动问题

  
楼 主:zlinghe 2006年1月18日12:36
 求助,8019网卡驱动问题
我现在用51控制8019网卡芯片,采用查询方式收数据。但接收数据的时候只能收几个数据包,然后收到的4个字节的包头就不对了,再往后就干脆全为零了,之后CURR寄存器就为0XFF了。郁闷,到底是怎么回事呢?
这是相关的几个函数:
//8019初始化函数
void RTLInit(BYTE LocalMACAddr[])
{
//    BYTE temp;
//    int i;
    
    NET_RST=1;
    delayms(2);
    NET_RST=0;
    delayms(100);

    /* init RTL registers*/
    WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND)); /* set page0, stop command. command is stop after power up. */
    delayms(10);   //确保芯片进入停止状态

    WriteReg(DCR_WPAGE0,        0xC8);    /* DCR: refer to define of DCR in Rtl8019as.h */
    
    WriteReg(RBCRH_WPAGE0,0);
    WriteReg(RBCRL_WPAGE0,0);
    
    //使芯片与网络断开
    WriteReg(RCR_WPAGE0,        0x20);    /* RCR: refer to define of RCR in Rtl8019as.h */
    WriteReg(TCR_WPAGE0,        0x02);    /* TCR: refer to define of TCR in Rtl8019as.h */
    
    WriteReg(PSTART_WPAGE0,    RECEIVE_START_PAGE);    /* Pstart    */
    WriteReg(PSTOP_WPAGE0,    RECEIVE_STOP_PAGE);        /* Pstop    *///0x80也可以使用
    WriteReg(BNRY_WPAGE0,        RECEIVE_START_PAGE);    /* BNRY        */
    WriteReg(TPSR_WPAGE0,        SEND_START_PAGE0);    /* TPSR        */
    
    WriteReg(ISR_WPAGE0,        0xFF);    /* write FF to clear up all interrupt status */
    WriteReg(IMR_WPAGE0,0x0);

    WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND)); 

    WriteReg(CURR_WPAGE1,RECEIVE_START_PAGE + 1);    

    /* set phisical address */
    WriteReg(PRA0_WPAGE1,LocalMACAddr[0]);
    WriteReg(PRA1_WPAGE1,LocalMACAddr[1]);
    WriteReg(PRA2_WPAGE1,LocalMACAddr[2]);
    WriteReg(PRA3_WPAGE1,LocalMACAddr[3]);
    WriteReg(PRA4_WPAGE1,LocalMACAddr[4]);
    WriteReg(PRA5_WPAGE1,LocalMACAddr[5]);

    /* MAR0 */
    WriteReg(0x07, 0xff);
    WriteReg(0x08, 0xff);
    WriteReg(0x09, 0xff);
    WriteReg(0x0a, 0xff);
    WriteReg(0x0b, 0xff);
    WriteReg(0x0c, 0xff);
    WriteReg(0x0d, 0xff);
    WriteReg(0x0e, 0xff);
    WriteReg(0x0f, 0xff);
    
    WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND)); 

    WriteReg(RCR_WPAGE0,        0xCC);    /* RCR: refer to define of RCR in Rtl8019as.h */
    WriteReg(TCR_WPAGE0,        0x00);    /* TCR: refer to define of TCR in Rtl8019as.h */

    /* transimit start page */
    LastSendStartPage = SEND_START_PAGE0;
    StartPageOfPacket = RECEIVE_START_PAGE + 1;

    /* in the beginning, no packet is in sending */
    InSending = FALSE;
    
    /* initial over, start command and receive */
    WriteReg(ISR_WPAGE0,        0xFF);    /* write FF to clear up all interrupt status */
}

/* read rlt ram data to buffer */
void RTLReadRam(WORD address,WORD size,BYTE DT_XDATA * buff)
{
    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);    
}

//接收函数
struct SMemHead DT_XDATA * RTLReceivePacket(void) REENTRANT_SIG
{
    BYTE curr,bnry,flag;
    WORD address;
    WORD PacketSize;
    struct SMemHead DT_XDATA *MemHead;

    /* if send is running don't crrupt RTL register*/
    if(InSending == TRUE)
        return NULL;

    MemHead = NULL;
    //让芯片停止工作
    WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND));
    curr = ReadReg(CURR_RPAGE1);

    //检查当前接收地址是否超出范围
    if(StartPageOfPacket >  = RECEIVE_STOP_PAGE || StartPageOfPacket   < RECEIVE_START_PAGE)
    {
        StartPageOfPacket = curr;
        WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
        return NULL;
    }
    
    if(StartPageOfPacket == curr){
        //没数据接收
        WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
        return NULL;
    }
    
    //读取头4个字节
    address = ((WORD)StartPageOfPacket)  <  <8;
    RTLReadRam(address,4,Head);
    
    //判断是否是正确的包    
    if(Head[0] & RSR_RECEIVE_NO_ERROR)
    {
        //接收数据包的长度
        PacketSize = (((WORD)Head[3])  <  <8) + Head[2] - 4;    

        /* allocate buffer and read packet into buffer */
        flag=0;
        //判断长度是否溢出
        if(PacketSize  <MAX_PACKET_SIZE+1)  flag|=0x01;
        //判断下一个包页地址是否正确
        if((Head[1]  <RECEIVE_STOP_PAGE)&&(Head[1]>  RECEIVE_START_PAGE-1))
            flag|=0x10;
        if(flag==0x11){
            //都正确
            address += 4;
            //接收以太网报文头
            RTLReadRam(address, sizeof(struct SEtherHead), (uchar *)&EtherHead);
            //只接收IP和ARP协议的报文
            if((EtherHead.type==0x0800)||(EtherHead.type==0x0806)){
                address+=sizeof(struct SEtherHead);
                if((MemHead = MemAllocate(PacketSize)) != NULL)
                {
                    RTLReadRam(address,PacketSize,MemHead->  pStart);    /* read from rtl */
                }
            }    
        }else{
            if(!flag){
                Head[1]=curr;
            }else{
                if(flag==0x01){
                    //根据包长度计算下一个包所在的页
                    Head[1]=StartPageOfPacket+Head[3];
                    if(Head[2]) Head[1]++;
                }    
            }    
        }        
    }
    else{
        Head[1]=curr;
    }    
    
    //得到下一个包的页地址
    StartPageOfPacket = Head[1];

    //写入BNRY寄存器
    bnry = StartPageOfPacket - 1;
    if(bnry   < RECEIVE_START_PAGE)
        bnry = RECEIVE_STOP_PAGE - 1;
    //关闭DMA状态    
    WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
    WriteReg(BNRY_WPAGE0,bnry);    
    return MemHead;
}


>>>>>>对该主题发表你的看法

本主题贴数1,分页: [第1页]


[上一篇主题]:想入门,请教学习板的问题

[下一篇主题]:单片机学习资料下载