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

📄 rtl8019a(c).txt

📁 一个简洁
💻 TXT
字号:
******************************************************************************* 
 *  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; 

} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -