📄 enc28j60.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 + -