📄 ethmod.c
字号:
printf("\r\n");
data_L = 0x00;
for(i=0;i<80;++i)
{
bin2hex(aux_data[i]);
printf(" %c%c",high_char,low_char);
if(++data_L == 0x10)
{
data_L = 0x00;
printf("\r\n");
}
}
}
/******************************************************************
//* Write to NIC Control Register
//******************************************************************/
void write_creg(int regaddr, int regdata)
{
cregaddr = regaddr;
cregdata = regdata;
tocreg;
iow_pin=0;/*bit_clear(iow_pin);*/
delay_cycles(1);
iow_pin=1;/*bit_set(iow_pin);*/
fromcreg;
}
/******************************************************************
//* Read From NIC Control Register
//******************************************************************/
char read_creg(int regaddr)
{
fromcreg;
cregaddr = regaddr;
ior_pin=0;/*bit_clear(ior_pin);*/
byte_read = input_d();
ior_pin=1;/*bit_set(ior_pin);*/
return(byte_read);
}
/******************************************************************
//* Detect EEPROM Clock from RTL8019AS
//******************************************************************/
void clock_9346()
{
#asm
chk_is_lo:
btfss EESK
goto chk_is_lo
chk_is_hi:
btfsc EESK
goto chk_is_hi
#endasm
}
/******************************************************************
//* Emulate the presence of a 9346 EEPROM
//******************************************************************/
void fakeout_9346()
{
char reps,clocks,datum;
#asm
movlw 0x02
movwf reps
reload:
bcf EEDO
movlw 0x03 /*0x03=half duplex 0x07=full duplex*/
movwf datum
#endasm
start_bit:
clock_9346();
#asm
btfss EEDI
goto start_bit
#endasm
clock_9346();
#asm
btfss EEDI
goto start_bit
#endasm
clock_9346();
#asm
btfsc EEDI
goto start_bit
movlw 0x06
movwf clocks
#endasm
addr:
clock_9346();
#asm
decfsz clocks,1
goto addr
movlw 0x10
movwf clocks
bcf C
#endasm
send:
clock_9346();
#asm
movf datum,0
movwf PORTA
rrf datum,1
decfsz clocks,1
goto send
decfsz reps,1
goto reload
bcf EEDO
#endasm
}
/******************************************************************
//* Handle Receive Ring Buffer Overrun
//* No packets are recovered
//******************************************************************/
void overrun()
{
read_creg(CR);
data_L = byte_read;
write_creg(CR,0x21);
delay_ms(2);
write_creg(RBCR0,0x00);
write_creg(RBCR1,0x00);
if(!bit_test(data_L,2))
resend = 0;
else if(bit_test(data_L,2))
{
read_creg(ISR);
data_L = byte_read;
if(bit_test(data_L,1) || bit_test(data_L,3))
resend = 0;
else
resend = 1;
}
write_creg(TCR,0x02);
write_creg(CR,0x22);
write_creg(BNRY,rxstart);
write_creg(CR,0x62);
write_creg(CURR,rxstart);
write_creg(CR,0x22);
write_creg(ISR,0x10);
write_creg(TCR,tcrval);
}
/******************************************************************
//* Echo Packet Function
//* This routine does not modify the incoming packet size and
//* thus echoes the original packet structure.
//******************************************************************/
void echo_packet()
{
write_creg(CR,0x22);
write_creg(TPSR,txstart);
write_creg(RSAR0,0x00);
write_creg(RSAR1,0x40);
write_creg(ISR,0xFF);
write_creg(RBCR0,pageheader[enetpacketLenL] - 4 );
write_creg(RBCR1,pageheader[enetpacketLenH]);
write_creg(CR,0x12);
txlen = make16(pageheader[enetpacketLenH],pageheader[enetpacketLenL]) - 4;
for(i=0;i<txlen;++i)
write_creg(RDMAPORT,packet[enetpacketDest0+i]);
byte_read = 0;
while(!bit_test(byte_read,RDC))
read_creg(ISR);
write_creg(TBCR0,pageheader[enetpacketLenL] - 4);
write_creg(TBCR1,pageheader[enetpacketLenH]);
write_creg(CR,0x24);
}
/******************************************************************
//* Get A Packet From the Ring
//* This routine removes a data packet from the receive buffer
//* ring.
//******************************************************************/
void get_packet()
{
/*execute Send Packet command to retrieve the packet*/
write_creg(CR,0x1A);
for(i=0;i<4;++i)
{
read_creg(RDMAPORT);
pageheader[i] = byte_read;
}
rxlen = make16(pageheader[enetpacketLenH],pageheader[enetpacketLenL]);
for(i=0;i<rxlen;++i)
{
read_creg(RDMAPORT);
/*dump any bytes that will overrun the receive buffer*/
if(i < 96)
packet[i] = byte_read;
}
while(!bit_test(byte_read,RDC))
read_creg(ISR);
write_creg(ISR,0xFF);
/*process an ARP packet*/
if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x06)
{
if(packet[arp_hwtype+1] == 0x01 &&
packet[arp_prtype] == 0x08 && packet[arp_prtype+1] == 0x00 &&
packet[arp_hwlen] == 0x06 && packet[arp_prlen] == 0x04 &&
packet[arp_op+1] == 0x01 &&
MYIP[0] == packet[arp_tipaddr] &&
MYIP[1] == packet[arp_tipaddr+1] &&
MYIP[2] == packet[arp_tipaddr+2] &&
MYIP[3] == packet[arp_tipaddr+3] )
arp();
}
/*process an IP packet*/
else if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x00
&& packet[ip_destaddr] == MYIP[0]
&& packet[ip_destaddr+1] == MYIP[1]
&& packet[ip_destaddr+2] == MYIP[2]
&& packet[ip_destaddr+3] == MYIP[3])
{
if(packet[ip_proto] == PROT_ICMP)
icmp();
else if(packet[ip_proto] == PROT_UDP)
udp();
else if(packet[ip_proto] == PROT_TCP)
tcp();
}
}
/******************************************************************
//* SETIPADDRS
//* This function builds the IP header.
//******************************************************************/
void setipaddrs()
{
/*move IP source address to destination address*/
packet[ip_destaddr]=packet[ip_srcaddr];
packet[ip_destaddr+1]=packet[ip_srcaddr+1];
packet[ip_destaddr+2]=packet[ip_srcaddr+2];
packet[ip_destaddr+3]=packet[ip_srcaddr+3];
/*make ethernet module IP address source address*/
packet[ip_srcaddr]=MYIP[0];
packet[ip_srcaddr+1]=MYIP[1];
packet[ip_srcaddr+2]=MYIP[2];
packet[ip_srcaddr+3]=MYIP[3];
/*move hardware source address to destinatin address*/
packet[enetpacketDest0]=packet[enetpacketSrc0];
packet[enetpacketDest1]=packet[enetpacketSrc1];
packet[enetpacketDest2]=packet[enetpacketSrc2];
packet[enetpacketDest3]=packet[enetpacketSrc3];
packet[enetpacketDest4]=packet[enetpacketSrc4];
packet[enetpacketDest5]=packet[enetpacketSrc5];
/*make ethernet module mac address the source address*/
packet[enetpacketSrc0]=MYMAC[0];
packet[enetpacketSrc1]=MYMAC[1];
packet[enetpacketSrc2]=MYMAC[2];
packet[enetpacketSrc3]=MYMAC[3];
packet[enetpacketSrc4]=MYMAC[4];
packet[enetpacketSrc5]=MYMAC[5];
/*calculate the IP header checksum*/
packet[ip_hdr_cksum]=0x00;
packet[ip_hdr_cksum+1]=0x00;
hdr_chksum =0;
hdrlen = (packet[ip_vers_len] & 0x0F) * 4;
addr = &packet[ip_vers_len];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[ip_hdr_cksum] = make8(chksum16,1);
packet[ip_hdr_cksum+1] = make8(chksum16,0);
}
/******************************************************************
//* CHECKSUM CALCULATION ROUTINE
//******************************************************************/
void cksum()
{
while(hdrlen > 1)
{
data_H=*addr++;
data_L=*addr++;
chksum16=make16(data_H,data_L);
hdr_chksum = hdr_chksum + chksum16;
hdrlen -=2;
}
if(hdrlen > 0)
{
data_H=*addr;
data_L=0x00;
chksum16=make16(data_H,data_L);
hdr_chksum = hdr_chksum + chksum16;
}
}
/******************************************************************
//* Initialize the RTL8019AS
//******************************************************************/
void init_RTL8019AS()
{
ADCON1 = 0x06; /*00000110 all digital to start*/
ADCON0 = 0;
set_tris_C(0x85);
set_tris_A(0x00);
bit_clear(EEDO);
set_tris_B(0xE0); /* setup address lines*/
cregaddr = 0x00; /* clear address lines*/
fromcreg; /* address lines = input*/
set_tris_E(0x00); /* setup IOW, IOR, RESET*/
iow_pin=1;/*bit_set(iow_pin); disable IOW*/
ior_pin=1;/*bit_set(ior_pin); disable IOR*/
rst_pinb=1;/*it_set(rst_pin); put NIC in reset*/
delay_ms(2); /* delay at least 1.6ms*/
rst_pinb=0;/*bit_clear(rst_pin); /* disable reset line*/
read_creg(RSTPORT); /* read contents of reset port*/
write_creg(RSTPORT,byte_read); /* do soft reset*/
delay_ms(10); /* give it time*/
read_creg(ISR); /* check for good soft reset*/
if(!bit_test(byte_read,RST)){
while(1){
printf("INIT FAILED\n\r");
}
}
write_creg(CR,0x21); /*stop the NIC, abort DMA, page 0*/
delay_ms(2); /*make sure nothing is coming in or going out*/
write_creg(DCR,dcrval); /*0x58*/
write_creg(RBCR0,0x00); /*clear the DMA byte counters*/
write_creg(RBCR1,0x00);
write_creg(RCR,0x04); /*accept broadcast packets */
write_creg(TPSR,txstart); /*set transmit buffer start page */
write_creg(TCR,0x02);
write_creg(PSTART,rxstart);//set receive buffer start page*/
write_creg(BNRY,rxstart); /*initialize the boundary */
write_creg(PSTOP,rxstop); /*set receive buffer stop page */
write_creg(CR,0x61); /*stop NIC and change control register page */
delay_ms(2);
write_creg(CURR,rxstart); /*write NIC MAC (hardware) address */
for(i=0;i<6;++i)
write_creg(PAR0+i, MYMAC[i]);
write_creg(CR,0xC1); /*prepare to emulate 9346 EEPROM*/
write_creg(CR9346,0xC0);
write_creg(CR9346,0x40);
fakeout_9346(); /*emulate the 9348 */
delay_ms(10);
write_creg(CR,0x21); /*stop the NIC and go to home page */
write_creg(DCR,dcrval); /*set FIFO threshold, enable Send Packet Command, */
write_creg(CR,0x22); /*start NIC */
write_creg(ISR,0xFF); /*clear interrupts*/
write_creg(IMR,imrval); /*unmask interrupts */
write_creg(TCR,tcrval); /*normal operation and enable CRC */
}
/******************************************************************
//* MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN
//******************************************************************/
void main()
{
init_RTL8019AS();
synflag = 0;
finflag = 0;
/******************************************************************
//* Look for a packet in the receive buffer ring
//******************************************************************/
while(1)
{
/*start the NIC*/
write_creg(CR,0x22);
/*wait for a good packet*/
while(!bit_test(INT0));
/*read the interrupt status register*/
read_creg(ISR);
/*if the receive buffer has been overrun*/
if(bit_test(byte_read,OVW))
overrun();
/*if the receive buffer holds a good packet*/
if(bit_test(byte_read,PRX))
get_packet();
/*make sure the receive buffer ring is empty*/
/*if BNRY = CURR, the buffer is empty*/
read_creg(BNRY);
data_L = byte_read;
write_creg(CR,0x62);
read_creg(CURR);
data_H = byte_read;
write_creg(CR,0x22);
/*buffer is not empty.. get next packet*/
if(data_L != data_H)
get_packet();
/*reset the interrupt bits*/
write_creg(ISR,0xFF);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -