搜索
bottom↓
回复: 34

一个简洁,高效的 RTL8019AS 驱动代码。

[复制链接]

出0入0汤圆

发表于 2006-9-25 11:28:52 | 显示全部楼层 |阅读模式
*******************************************************************************

*  Copyright (C) 2005 Ben Ning

*  rtl8019.c: Send & Receive Implementation for RTL8019AS

*

*******************************************************************************/

#pragma LARGE ORDER NOPRINT OPTIMIZE(2)



#include <stdlib.h>

#include <stdio.h>



#include <absacc.h>

#include <string.h>



#include "NetAPI.h"

#include "NET.H"

//#include "SERIAL.H"

#include "w78e58.h"

#include "rtl8019.h"



//-----------------------------------------------------------------------------

// select RTL8019AS register page

//-----------------------------------------------------------------------------

void rtl8019_page(UCHAR page_num)

{

        UCHAR data temp;



        temp = CR; //command register

        temp=temp&0x3B ; // 0011 1011 bit2 = 0 for to disabel TXP

        page_num = page_num << 6;

        temp=temp | page_num;

        CR = temp;

}





//-----------------------------------------------------------------------------

// reset RTL8019AS chip

//-----------------------------------------------------------------------------



void rtl8019_reset()

{

        UCHAR i, j, temp;

       

        // hardware reset

        RTL8019_RESET = 1;

        for (i=0; i<100; i++) for (j=0; j<255; j++);

        RTL8019_RESET = 0;

        for (i=0; i<100; i++) for (j=0; j<255; j++);

       

        // software reset

        temp = REST_PORT;

        for (i=0; i<100; i++) for (j=0; j<255; j++);

        REST_PORT = temp;

        for (i=0; i<100; i++) for (j=0; j<255; j++);

}



//-----------------------------------------------------------------------------

// Initialize the RTL8019AS chip

//-----------------------------------------------------------------------------

extern UCHAR xdata my_hwaddr[6];



void rtl8019_init(void)

{

        UCHAR i, j;



//        for (i=0; i<255; i++);

        rtl8019_reset();



        CR = 0x21; // stop mode for setting registers and select page 0



        for (i=0; i<10; i++)

                for (j=0; j<255; j++);        // delay about 10ms

               

        DCR = 0xc8; // byte dma 8 bit dma mode



        RBCR0 = 0x00;

        RBCR1 = 0x00;

        TCR = 0x02;



//        RCR = 0xcc; //monitor mode (no packet receive)

        RCR = 0xe0; //monitor mode (no packet receive)



        PSTART        = RXSTART_INIT;

//        PSTOP        = 0x80; // for 16 bit mode

        PSTOP        = RXSTOP_INIT; // for 8 bit mode

        BNRY        = RXSTART_INIT;



        TPSR = TXSTART_INIT;

        ISR = 0xff; // clear all interrupt flags

        IMR        = 0x00; // disable all interrupt





        CR = 0x61;                // select page 1

        CURR = RXSTART_INIT;



//        CR = 0x22; // Let chip to work

//        TCR = 0xe0;

//        CR = 0x62;



        // set Mac address

        PAR0 = my_hwaddr[0];

        PAR1 = my_hwaddr[1];

        PAR2 = my_hwaddr[2];

        PAR3 = my_hwaddr[3];

        PAR4 = my_hwaddr[4];

        PAR5 = my_hwaddr[5];



        // set muticast address

        MAR0 = 0xFF;

        MAR1 = 0xFF;

        MAR2 = 0xFF;

        MAR3 = 0xFF;

        MAR4 = 0xFF;

        MAR5 = 0xFF;

        MAR6 = 0xFF;

        MAR7 = 0xFF;

       

        CR = 0x21; // select page 0



        RCR = 0xcc; // normal mode

        TCR = 0xe0;

        CR = 0x22;  // Normal work

        ISR = 0xff; // clear all interrupt flags



}



//-----------------------------------------------------------------------------

// This functions checks RTL8019AS status then sends an ethernet frame to it.

//-----------------------------------------------------------------------------

void rtl8019_send_frame(UCHAR xdata * outbuf, UINT len)

{

        UINT data i, j, n;



        rtl8019_page(0);



        if (len<60)        n = 60; else n = len;



        // set start address for sending

        RSAR1 = TXSTART_INIT; //  write dma address        -- high byte

        RSAR0 = 0x00; //  write dma address -- low byte

       

        //        set the count of bytes that will be send out

        RBCR1 = n >> 8;

        RBCR0 = n & 0xff;



        CR = 0x12; //write dma, page0

       

        // Write data to dma

        for (i=0; i<len; i++) DMA_PORT = *(outbuf+i);       



        // If necessary, to file some PAD bytes with 0x00

        for (i=len; i<n; i++) DMA_PORT = 0x00;       

       

        // Disable DMA OP

        RBCR1 = 0x00; // write count high

        RBCR0 = 0x00; // write count low;

        CR = 0x22;          //complete dma page 0

       

        for(i=0;i<16;i++)        // Try to resend 16 times

        {

                for (j=0; j<1000; j++) {

                        if (!(CR & TXP)) break; // If has transmited, break.

                }



                if (TSR & PTX) break; // If sending has completed



                CR = 0x3e;

        }       



        ISR = 0xff;



        TPSR = TXSTART_INIT;        //txd packet start;

               

        TBCR1 = n >> 8;        //high byte counter

        TBCR0 = n & 0xff;        //low byte counter



        ISR = 0xff;

        CR = 0x3e; //to sendpacket;



        // Release memory for re-use

//        free(outbuf);

                 

}



//------------------------------------------------------------------------

// This function gets an incoming Ethernet frame from the RTL8019AS.

// There may be more than 1 waiting but just allocate memory for

// one and read one in.  Use the RTL8019AS to queue incoming packets.

//------------------------------------------------------------------------

//extern UCHAR idata rcve_buf_allocated;



UCHAR xdata * rtl8019_rcve_frame(void)

{

        UINT data len, i;

        UCHAR xdata * data buf;

        UCHAR xdata * data p;

        UCHAR data curr, bnry;

        UCHAR data status, next_page, len_l, len_h;

       

        rtl8019_page(0);



        status = ISR;

         // Check if buffer overflow

        if (status & 0x90)

                rtl8019_OverflowRecover();



        status = RSR;

        if (!(status & 0x01)) // no data received

                return NULL;



        bnry = BNRY; //bnry page have read

        rtl8019_page(1);

        curr = CURR; //curr write page



        rtl8019_page(0);



        if (bnry==curr) return NULL; // no arrived package

       

        CRDA1 = bnry;        // current read dma address high

        CRDA0 = 0x00;        // current read dma address low



        RBCR1 = 0x00;        // count high

        RBCR0 = 0x04;        // count low



        CR = 0x0a; // begin to read dma



        // read 8019 header

        status = DMA_PORT;

        next_page = DMA_PORT;

        len_l = DMA_PORT;

        len_h = DMA_PORT;



        RBCR1 = 0x00;        // to read a page (256 bytes)

        RBCR0 = 0x00;

        CR = 0x22; // DMA completed page0

       

        // if boundary pointer is invalid

//        if (!(status & 0x01) || (next_page>0x7f) || (next_page<0x4c) || (len_h>0x06) )

        if (!(status & 0x01) || (next_page>=RXSTOP_INIT) || (next_page<RXSTART_INIT) || (len_h>0x06) )

        {

                rtl8019_page(1);

                curr = CURR;

                rtl8019_page(0);

                bnry = curr;

                BNRY = bnry;

                ISR = 0xff;



                return NULL;

        }

       

        len = ((UINT) len_h << 8) | (UINT) len_l;

        len = len - 4; // subract 4 bytes for eth CRC



        // Allocate enough memory to hold the incoming frame

        buf = (UCHAR xdata *) malloc(len);





        if (buf == NULL) {

                 return NULL;

        }



        p = buf;



        CRDA1 = bnry;        // read DMA address high

        CRDA0 = 0x04;        // read DMA address low, skip 4 byte that is 8019 header



        RBCR1 = len >> 8;                // count high

        RBCR0 = len & 0x00ff;        // count low



        CR = 0x0a; // begin to read DMA



        for (i=0; i<len; i++) {

                *p++ = DMA_PORT;

        }



        RBCR1 = 0x00;        // to read a page (256 bytes)

        RBCR0 = 0x00;

        CR = 0x22; // DMA completed page0

        ISR = 0xff;



        BNRY = next_page; //bnry; // Update BNRY

               

        return (buf);

}



void rtl8019_OverflowRecover(void)

{

        UCHAR data data_L, resend;

        UCHAR idata i, j;



        data_L = CR;



        CR = 0x21; // stop mode for setting registers and select page 0



        for (i=0; i<10; i++) for (j=0; j<255; j++);        // delay about 10ms



        RBCR0 = 0x00;

        RBCR1 = 0x00;

               

        if (data_L & TXP) {

         data_L = ISR;

         if((data_L & 0x02) || (data_L & 0x08))

             resend = 0;

         else

             resend = 1;

        }

        else

                resend = 0;



        TCR = 0x02;



        CR = 0x22;

        BNRY = RXSTART_INIT;



    CR = 0x62;

    CURR = RXSTART_INIT;



    CR = 0x22;

    ISR = 0x10;

    TCR = TCR_INIT;

     

     if(resend)

         CR = 0x26;



     ISR = 0xFF;



}



/-------------------------------------------------------------

http://shallop.vicp.net

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2006-9-25 11:31:02 | 显示全部楼层
希望这个代码能对同行有点帮助。

出0入0汤圆

发表于 2006-9-25 12:06:11 | 显示全部楼层
不错!!!

出0入0汤圆

发表于 2008-5-24 19:10:20 | 显示全部楼层
不错,谢谢!

出0入0汤圆

发表于 2008-5-25 10:56:31 | 显示全部楼层
谢谢,不懂网络,学学。

出0入0汤圆

发表于 2008-5-25 16:56:51 | 显示全部楼层
好像不错,顶一下

出0入0汤圆

发表于 2008-5-25 18:59:43 | 显示全部楼层
记号..还没用得上.

出0入0汤圆

发表于 2008-5-26 08:09:14 | 显示全部楼层
谢谢,记号了.

出0入0汤圆

发表于 2008-5-26 08:20:57 | 显示全部楼层
收下!

出0入0汤圆

发表于 2008-6-3 15:30:01 | 显示全部楼层
我现在正在用RTL8019,pingrtl8019没ping通,不知道是不是要驱动程序?

出0入0汤圆

发表于 2008-6-3 15:41:17 | 显示全部楼层
以后打算用,先MARK

出0入0汤圆

发表于 2008-6-3 17:05:43 | 显示全部楼层
MARK

出0入0汤圆

发表于 2008-6-3 17:10:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-19 00:08:52 | 显示全部楼层
ok

出0入0汤圆

发表于 2008-11-19 00:32:39 | 显示全部楼层
不知这芯片还有卖嘛?

出0入0汤圆

发表于 2008-11-19 01:12:00 | 显示全部楼层
这是个裸包收发代码
头像被屏蔽

出0入0汤圆

发表于 2008-11-19 07:30:30 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2008-11-19 12:30:47 | 显示全部楼层
做个记号。。。

出0入0汤圆

发表于 2008-11-19 14:05:36 | 显示全部楼层
好的,不错啊

出0入0汤圆

发表于 2008-11-19 15:13:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-19 17:23:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-20 09:18:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-23 13:17:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-23 13:23:04 | 显示全部楼层
收下!谢谢

出0入0汤圆

发表于 2009-6-5 20:32:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-13 08:35:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-10 11:49:09 | 显示全部楼层
可以参考一下,谢谢

出0入0汤圆

发表于 2010-6-2 21:45:19 | 显示全部楼层
请求下:
for(i=0;i<16;i++) // Try to resend 16 times
{  
  for (j=0; j<1000; j++)
  {
   if (!(CR & TXP)) break; // If has transmited, break.
  }

  if (TSR & PTX) break; // If sending has completed

  CR = 0x3e;
}
这段的目的是检测是否发送完并且没错误,如果还没发送完,就再启动发送,这样发送16次?
接下来的

ISR = 0xff;

TPSR = TXSTART_INIT; //txd packet start;

TBCR1 = n >> 8; //high byte counter
TBCR0 = n & 0xff; //low byte counter

ISR = 0xff;
CR = 0x3e; //to sendpacket;

这个目的又是什么?越看越糊涂了

出0入0汤圆

发表于 2010-7-16 12:57:03 | 显示全部楼层
检查上一次的发送是否完成,如果发送失败了就再发送,等上次的数据发送完了,就启动本次的发送
按我理解应该是这样子的

出0入0汤圆

发表于 2010-7-16 13:03:17 | 显示全部楼层
问一下,谁有这源程序的各个寄存器的定义和电路图,有的话传个上来
谢谢

出0入0汤圆

发表于 2011-6-2 14:27:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-2 14:46:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-6 11:00:30 | 显示全部楼层
标记下。

出0入0汤圆

发表于 2013-7-26 15:46:32 | 显示全部楼层
标记RTL8091
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 01:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表