Files
SM-1000M/IAPV1.1/Driver/enc28j60/ENC28J60.C
2026-04-23 10:50:18 +08:00

409 lines
13 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}