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

📄 p16_eth.c

📁 一个由PIC单片机组成的Web服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* RTL8019AS network driver for ChipWeb - Copyright (c) Iosoft Ltd 2001
**
** This source code is only licensed for distribution in the Iosoft ChipWeb
** package, and the purchaser of that package is granted the non-exclusive
** right to use the software for personal experimentation only, provided
** that this copyright notice is retained. All other rights are retained by
** Iosoft Ltd.
**
** Redistribution of this source code is not permitted. Binary images derived
** from the source code may only be redistributed if a commercial license is
** obtained; see www.iosoft.co.uk or email license@iosoft.co.uk
**
** The software is supplied 'as-is' for development purposes, without warranty
** of any kind, either expressed or implied, including, but not limited to,
** the implied warranties of merchantability and fitness for purpose.
** In no event will Iosoft Ltd. be liable for damages, including any general,
** special, incidental or consequential damages arising out of the use or
** inability to use the software, including, but not limited to, loss or
** corruption of data, or losses sustained by the developer or third parties,
** or failure of the software to operate with any other software or systems.
** This license shall be governed by the laws of England. */

#define DROP_TX 0       /* If non-zero, drop 1 in n Tx packets for debug */

#ifndef NET_TXBUFFERS
#define NET_TXBUFFERS 1         // Number of network transmit buffers
#endif

/* First 3 bytes of MAC address are assigned by the IEEE to a specific
** organisation, last 3 bytes will contain the board serial number */
#define MACBASE_ADDR {0x00, 0x04, 0xa3, 0, 0, 0}

DEFBIT_2(PORTE, NIC_RESET)      /* I/O Definitions */
DEFBIT_1(PORTE, NIC_IOW_)
DEFBIT_0(PORTE, NIC_IOR_)
#define NIC_ADDR PORTB
#define NIC_DATA PORTD
#define DATA_TO_NIC   set_tris_d(ALL_OUT)
#define DATA_FROM_NIC set_tris_d(ALL_IN)
#define TRISB_VAL   0x20        /* Port B, bit 5 pushbutton I/P */

#define PROMISC  0              /* Set non-zero to accept all packets */

/* Ethernet definitions.. */
#define CRCLEN    4             /* Length of Ethernet CRC */
#define MINFRAME  60            /* Min frame size without CRC */
#define MAXFRAME  1514          /* Max frame size without CRC */
#define MINFRAMEC (MINFRAME+CRCLEN) /* Ditto including CRC */
#define MAXFRAMEC (MAXFRAME+CRCLEN)

/* NE2000 definitions */
#define DATAPORT 0x10
#define NE_RESET 0x1f

/* 8390 Network Interface Controller (NIC) page0 register offsets */
#define CMDR    0x00            /* command register for read & write */
#define PSTART  0x01            /* page start register for write */
#define PSTOP   0x02            /* page stop register for write */
#define BNRY    0x03            /* boundary reg for rd and wr */
#define TPSR    0x04            /* tx start page start reg for wr */
#define TBCR0   0x05            /* tx byte count 0 reg for wr */
#define TBCR1   0x06            /* tx byte count 1 reg for wr */
#define ISR     0x07            /* interrupt status reg for rd and wr */
#define RSAR0   0x08            /* low byte of remote start addr */
#define RSAR1   0x09            /* hi byte of remote start addr */
#define RBCR0   0x0A            /* remote byte count reg 0 for wr */
#define RBCR1   0x0B            /* remote byte count reg 1 for wr */
#define RCR     0x0C            /* rx configuration reg for wr */
#define TCR     0x0D            /* tx configuration reg for wr */
#define DCR     0x0E            /* data configuration reg for wr */
#define IMR     0x0F            /* interrupt mask reg for wr */

/* NIC page 1 register offsets */
#define PAR0    0x01            /* physical addr reg 0 for rd and wr */
#define CURRP   0x07            /* current page reg for rd and wr */
#define MAR0    0x08            /* multicast addr reg 0 for rd and WR */

/* NIC page 3 register offsets */
#define RTL9346CR 0x01          /* RTL 9346 command reg */
#define RTL3    0x06            /* RTL config reg 3 */

/* NIC RAM definitions */
#define RAMPAGES 0x20           /* Total number of 256-byte RAM pages */
#define TXSTART  0x40           /* Tx buffer start page */
#define TXPAGES  6              /* Pages for one Tx buffer */
#define RXSTART  (TXSTART+(TXPAGES*NET_TXBUFFERS))  /* Rx buffer start page */
#define RXSTOP   (TXSTART+RAMPAGES-1)               /* Rx buffer end page */
#define DCRVAL   0x48           /* Value for data config reg */

#define MACLEN   6              /* My MAC address */
BYTE myeth[MACLEN] = MACBASE_ADDR;

#define RXBUFFLEN 42            // Size of Rx buffer
#define RXMARGIN  10            // Minimum number of pushback bytes
BANK1 BYTE next_page, curr_rx_page;
BANK2 WORD curr_rx_addr;
BANK2 WORD net_rxin;            // Length of incoming packet in NIC
BANK2 BOOL rx_checkoff;         // Flag to disable Rx checksumming
BANK2 WORD rxout;               // Length of packet processed so far
BANK2 BYTE rxbuffin, rxbuffout; // I/O pointers for Rx process buffer
BANK2 BYTE rxbuff[RXBUFFLEN];   // Rx buffer
LOCATE(rxbuff, 0x110)

BANK3 BYTE nic_tx_transfer;     // Flag set if Tx data is being sent to NIC

#define TXBUFFLEN 42            // Size of Tx buffer
#define TXMARGIN  10            // Buffer to be emptied when this space remains
BANK3 WORD net_txlen;           // Max length of Tx data sent to NIC
BANK3 WORD txin;                // Current I/P pointer for Tx data
BANK3 BYTE txbuffin;            // I/P pointer for Tx process buffer
BANK3 BYTE txbuff[TXBUFFLEN];   // Tx buffer
LOCATE(txbuff, 0x190)
#if NET_TXBUFFERS > 1
BANK3 BYTE txbuffnum;           // Number of Tx buffer, if using more than 1
BANK3 WORD txbuff_lens[NET_TXBUFFERS];  // Length of last buffer transmission
#endif

typedef struct {                // NIC hardware packet header
    BYTE stat;                  //     Error status
    BYTE next;                  //     Pointer to next block
    WORD len;                   //     Length of this frame incl. CRC
} NICHEADER;

typedef struct {                // Ethernet frame header
    BYTE dest[MACLEN];          //     Dest & srce MAC addresses
    BYTE srce[MACLEN];
    WORD pcol;                  //     Protocol
} ETHERHEADER;

#define ETHERHDR_LEN (sizeof(ETHERHEADER))
#define MAXNET_DLEN (MAXFRAME-ETHERHDR_LEN)

typedef struct {                // NIC and Ethernet headers combined
    NICHEADER nic;
    ETHERHEADER eth;
} NICETHERHEADER;

BANK1 NICETHERHEADER host;      // Buffer for incoming NIC & Ether hdrs

/* Prototypes for this file */
void init_rxbuff(void);
void init_txbuff(BYTE buffnum);
BOOL setpos_rxout(WORD newpos);
BOOL setpos_txin(WORD newpos);
BYTE load_rxbuff(BYTE margin, BYTE count);
void save_txbuff(void);
BOOL init_net(void);
void reset_ether(void);
BOOL get_net(void);
void transmit(void);
void setnic_addr(WORD addr);
void setnic_tx(WORD addr);
void setnic_rx(WORD addr);
void getnic_rxbuff(BYTE len);
void putnic_txbuff(void);
BYTE nicwrap(BYTE page);
BYTE innic(BYTE reg);
void outnic(BYTE reg, BYTE b);

/* Prototypes for other files */
WORD get_data(BYTE *ptr, WORD maxlen);
BOOL put_byte(BYTE b);
void put_data(BYTE *data, WORD len);
WORD swapw(WORD val);
void check_byte(BYTE b);

/* Initialise the receive buffer */
void init_rxbuff(void)
{
    rxout = rxbuffin = rxbuffout = 0;
    rx_checkoff = arp_resp = 0;
    setnic_rx(0);
}

/* Initialise the transmit buffer
** If more than one Tx frame, select which */
void init_txbuff(BYTE buffnum)
{
#if NET_TXBUFFERS > 1
    txbuffnum = buffnum;
#endif
    txin = net_txlen = txbuffin = 0;
    checkflag = checkhi = checklo = 0;
    setnic_tx(0);
}

/* Move the Rx O/P pointer to the given location, return 0 if beyond data */
BOOL setpos_rxout(WORD newpos)
{
    if (newpos > net_rxin)
        return(0);
    setnic_rx(newpos);
    rxout = newpos;
    rxbuffin = rxbuffout = 0;
    return(1);
}

/* Truncate the remaining Rx data to the given length */
void truncate_rxout(WORD len)
{
    WORD end;

    if ((end = rxout+len) < net_rxin)
        net_rxin = end;
    if ((end = rxbuffout+len) < rxbuffin)
        rxbuffin = end;
}

/* Return the number of Rx data bytes left in buffer */
WORD rxleft(void)
{
    return(net_rxin - rxout);
}

/* Move the Rx O/P pointer to the given location, return 0 if beyond data */
BOOL setpos_txin(WORD newpos)
{
    if (newpos > MAXFRAME-ETHERHDR_LEN)
        return(0);
    save_txbuff();
    setnic_tx(txin = newpos);
    return(1);
}

/* Return amount the free space left in Tx buffer */
WORD txleft(void)
{
    return(MAXFRAME-ETHERHDR_LEN - txin);
}

/* Load a given number of bytes from the NIC into the Rx buffer
** Remove any processed data from the buffer, but allow a margin
** of data to be retained. Return the actual number of bytes loaded */
BYTE load_rxbuff(BYTE margin, BYTE count)
{
    BYTE in, n;
    WORD rxleft;

    if (rxbuffout > margin)
    {
        in = margin;
        while (rxbuffout<rxbuffin)
            rxbuff[in++] = rxbuff[rxbuffout++];
        rxbuffin = in;
        rxbuffout = margin;
    }
    rxleft = net_rxin - rxout;
    count = (BYTE)MIN(count, rxleft);
    n = count = (BYTE)MIN(count, RXBUFFLEN-rxbuffin);
    if (n)
    {
        if (nic_tx_transfer)
            setnic_rx(rxout);
        getnic_rxbuff(count);
    }
    return(count);
}

/* Save the contents of the Tx buffer into the NIC */
void save_txbuff(void)
{
    if (txbuffin)
    {
        if (!nic_tx_transfer)
            setnic_tx(txin - txbuffin);
        putnic_txbuff();
        txbuffin = 0;
    }
    if (txin > net_txlen)
        net_txlen = txin;
}

/* Get an incoming byte value, return 0 if end of message */
BOOL get_byte(BYTE *bp)
{
    BYTE b;

    if (rxbuffout >= rxbuffin)
        load_rxbuff(RXMARGIN, RXBUFFLEN);
    if (rxbuffout >= rxbuffin)
        return(0);
    b = rxbuff[rxbuffout++];
    rxout++;
    if (!rx_checkoff)
        check_byte(b);
    *bp = b;
#if DEBUG
    disp_hexbyte(b);
#endif
    return(1);
}

/* Push back a byte value, return 0 if no room */
BOOL unget_byte(BYTE b)
{
    if (rxbuffout && rxout)
    {
        rxbuff[--rxbuffout] = b;
        rxout--;
        return(1);
    }
    return(0);
}

/* Send a byte to the network buffer, then add to checksum
** Return 0 if no more data can be accepted */
BOOL put_byte(BYTE b)
{
    if (txin >= MAXFRAME)
        return(0);
    if (txbuffin >= TXBUFFLEN-TXMARGIN)
        save_txbuff();
    txbuff[txbuffin++] = b;
    txin++;
    check_byte(b);
    return(1);

⌨️ 快捷键说明

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