⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emac.c

📁 arm_7x256的ADS1.2的网络测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -