📄 ne2000.c
字号:
#include "necfg.h"
#include "ne2000.h"
#include "..\inc\44blib.h"
#include "..\inc\44b.h"
#include <string.h>
unsigned char mymac[MACLEN];
NICHDR nichdr;
void Reset_NIC(void)
{
unsigned char temp;
EN_CR = ENCR_PAGE0 + ENCR_NODMA + ENCR_START;
Delay(100);
rPCONC |= 0x10000000;
#if NE_WORDMODE
rPDATC |= 0x4000;
#else
rPDATC &= 0xbfff;
#endif
Delay(500);
temp = EN_RESET;
EN_RESET = temp;
Delay(500);
rPDATC &= 0xbfff;
rPCONC &= 0xcfffffff;
EN_CR = ENCR_PAGE0 + ENCR_NODMA + ENCR_STOP;
Delay(100);
if(EN_ISR & ENISR_RESET)
{
Uart_Printf("\nNIC Reset OK!\n");
}
else
{
Uart_Printf("\nNIC Reset Failed!\n");
return;
}
EN_DCR = NE_DCRVAL;
EN_RBCR0 = 0x00; /* MSB remote byte count reg */
EN_RBCR1 = 0x00; /* LSB remote byte count reg */
EN_RCR = ENRCR_RXOFF; /* RX configuration reg Monitor mode (no packet receive) */
EN_TCR = ENTCR_TXOFF; /* TX configuration reg set internal loopback mode */
EN_TPSR = TX_START_PG;
EN_PSTART = RX_START_PG ; /* DMA START PAGE 46h */
EN_PSTOP = RX_STOP_PG; /* Ending page +1 of ring buffer */
EN_BNRY = RX_START_PG; /* Boundary page of ring buffer */
EN_ISR = 0xff; /* INTerrupt stauts reg */
EN_IMR = ENIMR_RX | ENIMR_RX_ERR | ENIMR_TX | ENIMR_TX_ERR;
EN_CR = ENCR_PAGE1 + ENCR_NODMA + ENCR_STOP;
Delay(100);
EN_PAR0 = mymac[0];
EN_PAR1 = mymac[1];
EN_PAR2 = mymac[2];
EN_PAR3 = mymac[3];
EN_PAR4 = mymac[4];
EN_PAR5 = mymac[5];
EN_MAR0 = 0xff;
EN_MAR1 = 0xff;
EN_MAR2 = 0xff;
EN_MAR3 = 0xff;
EN_MAR4 = 0xff;
EN_MAR5 = 0xff;
EN_MAR6 = 0xff;
EN_MAR7 = 0xff;
EN_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */
EN_CR = ENCR_PAGE0 + ENCR_NODMA ; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
Delay(100);
EN_RCR = ENRCR_RXCONFIG; /* rx on(broadcasts, no multicast,errors 04*/
EN_TCR = ENTCR_TXCONFIG; /* xmit on. */
EN_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */
EN_IMR = ENISR_ALL; /* INTerrupt mask reg */
EN_CR = ENCR_PAGE0 + ENCR_NODMA + ENCR_START;
}
void getnic(unsigned short addr, unsigned char data[],unsigned short len)
{
unsigned short count;
unsigned short * dataw;
count = NE_WORDMODE ? len >> 1 : len;
EN_ISR = ENISR_RDC; // clear remote dma interrupt flag
EN_RBCR0 = (unsigned char)(len & 0xff); // read length low
EN_RBCR1 = (unsigned char)(len >> 8); // read length high
EN_RSAR0 = (unsigned char)(addr & 0xff); // read address low
EN_RSAR1 = (unsigned char)(addr >> 8); // read address high
EN_CR = ENCR_RREAD + ENCR_START + ENCR_PAGE0;// do dma read
#if NE_WORDMODE
dataw = (unsigned short *)data; // Use pointer for speed
while(count--) // Get words
*dataw++ = EN_DATAW;
if (len & 0x01) // If odd length, do last byte
*(unsigned char *)dataw = EN_DATAB;
#else
while(count--) // Get bytes
*data++ = EN_DATAB;
#endif
}
void putnic(unsigned short addr, unsigned char data[],unsigned short len)
{
unsigned short count;
unsigned short * dataw;
len += len & 0x01;
count = NE_WORDMODE ? len >> 1 : len;
EN_ISR = ENISR_RDC; //clear remote dma interrupt flag
EN_RBCR0 = (unsigned char)(len & 0xff);
EN_RBCR1 = (unsigned char)(len >> 8);
EN_RSAR0 = (unsigned char)(addr & 0xff);
EN_RSAR1 = (unsigned char)(addr >> 8);
EN_CR = ENCR_RWRITE + ENCR_START + ENCR_PAGE0;
#if NE_WORDMODE /* Word transfer? */
dataw = (unsigned short *)data;
while(count--)
EN_DATAW = *dataw++;
#else
while(count--) /* O/P bytes */
EN_DATAB = *data++;
#endif
count = 10000; /* Done: must ensure DMA complete */
while(count && (EN_ISR & ENISR_RDC) == 0)
count--;
}
unsigned char nicwrap(unsigned char page)
{
if (page >= RX_STOP_PG)
page += RX_START_PG - RX_STOP_PG;
else if(page < RX_START_PG)
page += RX_STOP_PG - RX_START_PG;
return (page);
}
unsigned short Get_Ethernet(ETHERFRAME *efp)
{
unsigned short current_offset;
unsigned char curr_page;
unsigned char bnry;
if (EN_ISR & 0x10) Reset_NIC();
EN_CR = ENCR_NODMA + ENCR_PAGE1 + ENCR_START;
curr_page = EN_CURR;
EN_CR = ENCR_NODMA + ENCR_PAGE0 + ENCR_START;
bnry = EN_BNRY + 1;
if (bnry > RX_STOP_PG) bnry = RX_START_PG;
if (bnry != curr_page)
{
current_offset = (unsigned short)(bnry << 8);
memset((unsigned char *)&nichdr, 0xee, sizeof(nichdr));
getnic(current_offset, (unsigned char *)&nichdr, sizeof(nichdr));
if ((nichdr.stat & 0x01) && nichdr.len >= MINFRAMEC && nichdr.len<=MAXFRAMEC)
if(efp)
getnic(current_offset + sizeof(nichdr), (unsigned char *)efp, nichdr.len - sizeof(nichdr));
if (nichdr.next >= RX_START_PG && nichdr.next < RX_STOP_PG)
bnry = nichdr.next;
else
bnry = nicwrap(bnry + 1);
bnry = nicwrap(bnry - 1);
EN_BNRY = bnry;
return (nichdr.len - sizeof(nichdr));// - sizeof(ETHERHDR));
}
return (0);
}
unsigned short Put_Ethernet(ETHERFRAME *efp, unsigned short len)
{
if (EN_CR & ENCR_TRANS)
len=0;
else
{
len = min(MAXFRAME,max(len,MINFRAME));
EN_CR = ENCR_PAGE0 + ENCR_NODMA;
EN_ISR = ENISR_TX + ENISR_TX_ERR;
EN_TBCR0=(unsigned char)(len & 0xff);
EN_TBCR1=(unsigned char)(len >> 8);
putnic(TX_START_PG << 8, (unsigned char *)efp, len);
EN_CR = ENCR_NODMA + ENCR_PAGE0 + ENCR_TRANS;
}
return(len);
}
unsigned short Make_Frame(ETHERFRAME *efp, unsigned char srce[], unsigned char dest[], unsigned short pcol, unsigned short dlen)
{
unsigned char i;
efp->e.ptype = pcol;
for(i=0;i<MACLEN;i++)
{
efp->e.dest[i] = dest[i];
efp->e.srce[i] = srce[i];
}
Swap_Ether(efp);
dlen += sizeof(ETHERHDR);
return(dlen);
}
void Swap_Ether(ETHERFRAME *efp)
{
efp->e.ptype = swapw(efp->e.ptype);
}
unsigned short csum(void *dp, unsigned short count)
{
unsigned int total=0L;
unsigned short n, *p, carries;
n = count / 2;
p = (unsigned short *)dp;
while (n--)
total += *p++;
if (count & 1)
total += (*(unsigned char *)p);
while ((carries = (unsigned short)(total >> 16)) != 0)
total = (total & 0xffffL) + carries;
return((unsigned short)total);
}
unsigned short swapw(unsigned short w)
{
unsigned short s_w;
s_w = ((w<<8)&0xff00) | ((w>>8)&0x00ff);
return s_w;
}
unsigned int swapl(unsigned int lw)
{
unsigned int s_lw;
s_lw = ((lw<<24)&0xff000000) | ((lw<<8 )&0x00ff0000) | ((lw>>8 )&0x0000ff00) | ((lw>>24)&0x000000ff);
return s_lw;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -