📄 cs8900.c
字号:
if ( (status & PP_BusStat_TxRDY) == 0)
{
/* If not ready for Tx now, abort this frame.*/
/* Note: Another alternative is to poll PP_BusStat_TxRDY until it is set, if you don't want to
abort Tx frames.*/
/* set gPrevTxBidFail to 1, and next time if cs8900_poll_send() is called, it can
set PP_TxCmd_Force to clear off the reserved Tx buffer in CS8900 chip */
gPrevTxBidFail = 1;
INT_ENABLE(26);
return -1;
}
/* Step 5: copy Tx data into CS8900's buffer */
/* This actually starts the Txmit*/
sdata = (unsigned short *)gTxDataBuf;
len = gTxLength;
if (len > 0) {
/* Output contiguous words, two bytes at a time. */
while (len > 1)
{
CS8900_RTDATA = *sdata;
sdata++;
len -= 2;
}
/* If Odd bytes, copy the last one byte to chip.*/
if (len == 1)
{
CS8900_RTDATA = (*sdata & 0x00ff);
}
}
/* Enable interrupts at processor level if it is disabled in step 0 */
INT_ENABLE(26);
/* Step 6: Poll the TxEvent Reg for the TX completed status */
/* This step is optional. If you don't wait until Tx compelete, the next cs8900_poll_send()
Bid For Tx may encounter Not Ready For Tx because CS8900 is still Tx'ing.*/
for (i=0; i<30000; i++)
{
status = ReadReg(PP_TER);
if ( status != 0x0008 )
{
break;
}
}
/* Tx compelete without error, return total_length Tx'ed */
if ((status & PP_TER_TxOK) || (status == 0x0008))
{
return gTxLength; /* return successful*/
}
/* Tx with Errors, Return failed */
return -1;
}
/* Ether */
#define ETH_DES 0 /* DESTINATION */
#define ETH_SRC 6 /* SOURCE */
#define ETH_PRO 12 /* PROTOCOL */
/* ARP */
#define ARP_HRD 14 /* HARDWARE TYPE */
#define ARP_PRO 16 /* PROTOCOL TYPE */
#define ARP_HLN 18 /* HARDWARE SIZE */
#define ARP_PLN 19 /* PROTOCOL SIZE */
#define ARP_OPC 20 /* OPERATION CODE */
#define ARP_SHA 22 /* SENDER HARDWARE ADDRESS */
#define ARP_SPA 28 /* SENDER PROTOCOL ADDRESS */
#define ARP_THA 32 /* TARGET HARDWARE ADDRESS */
#define ARP_TPA 38 /* TARGET PROTOCOL ADDRESS */
/* IP */
#define IP_HLV 14 /* HEADER LENGTH AND VERSION */
#define IP_TOS 15 /* TYPE OF SERVICE */
#define IP_LEN 16 /* TOTAL LENGTH */
#define IP_ID 18 /* IDENTIFICATION */
#define IP_OFF 20 /* FRAGMENT OFFSET FIELD */
#define IP_TTL 22 /* TIME TO LIVE */
#define IP_PRO 23 /* PROTOCOL */
#define IP_SUM 24 /* CHECKSUM */
#define IP_SRC 26 /* SOURCE IP ADDRESS */
#define IP_DST 30 /* DESTINATION IP ADDRESS */
/* ICMP */
#define ICMP_TYP 34 /* TYPE */
#define ICMP_COD 35 /* CODE */
#define ICMP_SUM 36 /* CHECKSUM */
#define ICMP_ID 38 /* IDENTIFIER */
#define ICMP_SEQ 40 /* SEQUENCE NUMBER */
#define ICMP_DAT 42 /* ICMP DATA */
/* UDP */
#define UDP_SRC 34 /* UDP SOURCE PORT */
#define UDP_DST 36 /* UDP DESTINATION PORT */
#define UDP_LEN 38 /* LENGTH OF UDP PACKET */
#define UDP_SUM 40 /* CHECKSUM */
#define UDP_DAT 42 /* UDP DATA */
unsigned char LocalIp[4] = {192,168, 0,123};
unsigned short TxCntr = 0;
unsigned char EthBroadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char EthArp[2] = {0x08, 0x06};
unsigned char EthIP[2] = {0x08, 0x00};
unsigned char ArpRequest[8] = {0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01};
unsigned char ArpReply[8] = {0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02};
unsigned char IpHead[2] = {0x45, 0x00};
unsigned char IpIcmp[1] = {0x01};
unsigned char IpUdp[1] = {0x11};
unsigned char IcmpRequest[1] = {0x08};
unsigned char IcmpReply[1] = {0x00};
unsigned char UdpSum[2] = {0x00, 0x00};
int MemoryMatch(unsigned char *a, unsigned char *b, int len)
{
int i;
for (i=0; i<len; i++)
{
if (*a != *b) return 0;
a++;
b++;
}
return 1;
}
void MemoryCopy(unsigned char *a, unsigned char *b, int len)
{
int i;
for (i=0; i<len; i++)
{
*a = *b;
a++;
b++;
}
}
void MemoryFill(unsigned char *a, unsigned char b, int len)
{
int i;
for (i=0; i<len; i++)
{
*a = b;
a++;
}
}
unsigned short CheckSum(unsigned short *addr, int len)
{
int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
void cmd_eth(void)
{
unsigned char *rx;
unsigned char *tx;
int rx_len;
unsigned short sum, ulen;
rx = gRxDataBuf;
tx = gTxDataBuf;
cs8900_poll_init();
for (;;)
{
rx_len = cs8900_poll_recv();
if (rx_len>0)
{
if (MemoryMatch(&rx[ARP_HRD], ArpRequest, 8)) // A arp request?
if (MemoryMatch(&rx[ARP_TPA], LocalIp, 4)) // Calling me?
{
MemoryFill(tx, 0x00, 60);
MemoryCopy(&tx[ETH_DES], &rx[ETH_SRC], 6); // Dest MAC
MemoryCopy(&tx[ETH_SRC], gEtherAddr, 6); // My MAC
MemoryCopy(&tx[ETH_PRO], EthArp, 2); // ARP PROTOCOL
MemoryCopy(&tx[ARP_HRD], ArpReply, 8); // ARP reply head
MemoryCopy(&tx[ARP_SHA], gEtherAddr, 6); // My MAC
MemoryCopy(&tx[ARP_SPA], LocalIp, 4); // My IP
MemoryCopy(&tx[ARP_THA], &rx[ARP_SHA], 6); // Dest MAC
MemoryCopy(&tx[ARP_TPA], &rx[ARP_SPA], 4); // Dest IP
gTxLength=60;
cs8900_poll_send();
TxCntr++;
}
if (MemoryMatch(&rx[IP_HLV], IpHead, 2)) // A normal IP header?
if (CheckSum((unsigned short *)(&rx[IP_HLV]), 20)==0) // A good IP header?
if (MemoryMatch(&rx[IP_DST], LocalIp, 4)) // Is an IP for me?
if (MemoryMatch(&rx[ICMP_TYP], IcmpRequest, 1)) // An echo request?
{
ulen = rx[IP_LEN]*0x100 + rx[IP_LEN+1] - 20;
MemoryCopy(tx, rx, rx_len); // Copy IP header & echo data & etc.
// Ether
MemoryCopy(&tx[ETH_DES], &rx[ETH_SRC], 6); // Dest MAC
MemoryCopy(&tx[ETH_SRC], gEtherAddr, 6); // My MAC
MemoryCopy(&tx[ETH_PRO], EthIP, 2); // IP PROTOCOL
// IP
tx[IP_ID] = (TxCntr>>16)&0xFF;
tx[IP_ID+1] = TxCntr&0xFF;
tx[IP_TTL] = 128;
MemoryCopy(&tx[IP_SRC], &rx[IP_DST], 4); // My IP
MemoryCopy(&tx[IP_DST], &rx[IP_SRC], 4); // Dest IP
MemoryFill(&tx[IP_SUM], 0x00, 2); // Reset Checksum
sum = CheckSum((unsigned short *)(&tx[IP_HLV]), 20);
MemoryCopy(&tx[IP_SUM], (unsigned char*)(&sum), 2); // New Checksum;
// ICMP
MemoryCopy(&tx[ICMP_TYP], IcmpReply, 1); // ICMP reply
MemoryFill(&tx[ICMP_SUM], 0x00, 2); // Reset Checksum
sum = CheckSum((unsigned short *)(&tx[ICMP_TYP]), ulen);
MemoryCopy(&tx[ICMP_SUM], (unsigned char*)(&sum), 2); // New Checksum;
gTxLength=ulen + 20 + 14;
cs8900_poll_send();
TxCntr++;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -