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

📄 at91emac.c

📁 ATMEL920T的BSP及ETH等已经设备驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------------	*/
/*         ATMEL Microcontroller Software Support  -  ROUSSET  -							*/
/*----------------------------------------------------------------------------	*/
/* The software is delivered "AS IS" without warranty or condition of any					*/
/* kind, either express, implied or statutory. This includes without							*/		
/* limitation any warranty or condition with respect to merchantability or						*/
/* fitness for any particular purpose, or against the infringements of						*/
/* intellectual property rights of others.												*/
/*----------------------------------------------------------------------------	*/
/* File Name           : main.c															*/
/* Object              : main application written in C										*/	
/* Creation            : Hi   11/18/2002													*/
/*																				*/
/*----------------------------------------------------------------------------	*/
/*#include "AT91RM9200.h"*/
/*#include "lib_AT91RM9200.h"*/
#include "AT91Emac.h"
#include <string.h>
#include "end.h"
extern unsigned int AT91F_GetTickCount(void);

/* Our Ethernet MAC address and IP address*/
char OurEmacAddr[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
unsigned char OurIpAddr[4]  = {192, 168, 0, 254}; /* {0x0A, 0xD7, 0xF5, 0xAC}*/

/*Buffer descriptor address must be word aligned*/
#define AT91C_EMAC_TDLIST_BASE	0x20010000

char RxPacket[NB_ETH_RX_PACKETS*ETH_PACKET_SIZE+sizeof(unsigned long)];
AT91PS_TdDescriptor tdList = (AT91PS_TdDescriptor)AT91C_EMAC_TDLIST_BASE;



/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_PMC_EnablePeriphClock												*/
/* \brief Enable peripheral clock														*/	
/*----------------------------------------------------------------------------	*/
__inline void AT91F_PMC_EnablePeriphClock (
	AT91PS_PMC pPMC, /* \arg pointer to PMC controller*/
	unsigned int periphIds)  /* \arg IDs of peripherals to enable*/
{
	pPMC->PMC_PCER = periphIds;
}


/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_EMAC_CfgPMC														*/
/* \brief Enable Peripheral clock in PMC for  EMAC										*/	
/*----------------------------------------------------------------------------	*/
__inline void AT91F_EMAC_CfgPMC (void)
{
	AT91F_PMC_EnablePeriphClock(
		AT91C_BASE_PMC, /* PIO controller base address*/
		((unsigned int) 1 << AT91C_ID_EMAC));
}


/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_PIO_CfgPeriph														*/
/* \brief Enable pins to be drived by peripheral											*/
/*----------------------------------------------------------------------------	*/
__inline void AT91F_PIO_CfgPeriph(
/*	AT91PS_PIO pPio,            */ /* \arg pointer to a PIO controller*/
	UINT32 pPio,					/* \arg pointer to a PIO controller*/
	unsigned int periphAEnable,  /* \arg PERIPH A to enable*/
	unsigned int periphBEnable)  /* \arg PERIPH B to enable*/

{
/*
	pPio->PIO_ASR = periphAEnable;
	pPio->PIO_BSR = periphBEnable;
	pPio->PIO_PDR = (periphAEnable | periphBEnable); *//* Set in Periph mode*/


	(*(volatile UINT32 *)((UINT32)pPio+ (PIO_ASR))) = periphAEnable;
	(*(volatile UINT32 *)((UINT32)pPio+ (PIO_BSR))) = periphBEnable;
	(*(volatile UINT32 *)((UINT32)pPio+ (PIO_PDR))) = (periphAEnable | periphBEnable);/* Set in Periph mode*/
}


/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_EMAC_CfgPIO														*/
/* \brief Configure PIO controllers to drive EMAC signals									*/	
/*----------------------------------------------------------------------------	*/
__inline void AT91F_EMAC_CfgPIO (void)
{
	/* Configure PIO controllers to periph mode*/
	AT91F_PIO_CfgPeriph(
		AT91C_BASE_PIOA, /* PIO controller base address*/
		((unsigned int) AT91C_PA14_ERXER   ) |
		((unsigned int) AT91C_PA12_ERX0    ) |
		((unsigned int) AT91C_PA13_ERX1    ) |
		((unsigned int) AT91C_PA8_ETXEN   ) |
		((unsigned int) AT91C_PA16_EMDIO   ) |
		((unsigned int) AT91C_PA9_ETX0    ) |
		((unsigned int) AT91C_PA10_ETX1    ) |
		((unsigned int) AT91C_PA11_ECRS_ECRSDV) |
		((unsigned int) AT91C_PA15_EMDC    ) |
		((unsigned int) AT91C_PA7_ETXCK_EREFCK), /* Peripheral A*/
		0); /* Peripheral B*/
}

/********************************************************************************/
/** EMAC lowlevel functions 															*/
/********************************************************************************/
/*----------------------------------------------------------------------------		*/
/* \fn    AT91F_MII_ReadPhy															*/
/* \brief This function return the MII phy register											*/
/*----------------------------------------------------------------------------		*/
unsigned short AT91F_MII_ReadPhy(
	AT91PS_EMAC pEmac,     /* \arg Pointer to AT91PS_EMAC service*/
	unsigned char addr) 
{
	unsigned int Wait = AT91F_GetTickCount() + 10;
	unsigned int value = 0x60020000 | (addr << 18);

	pEmac->EMAC_MAN = value;
  	while(AT91F_GetTickCount() < Wait);
	return (pEmac->EMAC_MAN & 0x0000ffff);
}



/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_MII_GetLinkSpeed													*/
/* \brief This function configure the link speed											*/
/*----------------------------------------------------------------------------	*/
int MII_GetLinkSpeed(AT91PS_EMAC pEmac)     /* \arg Pointer to AT91PS_EMAC service*/
{
  unsigned short stat1, stat2; 
  
	stat1 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG);
	stat1 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG);

	stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG);
    
    /*set MII for 100BaseTX and Full Duplex*/
	if ((stat1 & 0x4000) && (stat2 & 0x8000) )
    	pEmac->EMAC_CFG |= (AT91C_EMAC_SPD| AT91C_EMAC_FD);    
    /*set MII for 10BaseT and Full Duplex */
	else if ((stat1 & 0x1000) && (stat2 & 0x2000))
    	pEmac->EMAC_CFG = (pEmac->EMAC_CFG & AT91C_EMAC_SPD) | AT91C_EMAC_FD;
    /*set MII for 100BaseTX and Half Duplex */
	else if ((stat1 & 0x2000) && (stat2 & 0x4000))
    	pEmac->EMAC_CFG = (pEmac->EMAC_CFG | AT91C_EMAC_SPD ) & ~AT91C_EMAC_FD;
    /*set MII for 10BaseT and Half Duplex */
	else if ((stat1 & 0x0800) && (stat2 & 0x1000))
    	pEmac->EMAC_CFG = pEmac->EMAC_CFG & ~AT91C_EMAC_SPD & ~AT91C_EMAC_FD;

	return 0;
}

/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_MDIO_StartupPhy														*/
/* \brief This function start the phy													*/
/*----------------------------------------------------------------------------	*/
int AT91F_MDIO_StartupPhy(AT91PS_EMAC pEmac)     /* \arg Pointer to AT91PS_EMAC service*/
{
	int ret;
	if(pEmac->EMAC_SR & AT91C_EMAC_LINK)
		return 0;

	pEmac->EMAC_CTL |= AT91C_EMAC_MPE;

	ret = MII_GetLinkSpeed(pEmac);

	pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE;
  
	return 0;
}


/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_EMACInit															*/
/* \brief This function initialise the ethernet												*/
/*----------------------------------------------------------------------------	*/
int AT91F_EMACInit( /* \return Status ( Success = 0)*/
		AT91PS_EMAC pEmac,     /* \arg Pointer to AT91PS_EMAC service*/
		unsigned int pTdList)
{
	int status;
	
	AT91F_EMAC_CfgPMC();
	AT91F_EMAC_CfgPIO();

	status = AT91F_MDIO_StartupPhy(pEmac);
	if ( status )
		return status;

	/* the sequence write EMAC_SA1L and write EMAC_SA1H must be respected*/
	pEmac->EMAC_SA1L = ((int)OurEmacAddr[2] << 24) | ((int)OurEmacAddr[3] << 16) | ((int)OurEmacAddr[4] << 8) | OurEmacAddr[5];
	pEmac->EMAC_SA1H = ((int)OurEmacAddr[0] << 8) | OurEmacAddr[1];

	pEmac->EMAC_RBQP = pTdList;
	pEmac->EMAC_RSR  &= ~(AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
	pEmac->EMAC_CFG  |= (AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII);
	pEmac->EMAC_CFG  &= ~(AT91C_EMAC_CLK);
	pEmac->EMAC_CTL  |= (AT91C_EMAC_TE | AT91C_EMAC_RE);

 	return 0;
}

/*----------------------------------------------------------------------------	*/
/* \fn    AT91F_EmacEntry															*/
/* \brief Initialise Emac to receive packets												*/	
/*----------------------------------------------------------------------------	*/
int AT91F_EmacEntry(void)
{
	unsigned int i;
	char *pRxPacket;
	
	pRxPacket = (char *)((RxPacket+sizeof(unsigned long))&(~(sizeof(unsigned long)-1));

	/* Initialise tdList descriptor. This descriptor must be WORD aligned*/
	for (i = 0; i < NB_ETH_RX_PACKETS; i++) 
	{
		tdList[i].addr = ((unsigned int) (pRxPacket + (i * ETH_PACKET_SIZE))) & 0xFFFFFFFC;
		tdList[i].size = 0;
	}
	
	/* Set the WRAP bit at the end of the list descriptor*/
	tdList[NB_ETH_RX_PACKETS-1].addr |= 0x02;
	
	return(AT91F_EMACInit(AT91C_BASE_EMAC, (unsigned int) tdList));
}	



/*----------------------------------------------------------------------------	*/
/* \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 short *pFrameType, *pArpOp;
	unsigned int i, icmp_len;
	char *pData;
	int status = AT91C_NO_IPPACKET;
	
	AT91PS_IPheader pIpHeader;
	AT91PS_IcmpEchoHdr pIcmpEcho;
	int process = 0;
	

	/* Receive one packet		*/
	process = 0;	
	status = 0;
	for (i = 0; i < NB_ETH_RX_PACKETS; i++) {				
		if(tdList[i].addr & 0x1) {
			if (*AT91C_EMAC_RSR & AT91C_EMAC_REC)
				(*AT91C_EMAC_RSR) |= AT91C_EMAC_REC;
			process = 1;	
			break;				
		}
	}
		
	if (!process)
		return AT91C_NO_IPPACKET;
						
	process = i;
		
	/* Process this packet*/
	pFrameType = (unsigned short *) ((tdList[i].addr & 0xFFFFFFFC) + 12);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -