409 lines
13 KiB
C
409 lines
13 KiB
C
#include "enc28j60.h"
|
||
#include "spi.h"
|
||
#include <stdio.h>
|
||
|
||
static unsigned char Enc28j60Bank;
|
||
static unsigned int NextPacketPtr;
|
||
|
||
|
||
unsigned char enc28j60ReadOp(unsigned char op, unsigned char address)
|
||
{
|
||
unsigned char dat = 0;
|
||
|
||
ENC28J60_CSL();
|
||
|
||
dat = op | (address & ADDR_MASK);
|
||
SPI1_ReadWrite(dat);
|
||
dat = SPI1_ReadWrite(0xFF);
|
||
// do dummy read if needed (for mac and mii, see datasheet page 29)
|
||
if(address & 0x80)
|
||
{
|
||
dat = SPI1_ReadWrite(0xFF);
|
||
}
|
||
// release CS
|
||
ENC28J60_CSH();
|
||
return dat;
|
||
}
|
||
|
||
void enc28j60WriteOp(unsigned char op, unsigned char address, unsigned char data)
|
||
{
|
||
unsigned char dat = 0;
|
||
|
||
ENC28J60_CSL();
|
||
// issue write command
|
||
dat = op | (address & ADDR_MASK);
|
||
SPI1_ReadWrite(dat);
|
||
// write data
|
||
dat = data;
|
||
SPI1_ReadWrite(dat);
|
||
ENC28J60_CSH();
|
||
}
|
||
|
||
void enc28j60ReadBuffer(unsigned int len, unsigned char* data)
|
||
{
|
||
ENC28J60_CSL();
|
||
// issue read command
|
||
SPI1_ReadWrite(ENC28J60_READ_BUF_MEM);
|
||
while(len)
|
||
{
|
||
len--;
|
||
// read data
|
||
*data = (unsigned char)SPI1_ReadWrite(0);
|
||
data++;
|
||
}
|
||
*data='\0';
|
||
ENC28J60_CSH();
|
||
}
|
||
|
||
void enc28j60WriteBuffer(unsigned int len, unsigned char* data)
|
||
{
|
||
ENC28J60_CSL();
|
||
// issue write command
|
||
SPI1_ReadWrite(ENC28J60_WRITE_BUF_MEM);
|
||
|
||
while(len)
|
||
{
|
||
len--;
|
||
SPI1_ReadWrite(*data);
|
||
data++;
|
||
}
|
||
ENC28J60_CSH();
|
||
}
|
||
|
||
void enc28j60SetBank(unsigned char address)
|
||
{
|
||
// set the bank (if needed)
|
||
if((address & BANK_MASK) != Enc28j60Bank)
|
||
{
|
||
// set the bank
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
|
||
Enc28j60Bank = (address & BANK_MASK);
|
||
}
|
||
}
|
||
|
||
unsigned char enc28j60Read(unsigned char address)
|
||
{
|
||
// set the bank
|
||
enc28j60SetBank(address);
|
||
// do the read
|
||
return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
|
||
}
|
||
|
||
void enc28j60Write(unsigned char address, unsigned char data)
|
||
{
|
||
// set the bank
|
||
enc28j60SetBank(address);
|
||
// do the write
|
||
enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
|
||
}
|
||
|
||
void enc28j60PhyWrite(unsigned char address, unsigned int data)
|
||
{
|
||
// set the PHY register address
|
||
enc28j60Write(MIREGADR, address);
|
||
// write the PHY data
|
||
enc28j60Write(MIWRL, data);
|
||
enc28j60Write(MIWRH, data>>8);
|
||
// wait until the PHY write completes
|
||
|
||
while(enc28j60Read(MISTAT) & MISTAT_BUSY)
|
||
{
|
||
//Del_10us(1);
|
||
__NOP();
|
||
__NOP();
|
||
__NOP();
|
||
__NOP();
|
||
__NOP();
|
||
}
|
||
}
|
||
|
||
void enc28j60clkout(unsigned char clk)
|
||
{
|
||
//setup clkout: 2 is 12.5MHz:
|
||
enc28j60Write(ECOCON, clk & 0x7);
|
||
}
|
||
|
||
u8 enc28j60Init(unsigned char* macaddr)
|
||
{
|
||
u16 retry = 0;
|
||
ENC28J60_CSH();
|
||
enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
|
||
while(!(enc28j60Read(ESTAT)&ESTAT_CLKRDY)&&retry<500)
|
||
{
|
||
retry++;
|
||
// delay_ms(1);
|
||
};
|
||
if(retry>=500)return 1;//ENC28J60<36><30>ʼ<EFBFBD><CABC>ʧ<EFBFBD><CAA7>
|
||
// Del_1ms(250);
|
||
// check CLKRDY bit to see if reset is complete
|
||
// The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
|
||
//while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
|
||
// do bank 0 stuff
|
||
// initialize receive buffer
|
||
// 16-bit transfers, must write low byte first
|
||
// set receive buffer start address <20><><EFBFBD>ý<EFBFBD><C3BD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ 8K<38>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||
NextPacketPtr = RXSTART_INIT;
|
||
// Rx start
|
||
//<2F><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>FIFO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>
|
||
//<2F>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ERXSTH:ERXSTL <20><>ERXNDH:ERXNDL <20><>
|
||
//Ϊָ<CEAA>룬<EFBFBD><EBA3AC><EFBFBD>建<EFBFBD><E5BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ洢<DAB4><E6B4A2><EFBFBD>е<EFBFBD>λ<EFBFBD>á<EFBFBD>
|
||
//ERXST<53><54>ERXNDָ<44><D6B8><EFBFBD><EFBFBD><EFBFBD>ֽھ<D6BD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD><CCAB><EFBFBD>ӿڽ<D3BF><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Щ<EFBFBD>ֽڱ<D6BD>˳<EFBFBD><CBB3>д<EFBFBD><D0B4>
|
||
//<2F><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ǵ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>ERXND ָ<><D6B8><EFBFBD>Ĵ洢<C4B4><E6B4A2>Ԫ
|
||
//<2F><><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>һ<EFBFBD>ֽ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>ERXST ָ<><D6B8>
|
||
//<2F>Ĵ洢<C4B4><E6B4A2>Ԫ<EFBFBD><D4AA> <20><><EFBFBD>˽<EFBFBD><CBBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>FIFO <20><><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
|
||
//Ԫ<><D4AA>
|
||
enc28j60Write(ERXSTL, RXSTART_INIT&0xFF); //
|
||
enc28j60Write(ERXSTH, RXSTART_INIT>>8);
|
||
// set receive pointer address
|
||
//ERXWRPTH:ERXWRPTL <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD>FIFO <20><>
|
||
//<2F><><EFBFBD>ĸ<EFBFBD>λ<EFBFBD><CEBB>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ֽڡ<D6BD> ָ<><D6B8><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>ģ<EFBFBD><C4A3>ڳ<EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>롣 ָ<><D6B8><EFBFBD><EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>FIFO <20><>ʣ<EFBFBD><CAA3><EFBFBD>ռ<EFBFBD><D5BC>Ĵ<EFBFBD>С 8K-1500<30><30>
|
||
enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
|
||
enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
|
||
// RX end
|
||
enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
|
||
enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
|
||
// TX start 1500
|
||
enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
|
||
enc28j60Write(ETXSTH, TXSTART_INIT>>8);
|
||
// TX end
|
||
enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);
|
||
enc28j60Write(ETXNDH, TXSTOP_INIT>>8);
|
||
// do bank 1 stuff, packet filter:
|
||
// For broadcast packets we allow only ARP packtets
|
||
// All other packets should be unicast only for our mac (MAADR)
|
||
//
|
||
// The pattern to match on is therefore
|
||
// Type ETH.DST
|
||
// ARP BROADCAST
|
||
// 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
|
||
// in binary these poitions are:11 0000 0011 1111
|
||
// This is hex 303F->EPMM0=0x3f,EPMM1=0x30
|
||
//<2F><><EFBFBD>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD>
|
||
//UCEN<45><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//<2F><>ANDOR = 1 ʱ<><CAB1>
|
||
//1 = Ŀ<><C4BF><EFBFBD><EFBFBD>ַ<EFBFBD>뱾<EFBFBD><EBB1BE>MAC <20><>ַ<EFBFBD><D6B7>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F><>ANDOR = 0 ʱ<><CAB1>
|
||
//1 = Ŀ<><C4BF><EFBFBD><EFBFBD>ַ<EFBFBD>뱾<EFBFBD><EBB1BE>MAC <20><>ַƥ<D6B7><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ᱻ<EFBFBD><E1B1BB><EFBFBD><EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
//CRCEN<45><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CRC У<><D0A3>ʹ<EFBFBD><CAB9>λ
|
||
//1 = <20><><EFBFBD><EFBFBD>CRC <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CRC <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||
|
||
//PMEN<45><4E><EFBFBD><EFBFBD>ʽƥ<CABD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//<2F><>ANDOR = 1 ʱ<><CAB1>
|
||
//1 = <20><><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>ʽƥ<CABD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2BDABB1><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F><>ANDOR = 0 ʱ<><CAB1>
|
||
//1 = <20><><EFBFBD>ϸ<EFBFBD>ʽƥ<CABD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
|
||
enc28j60Write(EPMM0, 0x3f);
|
||
enc28j60Write(EPMM1, 0x30);
|
||
enc28j60Write(EPMCSL, 0xf9);
|
||
enc28j60Write(EPMCSH, 0xf7);
|
||
// do bank 2 stuff
|
||
// enable MAC receive
|
||
//bit 0 MARXEN<45><4E>MAC <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//1 = <20><><EFBFBD><EFBFBD>MAC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
|
||
//bit 3 TXPAUS<55><53><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//1 = <20><><EFBFBD><EFBFBD>MAC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ˫<C8AB><CBAB>ģʽ<C4A3>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9>ͣ֡<CDA3><D6A1><EFBFBD><EFBFBD>
|
||
//bit 2 RXPAUS<55><53><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//1 = <20><><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>֡ʱ<D6A1><CAB1><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><><EFBFBD>Խ<EFBFBD><D4BD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>֡
|
||
enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
|
||
// bring MAC out of reset
|
||
//<2F><>MACON2 <20>е<EFBFBD>MARST λ<><CEBB><EFBFBD>㣬ʹMAC <20>˳<EFBFBD><CBB3><EFBFBD>λ״̬<D7B4><CCAC>
|
||
enc28j60Write(MACON2, 0x00);
|
||
// enable automatic padding to 60bytes and CRC operations
|
||
//bit 7-5 PADCFG2:PACDFG0<47><30><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CRC <20><><EFBFBD><EFBFBD>λ
|
||
//111 = <20><>0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>֡<EFBFBD><D6A1>64 <20>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC
|
||
//110 = <20><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
|
||
//101 = MAC <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8100h <20><><EFBFBD><EFBFBD><EFBFBD>ֶε<D6B6>VLAN Э<><D0AD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>䵽64 <20>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F><>VLAN ֡<><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>60 <20>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<D2AA><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC
|
||
//100 = <20><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
|
||
//011 = <20><>0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>֡<EFBFBD><D6A1>64 <20>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC
|
||
//010 = <20><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
|
||
//001 = <20><>0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>֡<EFBFBD><D6A1>60 <20>ֽڳ<D6BD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC
|
||
//000 = <20><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
|
||
//bit 4 TXCRCEN<45><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CRC ʹ<><CAB9>λ
|
||
//1 = <20><><EFBFBD><EFBFBD>PADCFG<46><47><EFBFBD>Σ<EFBFBD>MAC<41><43><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD>֡<EFBFBD><D6A1>ĩβ<CEB2><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC<52><43> <20><><EFBFBD><EFBFBD>PADCFG<46>涨Ҫ
|
||
//<><D7B7><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC<52><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뽫TXCRCEN <20><>1<EFBFBD><31>
|
||
//0 = MAC<41><43><EFBFBD><EFBFBD><EFBFBD><D7B7>CRC<52><43> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4 <20><><EFBFBD>ֽڣ<D6BD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>CRC <20><EFBFBD><F2B1A8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//bit 0 FULDPX<50><58>MAC ȫ˫<C8AB><CBAB>ʹ<EFBFBD><CAB9>λ
|
||
//1 = MAC<41><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ˫<C8AB><CBAB>ģʽ<C4A3>¡<EFBFBD> PHCON1.PDPXMD λ<><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>
|
||
//0 = MAC<41><43><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD>˫<EFBFBD><CBAB>ģʽ<C4A3>¡<EFBFBD> PHCON1.PDPXMD λ<><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㡣
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX);
|
||
// set inter-frame gap (non-back-to-back)
|
||
//<2F><><EFBFBD>÷DZ<C3B7><C7B1>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD>
|
||
//MAIPGL<47><4C> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʹ<EFBFBD><CAB9>12h <20><><EFBFBD≯üĴ<C3BC><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD>ʹ<EFBFBD>ð<EFBFBD>˫<EFBFBD><CBAB>ģʽ<C4A3><CABD>Ӧ<EFBFBD><D3A6><EFBFBD>̷DZ<CCB7><C7B1>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>ֽ<EFBFBD>MAIPGH<47><48> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʹ<EFBFBD><CAB9>0Ch
|
||
//<2F><><EFBFBD≯üĴ<C3BC><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
||
enc28j60Write(MAIPGL, 0x12);
|
||
enc28j60Write(MAIPGH, 0x0C);
|
||
// set inter-frame gap (back-to-back)
|
||
//<2F><><EFBFBD>ñ<EFBFBD><C3B1>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>MABBIPG<50><47><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
||
//ȫ˫<C8AB><CBAB>ģʽʱ<CABD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʹ<EFBFBD><CAB9>15h <20><><EFBFBD≯üĴ<C3BC>
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ð<EFBFBD>˫<EFBFBD><CBAB>ģʽʱ<CABD><CAB1>ʹ<EFBFBD><CAB9>12h <20><><EFBFBD>б<EFBFBD><D0B1>̡<EFBFBD>
|
||
enc28j60Write(MABBIPG, 0x15);
|
||
// Set the maximum packet size which the controller will accept
|
||
// Do not send packets longer than MAX_FRAMELEN:
|
||
// <20><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD> 1500
|
||
enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);
|
||
enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);
|
||
// do bank 3 stuff
|
||
// write MAC address
|
||
// NOTE: MAC address in ENC28J60 is byte-backward
|
||
enc28j60Write(MAADR5, macaddr[0]);
|
||
enc28j60Write(MAADR4, macaddr[1]);
|
||
enc28j60Write(MAADR3, macaddr[2]);
|
||
enc28j60Write(MAADR2, macaddr[3]);
|
||
enc28j60Write(MAADR1, macaddr[4]);
|
||
enc28j60Write(MAADR0, macaddr[5]);
|
||
//<2F><><EFBFBD><EFBFBD>PHYΪȫ˫<C8AB><CBAB> LEDBΪ<42><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
enc28j60PhyWrite(PHCON1, PHCON1_PDPXMD);
|
||
// no loopback of transmitted frames <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>
|
||
//HDLDIS<49><53>PHY <20><>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD>ֹλ
|
||
//<2F><>PHCON1.PDPXMD = 1 <20><>PHCON1.PLOOPBK = 1 ʱ<><CAB1>
|
||
//<2F><>λ<EFBFBD>ɱ<EFBFBD><C9B1><EFBFBD><EFBFBD>ԡ<EFBFBD>
|
||
//<2F><>PHCON1.PDPXMD = 0 <20><>PHCON1.PLOOPBK = 0 ʱ<><CAB1>
|
||
//1 = Ҫ<><D2AA><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>ݽ<EFBFBD>ͨ<EFBFBD><CDA8>˫<EFBFBD><CBAB><EFBFBD>߽ӿڷ<D3BF><DAB7><EFBFBD>
|
||
//0 = Ҫ<><D2AA><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>ݻỷ<DDBB>ص<EFBFBD>MAC <20><>ͨ<EFBFBD><CDA8>˫<EFBFBD><CBAB><EFBFBD>߽ӿڷ<D3BF><DAB7><EFBFBD>
|
||
enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);
|
||
// switch to bank 0
|
||
//ECON1 <20>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||
//<2F>Ĵ<EFBFBD><C4B4><EFBFBD>3-1 <20><>ʾΪECON1 <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD>
|
||
//ENC28J60 <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ܡ<EFBFBD> ECON1 <20>а<EFBFBD><D0B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ܡ<EFBFBD><DCA1><EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA <20><><EFBFBD>ƺʹ洢<CDB4><E6B4A2>ѡ<EFBFBD><D1A1>λ<EFBFBD><CEBB>
|
||
|
||
enc28j60SetBank(ECON1);
|
||
// enable interrutps
|
||
//EIE<49><45> <20><>̫<EFBFBD><CCAB><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||
//bit 7 INTIE<49><45> ȫ<><C8AB>INT <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>λ
|
||
//1 = <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>INT <20><><EFBFBD><EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>INT <20><><EFBFBD>ŵĻ<C4BB><EEB6AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>ձ<EFBFBD><D5B1><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><C6BD>
|
||
//bit 6 PKTIE<49><45> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>λ
|
||
//1 = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||
//0 = <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
|
||
// enable packet reception
|
||
//bit 2 RXEN<45><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>λ
|
||
//1 = ͨ<><CDA8><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>
|
||
//0 = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
|
||
|
||
if(enc28j60Read(MAADR5)== macaddr[0])
|
||
return 0;
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
// read the revision of the chip:
|
||
unsigned char enc28j60getrev(void)
|
||
{
|
||
//<2F><>EREVID <20><>Ҳ<EFBFBD>洢<EFBFBD>˰汾<CBB0><E6B1BE>Ϣ<EFBFBD><CFA2> EREVID <20><>һ<EFBFBD><D2BB>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD>
|
||
//<2F>ƼĴ<C6BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>5 λ<><CEBB>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><D8B6><EFBFBD>Ƭ
|
||
//<2F>İ汾<C4B0><E6B1BE>
|
||
return(enc28j60Read(EREVID));
|
||
}
|
||
|
||
void enc28j60PacketSend(unsigned int len, unsigned char* packet)
|
||
{
|
||
// Set the write pointer to start of transmit buffer area
|
||
enc28j60Write(EWRPTL, TXSTART_INIT&0xFF);
|
||
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
|
||
|
||
// Set the TXND pointer to correspond to the packet size given
|
||
enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF);
|
||
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
|
||
|
||
// write per-packet control byte (0x00 means use macon3 settings)
|
||
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
|
||
|
||
// copy the packet into the transmit buffer
|
||
enc28j60WriteBuffer(len, packet);
|
||
|
||
// send the contents of the transmit buffer onto the network
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
|
||
|
||
// Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
|
||
if( (enc28j60Read(EIR) & EIR_TXERIF) )
|
||
{
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
|
||
}
|
||
}
|
||
|
||
// Gets a packet from the network receive buffer, if one is available.
|
||
// The packet will by headed by an ethernet header.
|
||
// maxlen The maximum acceptable length of a retrieved packet.
|
||
// packet Pointer where packet data should be stored.
|
||
// Returns: Packet length in bytes if a packet was retrieved, zero otherwise.
|
||
unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet)
|
||
{
|
||
unsigned int rxstat;
|
||
unsigned int len;
|
||
|
||
// check if a packet has been received and buffered
|
||
//if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
|
||
// The above does not work. See Rev. B4 Silicon Errata point 6.
|
||
if( enc28j60Read(EPKTCNT) ==0 ) //<2F>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD><CCAB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
return(0);
|
||
}
|
||
|
||
// Set the read pointer to the start of the received packet <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||
enc28j60Write(ERDPTL, (NextPacketPtr));
|
||
enc28j60Write(ERDPTH, (NextPacketPtr)>>8);
|
||
|
||
// read the next packet pointer
|
||
NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
|
||
NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
|
||
|
||
// read the packet length (see datasheet page 43)<29><>ȡ<EFBFBD><C8A1><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
|
||
len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
|
||
len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
|
||
|
||
len-=4; //remove the CRC count
|
||
// read the receive status (see datasheet page 43)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||
rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
|
||
rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
|
||
// limit retrieve length
|
||
if (len>maxlen-1)
|
||
{
|
||
len=maxlen-1;
|
||
}
|
||
|
||
// 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;
|
||
}
|
||
else
|
||
{
|
||
// copy the packet from the receive buffer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>
|
||
enc28j60ReadBuffer(len, packet);
|
||
}
|
||
// Move the RX read pointer to the start of the next received packet
|
||
// This frees the memory we just read out
|
||
enc28j60Write(ERXRDPTL, (NextPacketPtr));
|
||
enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8);
|
||
|
||
// decrement the packet counter indicate we are done with this packet
|
||
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
|
||
return(len);
|
||
}
|
||
|
||
|
||
|