📄 emac.c
字号:
volatile int intstatus = pEmac->EMAC_TSR;
if ((TxtdList[TxBuffIndex].U_Status.S_Status.BuffUsed == 0))
{
TxtdList[TxBuffIndex].addr = (unsigned int)pData;
TxtdList[TxBuffIndex].U_Status.S_Status.Length = length;
TxtdList[TxBuffIndex].U_Status.S_Status.LastBuff = 1;
if (TxBuffIndex == (NB_TX_BUFFERS - 1))
TxBuffIndex = 0;
else
TxBuffIndex ++;
}
else
return 2;
pEmac->EMAC_NCR |= AT91C_EMAC_TSTART;
return 0;
}
//*----------------------------------------------------------------------------
//* \fn AT75F_EMACInt
//* \brief Initialise Emac to receive packets
//*----------------------------------------------------------------------------
void AT91F_EMAC_HANDLER (void)
{
AT91S_IPheader IpHeader;
AT91PS_EMAC pEmac = (AT91PS_EMAC)AT91C_BASE_EMAC;
unsigned int intstatus;
unsigned int i;
intstatus = pEmac->EMAC_ISR;
if (intstatus & AT91C_EMAC_RCOMP)
{
LED_TurnOn(LED1);
if (AT91F_ProcessEmacPacket(&IpHeader) == AT91C_IPPACKET)
AT91F_DisplayIpPacket(&IpHeader);
pEmac->EMAC_RSR |= AT91C_EMAC_REC;
LED_TurnOff(LED1);
}
if(pEmac->EMAC_TSR & AT91C_EMAC_COMP == AT91C_EMAC_COMP)
{
LED_TurnOn(LED2);
pEmac->EMAC_TSR |= AT91C_EMAC_COMP;
for (i = 0; i <NB_TX_BUFFERS; i++)
{
if(TxtdList[i].U_Status.S_Status.BuffUsed == 1)
{
TxtdList[i].U_Status.S_Status.Length = 0;
TxtdList[i].U_Status.S_Status.BuffUsed = 0;
}
}
LED_TurnOff(LED2);
}
if(pEmac->EMAC_TSR & AT91C_EMAC_UBR == AT91C_EMAC_UBR )
{
LED_TurnOn(LED3);
pEmac->EMAC_TSR |= AT91C_EMAC_UBR;
LED_TurnOff(LED3);
}
}
//*----------------------------------------------------------------------------
//* \fn AT91F_IcmpChksum
//* \brief Process ICMP Checksum...
//*----------------------------------------------------------------------------
unsigned short AT91F_IcmpChksum(unsigned short *p, int len)
{
int i, t;
for (i=0,t=0; i < len; i++, p++)
t += SWAP16(*p);
t = (t & 0xffff) + (t >> 16);
return (~t);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_ProcessEmacPacket
//* \brief Process ARP and ICMP packets...
//*----------------------------------------------------------------------------
int AT91F_ProcessEmacPacket(AT91PS_IPheader pHeader)
{
unsigned int i, icmp_len;
char *pData;
int status = AT91C_NO_IPPACKET;
AT91PS_EMAC pEmac = (AT91PS_EMAC)AT91C_BASE_EMAC;
AT91PS_EthHdr pEth;
AT91PS_ArpHdr pArp;
AT91PS_IPheader pIpHeader;
AT91PS_IcmpEchoHdr pIcmpEcho;
int process = 0;
// Receive one packet
process = 0;
status = 0;
for (i = 0; i < NB_RX_BUFFERS; ++i)
{
if(RxtdList[i].addr & AT91C_OWNERSHIP_BIT)
{
if (pEmac->EMAC_RSR & AT91C_EMAC_REC == AT91C_EMAC_REC)
(pEmac->EMAC_RSR) |= AT91C_EMAC_REC;
process = 1;
break;
}
}
if (!process)
return AT91C_NO_IPPACKET;
process = i;
// Process this packet
pData = (char *)(RxtdList[i].addr & 0xFFFFFFFC);
pEth = (AT91PS_EthHdr)(pData + AT91C_RCV_OFFSET);
#if AT91C_DISPLAY_ALL_IPHEADER
status = AT91C_IPPACKET;
#endif
switch (SWAP16(pEth->et_protlen))
{
case PROT_ARP: // ARP Packet format
pArp = (AT91PS_ArpHdr)(pData + 14 + AT91C_RCV_OFFSET);
if (SWAP16(pArp->ar_op) == ARP_REQUEST) {
// ARP REPLY operation
pArp->ar_op = SWAP16(ARP_REPLY);
// Fill the dest address and src address
for (i = 0; i <6; i++) {
// swap ethernet dest address and ethernet src address
pEth->et_dest[i] = pEth->et_src[i];
pEth->et_src[i] = OurEmacAddr[i];
pArp->ar_tha[i] = pArp->ar_sha[i];
pArp->ar_sha[i] = OurEmacAddr[i];
}
// swap sender IP address and target IP address
for (i = 0; i<4; i++) {
pArp->ar_tpa[i] = pArp->ar_spa[i];
pArp->ar_spa[i] = OurIpAddr[i];
}
//if ((pArp->ar_tpa[0]==10)&&(pArp->ar_tpa[1]==159)&&(pArp->ar_tpa[2]==245)&&(pArp->ar_tpa[3]==203))
AT91F_TransmitPacket((pData + AT91C_RCV_OFFSET), 0x40);
}
break; // case PROT_ARP
case PROT_IP: // IP protocol frame
pIpHeader = (AT91PS_IPheader)(pData + 14 + AT91C_RCV_OFFSET);
pIcmpEcho = (AT91PS_IcmpEchoHdr)((char *)pIpHeader + 20);
memcpy(pHeader, pIpHeader,sizeof(AT91S_IPheader));
#if AT91C_DISPLAY_ALL_IPHEADER
status = AT91C_IPPACKET;
#endif
switch(pIpHeader->ip_p)
{
case PROT_ICMP:
// set the status variable to display in main.c only ICMP packets
status = AT91C_IPPACKET;
// if ICMP_ECHO_REQUEST ==> resp = ICMP_ECHO_REPLY
if(pIcmpEcho->type == ICMP_ECHO_REQUEST)
{
pIcmpEcho->type = ICMP_ECHO_REPLY;
pIcmpEcho->code = 0;
pIcmpEcho->cksum = 0;
// Checksum of the ICMP Message
icmp_len = (SWAP16(pIpHeader->ip_len) - 20);
if (icmp_len % 2)
{
*((unsigned char *)pIcmpEcho + icmp_len) = 0;
icmp_len ++;
}
icmp_len = icmp_len / sizeof(unsigned short);
pIcmpEcho->cksum = SWAP16(AT91F_IcmpChksum((unsigned short *) pIcmpEcho, icmp_len));
// Swap IP Dest address and IP Source address
for(i = 0; i <4; i++) {
pIpHeader->ip_dst[i] = pIpHeader->ip_src[i];
pIpHeader->ip_src[i] = OurIpAddr[i];
}
// Swap Eth Dest address and Eth Source address
for(i = 0; i <6; i++)
{
// swap ethernet dest address and ethernet src address
pEth->et_dest[i] = pEth->et_src[i];
pEth->et_src[i] = OurEmacAddr[i];
}
// send the echo_reply
//if ((pIpHeader->ip_dst[0]==10)&&(pIpHeader->ip_dst[1]==159)&&(pIpHeader->ip_dst[2]==245)&&(pIpHeader->ip_dst[3]==203))
AT91F_TransmitPacket((pData + AT91C_RCV_OFFSET), SWAP16(pIpHeader->ip_len) + 14 + AT91C_RCV_OFFSET);
}
break; // case PROT_ICMP
default:
break;
}
break; // case PROT_IP
default:
break;
}// switch (SWAP16(*pFrameType))
// The packet has been processed ==> release the corresponding buffers descriptors
#if 1
RxtdList[process].addr &= ~(AT91C_OWNERSHIP_BIT);
if(RxtdList[process].U_Status.status & AT91C_SOF)
{
if(!(RxtdList[process].U_Status.status & AT91C_EOF))
{
do
{
if (process == (NB_RX_BUFFERS-1))
process = 0;
else
process++;
RxtdList[process].addr &= ~(AT91C_OWNERSHIP_BIT);
}
while(!(RxtdList[process].U_Status.status & AT91C_EOF));
}
}
// if (pEmac->EMAC_RSR & AT91C_EMAC_REC == AT91C_EMAC_REC)
// (pEmac->EMAC_RSR) |= AT91C_EMAC_REC;
#endif
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -