📄 p16_eth.c
字号:
/* 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 + -