📄 ethernet_mini_driver.c
字号:
EDATA = 0x00;
i--;
};
i = 4;
while(i) //write destination IP address
{
EDATA = 0xFF;
i--;
};
tx_end += 20;
//END IP HEADER
//START UDP HEADER
EDATA = 0x00; //write UDP source port (68)
EDATA = 0x44;
EDATA = 0x00; //write UDP destination port (67)
EDATA = 0x43;
EDATA = 0x00; //write UDP length
EDATA = 0x00;
EDATA = 0x00; //write UDP checksum (no checksum)
EDATA = 0x00;
tx_end += 8;
//END UDP HEADER
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| op (1) | htype (1) | hlen (1) | hops (1) |
+---------------+---------------+---------------+---------------+
| xid (4) |
+-------------------------------+-------------------------------+
| secs (2) | flags (2) |
+-------------------------------+-------------------------------+
| ciaddr (4) |
+---------------------------------------------------------------+
| yiaddr (4) |
+---------------------------------------------------------------+
| siaddr (4) |
+---------------------------------------------------------------+
| giaddr (4) |
+---------------------------------------------------------------+
| |
| chaddr (16) |
| |
| |
+---------------------------------------------------------------+
| |
| sname (64) |
+---------------------------------------------------------------+
| |
| file (128) |
+---------------------------------------------------------------+
| |
| options (312) |
+---------------------------------------------------------------+
*/
//BEGIN DHCP MESSAGE
EDATA = BOOT_REQUEST; //write DHCP boot record type (request)
EDATA = HW_TYPE; //write DHCP hw address type (10Mb Ethernet)
EDATA = HW_TYPE_LEN; //write DHCP hw address length (6)
EDATA = 0x00; //write DHCP hops (0)
EDATA = 0x01; //write DHCP transaction id (01020304)
EDATA = 0x02;
EDATA = 0x03;
EDATA = 0x04;
EDATA = 0x00; //write DHCP elapsed boot time (0)
EDATA = 0x00;
EDATA = 0x80; //write DHCP flags (8000)
EDATA = 0x00;
i = 16;
while(i) //write ciaddr,yiaddr,siaddr,giaddr
{
EDATA = 0x00;
i--;
};
bufferptr = macaddrc;
i = 6;
while(i) //write source MAC address to chaddr
{
EDATA = *bufferptr;
bufferptr++;
i--;
};
i = 202;
while(i) //write remaining 10 bytes of 0x00 to chaddr
//write 64 bytes of 0x00 to sname
//write 128 bytes of 0x00 to file
{
EDATA = 0x00;
i--;
};
tx_end += 236;
EDATA = 0x63; //write DHCP magic cookie (63825363)
EDATA = 0x82;
EDATA = 0x53;
EDATA = 0x63;
EDATA = DHCP_MESSAGE_TYPE; //write DHCP message type
EDATA = DHCP_MESSAGE_TYPE_LEN;
EDATA = dhcpmsgtype;
tx_end += 7;
if(dhcpmsgtype == DHCP_DISCOVER_MESSAGE)
clr_offerrec;
if(dhcpmsgtype != DHCP_DISCOVER_MESSAGE &&
tempipaddrc[0] != 0x00 &&
tempipaddrc[1] != 0x00 &&
tempipaddrc[2] != 0x00 &&
tempipaddrc[3] != 0x00 )
{
EDATA = DHCP_SERVER_IDENTIFIER;
EDATA = DHCP_SERVER_IDENTIFIER_LEN;
bufferptr = svridc;
i = 4;
while(i) //write server ip address (server id)
{
EDATA = *bufferptr;
bufferptr++;
i--;
};
tx_end += 6;
}
EDATA = DHCP_PARAM_REQUEST_LIST; //write DHCP parameter list (2 entries)
EDATA = DHCP_PARAM_REQUEST_LIST_LEN;
EDATA = DHCP_SUBNET_MASK; //client's subnet mask
EDATA = DHCP_ROUTER; //routers on the client's subnet
tx_end += 4;
if(dhcpmsgtype == DHCP_REQUEST_MESSAGE)
{
EDATA = DHCP_PARAM_REQUEST_IP_ADDRESS;
EDATA = DHCP_PARAM_REQUEST_IP_ADDRESS_LEN;
bufferptr = tempipaddrc;
i = 4;
while(i) //write requested ip address
{
EDATA = *bufferptr;
bufferptr++;
i--;
};
tx_end += 6;
}
EDATA = 0xFF; //end of options
tx_end += 1;
//DHCP MESSAGE END
// write ip header total length
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART+0x11);
EWRPTH = HIGH_BYTE(TXSTART+0x00);
i = tx_end - 15;
EDATA = HIGH_BYTE(i);
EDATA = LOW_BYTE(i);
// write udp header total length
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART+0x27);
EWRPTH = HIGH_BYTE(TXSTART+0x00);
i = tx_end - 35;
EDATA = HIGH_BYTE(i);
EDATA = LOW_BYTE(i);
//compute ip header checksum
hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
offsetval = TXSTART+15; //beginning of IP header
EDMASTL = LOW_BYTE(offsetval);
EDMASTH = HIGH_BYTE(offsetval);
offsetval += (hdrlen-1);
EDMANDL = LOW_BYTE(offsetval);
EDMANDH = HIGH_BYTE(offsetval);
ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
while(ECON1 & ECON1_DMAST);
chksum_lo = EDMACSL;
chksum_hi = EDMACSH;
//write ip checksum values to TX buffer
offsetval = TXSTART+25;
EWRPTL = LOW_BYTE(offsetval);
EWRPTH = HIGH_BYTE(offsetval);
EDATA = chksum_hi;
EDATA = chksum_lo;
tx_end += (TXSTART-1);
//banksel(ETXNDL);
ETXNDL = LOW_BYTE(tx_end);
ETXNDH = HIGH_BYTE(tx_end);
//send the contents of the transmit buffer onto the network
temp = EIR;
if((temp & EIR_TXERIF) == 1)
{
TXERIF = 0;
TXRTS = 1;
TXRTS = 0;
}
TXIF = 0;
TXRTS = 1;
//do{
//temp = ECON1);
//}while((temp & ECON1_TXRTS) == 1);
while(1 == (ECON1 & ECON1_TXRTS));
// ++i;
}
//******************************************************************
//* RECEIVE DHCP MESSAGE ROUTINE
//******************************************************************
char receive_dhcp(void)
{
unsigned int i;
//char *packetptr,dhcpmsgchar;
msgtype = DHCP_UNKNOWN_MESSAGE;
clr_done;
if(packet[DHCP_op] == BOOT_REPLY)
{
if(bofferrec == 0)
{
for(i=0;i<4;++i)
tempipaddrc[i] = packet[DHCP_yiaddr+i];
}
if( packet[DHCP_chaddr] == macaddrc[0] &&
packet[DHCP_chaddr+1] == macaddrc[1] &&
packet[DHCP_chaddr+2] == macaddrc[2] &&
packet[DHCP_chaddr+3] == macaddrc[3] &&
packet[DHCP_chaddr+4] == macaddrc[4] &&
packet[DHCP_chaddr+5] == macaddrc[5])
{
packetptr = &packet[DHCP_options+4];
do{
dhcpmsgchar = *packetptr++;
switch(dhcpmsgchar)
{
case DHCP_MESSAGE_TYPE:
msglen = *packetptr++;
if(msglen == 0x01)
{
msgtype = *packetptr++;
if(bofferrec && (msgtype == DHCP_OFFER_MESSAGE))
{
set_trashit;
}
}
else
set_trashit;
break;
case DHCP_SERVER_IDENTIFIER:
msglen = *packetptr++;
if(msglen == 0x04)
{
for(i=0;i<4;++i)
{
tempsvridc[i] = *packetptr++;
}
}
else
set_trashit;
break;
case DHCP_SUBNET_MASK:
msglen = *packetptr++;
if(msglen == 0x04)
{
for(i=0;i<4;++i)
{
tempsubnetmaskc[i] = *packetptr++;
}
}
else
set_trashit;
break;
case DHCP_IP_LEASE_TIME:
msglen = *packetptr++;
if(msglen == 0x04)
{
if(bofferrec)
{
for(i=0;i<4;++i)
*packetptr++;
}
else
{
for(i=0;i<4;++i)
{
templeasetimec[i] = *packetptr++;
}
}
leasetime = make32(templeasetimec[0],templeasetimec[1],templeasetimec[2],templeasetimec[3]);
if(leasetime > 1800)
leasetime -= 1800; //renew 30 minutes before the lease expires
//uncomment line below to test DHCP RENEW
//leasetime = 60;
}
else
set_trashit;
break;
case DHCP_ROUTER:
msglen = *packetptr++;
if(msglen >= 0x04)
{
if(bofferrec)
{
for(i=0;i<4;++i)
*packetptr++;
}
else
{
for(i=0;i<4;++i)
{
tempgwayipaddrc[i] = *packetptr++;
}
}
}
else
set_trashit;
msglen -= 4;
while(msglen--)
*packetptr++;
break;
case DHCP_END_OPTION:
set_done;
break;
default:
msglen = *packetptr++;
while(msglen--)
*packetptr++;
break;
}
}while(bdone == 0);
}
}
if(msgtype == DHCP_OFFER_MESSAGE)
{
for(i=0;i<4;++i)
{
svridc[i] = tempsvridc[i];
}
set_offerrec;
}
else
{
if( svridc[0] != tempsvridc[0] ||
svridc[1] != tempsvridc[1] ||
svridc[2] != tempsvridc[2] ||
svridc[3] != tempsvridc[3] )
{
msgtype = DHCP_UNKNOWN_MESSAGE;
}
}
if(btrashit)
clr_newdhcppkt;
return msgtype;
}
//******************************************************************
//* Perform ARP Request
//* This routine uses a known remote IP address to get a remote
//* Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_request(void)
{
//char temp;
unsigned int i,tx_end;
clr_arpflag;
tx_end = TXSTART;
//load beginning page for transmit buffer
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART);
EWRPTH = HIGH_BYTE(TXSTART);
//write control byte
wr_sram(tx_control_byte);
++tx_end;
//build destination MAC address
for(i=0;i<6;++i)
{
wr_sram(0xFF);
++tx_end;
}
//build source MAC address
for(i=0;i<6;++i)
{
wr_sram(macaddrc[i]);
++tx_end;
}
wr_sram(0x08); //ARP packet type
wr_sram(0x06);
tx_end +=2;
wr_sram(0x00); //hardware type = 10Mb Ethernet
wr_sram(0x01);
tx_end +=2;
wr_sram(0x08); //IP protocol
wr_sram(0x00);
tx_end +=2;
wr_sram(0x06); //hardware addr len (06)
wr_sram(0x04); //hardware protocol addr len(04)
tx_end +=2;
wr_sram(0x00); //ARP request
wr_sram(0x01);
tx_end += 2;
//build source MAC address
for(i=0;i<6;++i)
{
wr_sram(macaddrc[i]);
++tx_end;
}
//build source IP address
for(i=0;i<4;++i)
{
wr_sram(ipaddrc[i]);
++tx_end;
}
//build unknown target MAC address area
for(i=0;i<6;++i)
{
wr_sram(0x00);
++tx_end;
}
//build target IP address
for(i=0;i<4;++i)
{
wr_sram(remoteipaddrc[i]);
++tx_end;
}
//mark end of ARP request packet
//banksel(ETXNDL);
ETXNDL = LOW_BYTE(tx_end);
ETXNDH = HIGH_BYTE(tx_end);
//send the contents of the transmit buffer onto the network
//temp = EIR);
//do{
//temp = ECON1);
while((ECON1 & ECON1_TXRTS) == 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -