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

📄 enc28j60.c

📁 力天电子 dsp源码
💻 C
字号:
/******************************************************************/
/*Copyright (C), 2008-2009, 力天电子,LiTian Tech.Co.Ltd.		  */
/*  Module Name   : ENC28J60          							  */
/*  File Name     : ENC28J60.c	   								  */        
/*  Author   	  : 侯长波                                        */     
/*  Create Date   : 2009/10/1                                     */      
/*  Version   	  : 1.0                                           */          
/*  Function      :                         					  */                       
/*  Description   :                                               */            
/*  Support       : www.LT430.com 				                  */             
/******************************************************************/
  
/*****************头文件********************/  
#include "DSP281x_Device.h"
#include "System.h"   
#include "reg.h"
#include "Ne2000.h"
#include "ARP.h"
#include "ICMP.h"

#define CS_DIR   GpioMuxRegs.GPFDIR.bit.GPIOF3
#define CS 	     GpioDataRegs.GPFDAT.bit.GPIOF3
#define SIMO_DIR GpioMuxRegs.GPFDIR.bit.GPIOF0
#define SIMO     GpioDataRegs.GPFDAT.bit.GPIOF0
#define SOMI_DIR GpioMuxRegs.GPFDIR.bit.GPIOF1
#define SOMI     GpioDataRegs.GPFDAT.bit.GPIOF1
#define SCLK_DIR GpioMuxRegs.GPFDIR.bit.GPIOF2
#define SCLK     GpioDataRegs.GPFDAT.bit.GPIOF2
#define RES_DIR  GpioMuxRegs.GPDDIR.bit.GPIOD5
#define RES 	 GpioDataRegs.GPDDAT.bit.GPIOD5
#define INT_DIR  GpioMuxRegs.GPEDIR.bit.GPIOE2
#define INT      GpioDataRegs.GPEDAT.bit.GPIOE2 

union NetNode myNode;
union netcard rxdnetbuf;
union netcard txdnetbuf;

unsigned char ENC28J60_Bank;
unsigned int  NextPacketPtr;

void Set_MacAddress(void);
void Init_ENC28J60(void);
void Write_Phy(unsigned char add, unsigned int data);
void encPacketSend(union ethernet_address_type *pDestAddr, union netcard *txdnet,
                   unsigned int buffer_length, unsigned int packet_type);
unsigned int encPacketReceive(union netcard *rxdnet);

void Init_GPIO(void)
{
	EALLOW;
	CS_DIR=1;
	SIMO_DIR=1;
	SOMI_DIR=0;
	SCLK_DIR=1;
	RES_DIR=1;
	INT_DIR=0;
	EDIS;
	CS=1;
	SCLK=0;
	RES=1;		
}

void Write_One(unsigned char data)  
{
  	unsigned char i,j,temp;
  	temp=data;
  	for(i=0;i<8;i++)
  	{
    	if((temp&0x80)==0x80)
      		SIMO=1;
    	else
      		SIMO=0;
    	SCLK=1;
		for(j=0;j<10;j++);
    	SCLK=0;
		for(j=0;j<10;j++);
    	temp<<=1;
  	}
}

unsigned char Read_One(void)
{
  	unsigned char i,j,temp=0;
  	for(i = 0;i < 8;i++)
  	{
    	if(SOMI==1)
      		temp |= (0x01 << (7-i));
    	SCLK=1;
		for(j=0;j<10;j++);
    	SCLK=0;
		for(j=0;j<10;j++);
  	}
  	return(temp);
}

void Write_All(unsigned char com,unsigned char add,unsigned char data) 
{
	unsigned char temp;
  	CS=0;
  	temp=com |(add&ADDR_MASK);
	Write_One(temp);
  	Write_One(data);
  	CS=1;
}

unsigned char Read_All(unsigned char com,unsigned char add)
{
	unsigned int temp=0;
  	CS=0;
  	temp=com |(add&ADDR_MASK);
  	Write_One(temp);
	temp=Read_One();
	if(add&0x80)
	{
		temp=Read_One();
	}
	CS=1;
  	return(temp);
}

void Set_Bank(unsigned char add)
{
	if((add & BANK_MASK) != ENC28J60_Bank)
	{
		Write_All(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
		Write_All(ENC28J60_BIT_FIELD_SET, ECON1, (add & BANK_MASK)>>5);
		ENC28J60_Bank = (add & BANK_MASK);
	}
}

void Write_Control(unsigned char add,unsigned int data)  
{
	Set_Bank(add);
  	Write_All(ENC28J60_WRITE_CTRL_REG, add, data);
}

unsigned char Read_Control(unsigned char add)
{
	unsigned char temp;
  	Set_Bank(add);
	temp=Read_All(ENC28J60_READ_CTRL_REG, add);
  	return(temp);
}

void Read_Buffer(unsigned int len,unsigned char *data)
{
	unsigned char temp;
  	CS=0;
  	temp=ENC28J60_READ_BUF_MEM;
  	Write_One(temp);
	while(len--)
	{
		temp=Read_One();
		*data++=temp;
	}
	CS=1;
}

void Write_Buffer(unsigned int len,unsigned char *data)
{
	unsigned char temp;
  	CS=0;
  	temp=ENC28J60_WRITE_BUF_MEM;
  	Write_One(temp);
	while(len--)
	{
		temp=*data++;
		Write_One(temp);
	}
	CS=1;
}

void Soft_RESET(void)
{
	unsigned char temp;
	unsigned int i;
  	CS=0;
  	temp=ENC28J60_SOFT_RESET;
  	Write_One(temp);
  	CS=1;
  	for(i=0;i<1000;i++);
  	while(!(Read_Control(ESTAT) & ESTAT_CLKRDY));	
}

void Set_MacAddress(void)
{
	Write_Control(MAADR0, myNode.node.mac[5]);
	Write_Control(MAADR1, myNode.node.mac[4]);
	Write_Control(MAADR2, myNode.node.mac[3]);
	Write_Control(MAADR3, myNode.node.mac[2]);
	Write_Control(MAADR4, myNode.node.mac[1]);
	Write_Control(MAADR5, myNode.node.mac[0]);
}

void Write_Phy(unsigned char add, unsigned int data)
{
	Write_Control(MIREGADR, add);
	Write_Control(MIWRL, data);	
	Write_Control(MIWRH, data>>8);
	while(Read_Control(MISTAT) & MISTAT_BUSY);
}

void Init_ENC28J60(void)
{
	unsigned int i;
	Init_GPIO();
	Soft_RESET();
	for(i=0;i<5000;i++);
	while(!(Read_Control(ESTAT) & ESTAT_CLKRDY));
	NextPacketPtr = RXSTART_INIT;
	Write_Control(ERXSTL, RXSTART_INIT&0xFF);
	Write_Control(ERXSTH, RXSTART_INIT>>8);
	Write_Control(ERXRDPTL, RXSTART_INIT&0xFF);
	Write_Control(ERXRDPTH, RXSTART_INIT>>8);
	Write_Control(ERXNDL, RXSTOP_INIT&0xFF);
	Write_Control(ERXNDH, RXSTOP_INIT>>8);
	Write_Control(ETXSTL, TXSTART_INIT&0xFF);
	Write_Control(ETXSTH, TXSTART_INIT>>8);
	Write_Control(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
	Write_Control(MACON2, 0x00);
	Write_All(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
	Write_Control(MAIPGL, 0x12);
	Write_Control(MAIPGH, 0x0C);
	Write_Control(MABBIPG, 0x12);
	Write_Control(MAMXFLL, MAX_FRAMELEN&0xFF);	
	Write_Control(MAMXFLH, MAX_FRAMELEN>>8);
	Set_MacAddress();
	Write_Phy(PHCON2, PHCON2_HDLDIS);
	Set_Bank(ECON1);
	Write_All(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC);
	Write_All(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
	Write_All(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);	
}

void encPacketSend(union ethernet_address_type *pDestAddr, union netcard *txdnet, 
                  unsigned int buffer_length, unsigned int packet_type)
{
	unsigned char i;
	for(i = 0; i < 6; i++)
	{
    	txdnet->etherframe.sourcenodeid[i] = myNode.node.mac[i];
   	}
	// Load the destination address
    for(i = 0; i < 6; i++)
    {
    	txdnet->etherframe.destnodeid[i] = pDestAddr->bytes[i];
    }
    txdnet->etherframe.protocal_L = packet_type;
	txdnet->etherframe.protocal_H = (packet_type>>8);

	// Set the write pointer to start of transmit buffer area
	Write_Control(EWRPTL, TXSTART_INIT);
	Write_Control(EWRPTH, TXSTART_INIT>>8);
	// Set the TXND pointer to correspond to the packet size given
	Write_Control(ETXNDL, (TXSTART_INIT+buffer_length));
	Write_Control(ETXNDH, (TXSTART_INIT+buffer_length)>>8);

	// write per-packet control byte
	Write_All(ENC28J60_WRITE_BUF_MEM, 0, 0x00);

	// copy the packet into the transmit buffer
	Write_Buffer(buffer_length, txdnet->bytedata.bytebuf);
	
	// send the contents of the transmit buffer onto the network
	Write_All(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
}

unsigned int encPacketReceive(union netcard *rxdnet)
{
	unsigned int rxstat;
	unsigned int len;

	// check if a packet has been received and buffered
	if( !(Read_Control(EIR) & EIR_PKTIF) )
		return 0;

	// Set the read pointer to the start of the received packet
	Write_Control(ERDPTL, (NextPacketPtr));
	Write_Control(ERDPTH, (NextPacketPtr)>>8);
	// read the next packet pointer
	NextPacketPtr  = Read_All(ENC28J60_READ_BUF_MEM, 0);
	NextPacketPtr |= Read_All(ENC28J60_READ_BUF_MEM, 0)<<8;
	// read the packet length
	len  = Read_All(ENC28J60_READ_BUF_MEM, 0);
	len |= Read_All(ENC28J60_READ_BUF_MEM, 0)<<8;
	// read the receive status
	rxstat  = Read_All(ENC28J60_READ_BUF_MEM, 0);
	rxstat |= Read_All(ENC28J60_READ_BUF_MEM, 0)<<8;

	if (len>MAX_FRAMELEN)
    {        len=MAX_FRAMELEN;    }    // check CRC and symbol errors (see datasheet page 44, table 7-3):    // The ERXFCON.CRCEN is set by default. Normally we should not    // need to check this.    if ((rxstat & 0x80)==0)
    {        // invalid       	len=0;
		return 0;    }
    else
    {
		len=len-4;                    }
	// copy the packet from the receive buffer
	Read_Buffer(len,rxdnet->bytedata.bytebuf);

	// Move the RX read pointer to the start of the next received packet
	// This frees the memory we just read out
	Write_Control(ERXRDPTL, (NextPacketPtr));
	Write_Control(ERXRDPTH, (NextPacketPtr)>>8);

	// decrement the packet counter indicate we are done with this packet
	Write_All(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);

	return len;
}

/*------------------------------------------*/
/*形式参数:void                            */
/*返回值:void				                */
/*函数描述:扫描函数 			            */
/*------------------------------------------*/ 
void Scan_ENC28J60(void)
{  
	unsigned int num_bytes,protocal,operation;
	// Unload packet from the receive buffer and store in <RX_BUFF>   
    num_bytes = encPacketReceive(&rxdnetbuf);
	if(num_bytes > 0)
	{
		protocal=(rxdnetbuf.etherframe.protocal_H<<8) | rxdnetbuf.etherframe.protocal_L;
		if(protocal==ARP_PACKET)//表示收到一个arp请求包
		{			
			operation=(rxdnetbuf.arpframe.operation_H<<8) | rxdnetbuf.arpframe.operation_L;
			if(operation==0x0001)
			{
				arp_answer();//ARP request,处理arp数据包
			}
			else if(operation==0x0002)
			{
				arp_process();//ARP answer
			}
		}
			//收到一个IP包
		else if((protocal == IP_PACKET)		
			&& ((rxdnetbuf.ipframe.verandihl&0xf0) == 0x40)	//	IP V4
			&& (rxdnetbuf.ipframe.destip[0] == myNode.nodebytes.ipbytes[0])
			&& (rxdnetbuf.ipframe.destip[1] == myNode.nodebytes.ipbytes[1])
			&& (rxdnetbuf.ipframe.destip[2] == myNode.nodebytes.ipbytes[2])
			&& (rxdnetbuf.ipframe.destip[3] == myNode.nodebytes.ipbytes[3]))//my IP
		{		
			arp_ip_mac();
			if(rxdnetbuf.ipframe.protocal == 1)			//	ICMP
			{
				if(rxdnetbuf.icmpframe.type == 8)		//	echo
				{
					ping_answer();
				}
			}
			else if(rxdnetbuf.ipframe.protocal == 17)	//	udp
			{
				//	net_udp_rcv();
			}
			else if(rxdnetbuf.ipframe.protocal == 6)	//	tcp
			{
				//	tcp_rcve(&rxdnetbuf);;
			}
		}
		else
		{
			//Lib_Uart_SendString("\nIEEE 802 packet rejected!\n");		//	IEEE 802 pkt rejected
		}
	}
} 

void Init_Network(void)
{	
	myNode.node.ip = IP4_ADDR(5,109,155,58);
	myNode.node.mask = IP4_ADDR(0,255,255,255);
	myNode.node.gate = IP4_ADDR(1,109,155,58);
	myNode.node.mac[0] = 0x00;
	myNode.node.mac[1] = 0x14;
	myNode.node.mac[2] = 0x2A;
	myNode.node.mac[3] = 0xBA;
	myNode.node.mac[4] = 0xFC;
	myNode.node.mac[5] = 0xAB;	
	Init_ENC28J60();
	Set_MacAddress();	
	Write_Phy(0x14,0x0470);
	arptab_init();
}

⌨️ 快捷键说明

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