1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

804 lines
20 KiB

/*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */
//*****************************************************************************
//
// File Name : 'enc28j60.c'
// Title : Microchip ENC28J60 Ethernet Interface Driver
// Author : Pascal Stang (c)2005
// Created : 9/22/2005
// Revised : 9/22/2005
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This driver provides initialization and transmit/receive
// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
// chip, using an SPI interface to the host processor.
//
//*****************************************************************************
#include "wiring.h"
#include <avr/pgmspace.h>
#include "avr/io.h"
#include "avrlibdefs.h"
#include "avrlibtypes.h"
#include "HardwareSerial.h"
#include "programStrings.h"
// include configuration
#include "nic.h"
#include "net.h"
#include "enc28j60conf.h"
#include "enc28j60.h"
#ifdef SPDR0
#define SPDR SPDR0
#define SPCR SPCR0
#define SPSR SPSR0
#define SPIF SPIF0
#define MSTR MSTR0
#define CPOL CPOL0
#define DORD DORD0
#define SPR0 SPR00
#define SPR1 SPR01
#define SPI2X SPI2X0
#define SPE SPE0
#endif
u08 Enc28j60Bank;
u16 NextPacketPtr;
char nicInit(void)
{
return enc28j60Init();
}
void nicSend(unsigned int len, unsigned char* packet)
{
enc28j60PacketSend(len, packet);
}
unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
{
return enc28j60PacketReceive(maxlen, packet);
}
void nicGetMacAddress(uint8_t* macaddr)
{
// read MAC address registers
// NOTE: MAC address in ENC28J60 is byte-backward
*macaddr++ = enc28j60Read(MAADR5);
*macaddr++ = enc28j60Read(MAADR4);
*macaddr++ = enc28j60Read(MAADR3);
*macaddr++ = enc28j60Read(MAADR2);
*macaddr++ = enc28j60Read(MAADR1);
*macaddr++ = enc28j60Read(MAADR0);
}
void nicSetMacAddress(uint8_t* macaddr)
{
// write MAC address
// NOTE: MAC address in ENC28J60 is byte-backward
enc28j60Write(MAADR5, *macaddr++);
enc28j60Write(MAADR4, *macaddr++);
enc28j60Write(MAADR3, *macaddr++);
enc28j60Write(MAADR2, *macaddr++);
enc28j60Write(MAADR1, *macaddr++);
enc28j60Write(MAADR0, *macaddr++);
}
#if defined(NET_DEBUG) || defined(NIC_DEBUG)
void nicRegDump(void)
{
enc28j60RegDump();
}
#endif
void nicHardReset(void)
{
#ifndef ENC28J60_HARD_RESET_DISABLED
enc28j60hardReset();
#endif
}
void nicSoftReset(void)
{
enc28j60softReset();
}
void nicReboot(void)
{
enc28j60Reboot();
}
uint16_t nicGetChecksum(uint8_t* packet, uint16_t len)
{
#ifdef ENC28J60_CHECKSUM_ENABLED
enc28j60getChecksum(packet, len);
#else
return 0x0000;
#endif
}
void enc28j60Reboot(void)
{
#ifndef ENC28J60_HARD_RESET_DISABLED
enc28j60hardReset();
#else
delayMicroseconds(10);
#endif
enc28j60softReset();
}
void enc28j60softReset(void)
{
// perform system reset
enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
delayMicroseconds(50);
// check CLKRDY bit to see if reset is complete
//while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
// Errata workaround #1, CLKRDY check is unreliable, delay 1 mS instead
delay(1);
}
#ifndef ENC28J60_HARD_RESET_DISABLED
void enc28j60hardReset(void)
{
// HW reset
sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_HRESET);
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_HRESET); // Down
delayMicroseconds(10);
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_HRESET); // Up
delay(1);
}
#endif
uint8_t enc28j60ReadOp(uint8_t op, uint8_t address)
{
uint8_t data;
// assert CS
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
// issue read command
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
// read data
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
// do dummy read if needed
if(address & 0x80)
{
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
}
data = SPDR;
// release CS
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
return data;
}
void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data)
{
// assert CS
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
// issue write command
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
// write data
SPDR = data;
while(!(SPSR & (1<<SPIF)));
// release CS
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
}
void enc28j60ReadBuffer(uint16_t len, uint8_t* data)
{
// assert CS
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
// issue read command
SPDR = ENC28J60_READ_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
// read data
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
*data++ = SPDR;
}
// release CS
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
}
uint16_t enc28j60getChecksum(uint8_t* packet, uint16_t len)
//void enc28j60PacketSend(uint16_t len, uint8_t* packet)
{
// Errata workaround #10 Transmit Logic
if (enc28j60Read(EIR) & EIR_TXERIF)
{
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
}
// Set the write pointer to start of transmit buffer area
enc28j60Write(EWRPTL, TXSTART_INIT);
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
// Set the TXND pointer to correspond to the packet size given
enc28j60Write(ETXNDL, (TXSTART_INIT+len));
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
// write per-packet control byte
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
// copy the packet into the transmit buffer
enc28j60WriteBuffer(len, packet);
// return the calculated checksum
return enc28j60doHardwareChecksum(len);
}
uint16_t enc28j60doHardwareChecksum(uint16_t len)
{
// Set EDMASTL to the beggining of the used memory
enc28j60Write(EDMASTL, TXSTART_INIT);
enc28j60Write(EDMASTH, TXSTART_INIT>>8);
// Set EDMAND to the end of the memory used
enc28j60Write(EDMANDL, (TXSTART_INIT+len));
enc28j60Write(EDMANDH, (TXSTART_INIT+len)>>8);
// Set EDMADST to the beggining of the DMA buffer
enc28j60Write(EDMADSTL, TXSTART_INIT);
enc28j60Write(EDMADSTH, TXSTART_INIT>>8);
// Enable DMA copy mode
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the DMA copy to complete
while(!(enc28j60Read(EIR) & EIR_DMAIF));
// Start the checksum calculation
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the checksum calculation to complete
while(!(enc28j60Read(ECON1) & ~ECON1_DMAST && enc28j60Read(EIR) & EIR_DMAIF));
// Read back and return the calculated checksum
return (uint16_t)(enc28j60Read(EDMACSL) | (uint16_t)enc28j60Read(EDMACSH)<<8);
}
void enc28j60WriteBuffer(uint16_t len, uint8_t* data)
{
// assert CS
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
// issue write command
SPDR = ENC28J60_WRITE_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
// write data
SPDR = *data++;
while(!(SPSR & (1<<SPIF)));
}
// release CS
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
}
void enc28j60SetBank(uint8_t 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);
}
}
uint8_t enc28j60Read(uint8_t address)
{
// set the bank
enc28j60SetBank(address);
// do the read
return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
}
void enc28j60Write(uint8_t address, uint8_t data)
{
// set the bank
enc28j60SetBank(address);
// do the write
enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
}
uint16_t enc28j60PhyRead(uint8_t address)
{
uint16_t data;
// Set the right address and start the register read operation
enc28j60Write(MIREGADR, address);
enc28j60Write(MICMD, MICMD_MIIRD);
// wait until the PHY read completes
while(enc28j60Read(MISTAT) & MISTAT_BUSY);
// quit reading
enc28j60Write(MICMD, 0x00);
// get data value
data = enc28j60Read(MIRDH);
data <<= 8;
data |= enc28j60Read(MIRDL);
// return the data
return data;
}
void enc28j60PhyWrite(uint8_t address, uint16_t 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);
}
char enc28j60Init(void)
{
/**
* Enable ENC28J560 Control ports
**/
// Enable CS and pull it high as CS is inverted
sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS); // CS as output
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS); // CS high
// Enable Hard reset and pull it high as RESET is inverted
#ifndef ENC28J60_HARD_RESET_DISABLED
sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_HRESET); // HR as output
cbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_HRESET); // HR low
#endif
/**
* setup SPI I/O pins
**/
sbi(ENC28J60_CONTROL_DDR, ENC28J60_SPI_SCK); // set SCK as output
cbi(ENC28J60_CONTROL_PORT, ENC28J60_SPI_SCK); // set SCK lo
sbi(ENC28J60_CONTROL_DDR, ENC28J60_SPI_MOSI); // set MOSI as output
cbi(ENC28J60_CONTROL_DDR, ENC28J60_SPI_MISO); // set MISO as input
sbi(ENC28J60_CONTROL_PORT, ENC28J60_SPI_SS); // SS must be output for Master mode to work
// master mode
sbi(SPCR, MSTR);
// select clock phase positive-going in middle of data
cbi(SPCR, CPOL);
// Data order MSB first
cbi(SPCR,DORD);
// switch to f/4 2X = f/2 bitrate
cbi(SPCR, SPR0);
cbi(SPCR, SPR1);
sbi(SPSR, SPI2X);
// enable SPI
sbi(SPCR, SPE);
delay(1);
#ifdef DEBUG_ENC_INIT
SPrintln("SPI Enabled");
#endif
// Reboot the ENC28J60
enc28j60Reboot();
#ifdef DEBUG_ENC_INIT
SPrintln("PHY reboot done");
#endif
#ifdef ENC28J60_LAMPS_MODE
#ifdef DEBUG_ENC_INIT
SPrintln("Custom lamps");
#endif
enc28j60PhyWrite(PHLCON, ENC28J60_LAMPS_MODE);
#else
// Errata #9 correction
if (enc28j60Read(MACON3) & MACON3_FULDPX)
{
#ifdef DEBUG_ENC_INIT
SPrintln("Full duplex lamps");
#endif
enc28j60PhyWrite(PHLCON, PHLCON_DEFAULT);
} else {
#ifdef DEBUG_ENC_INIT
SPrintln("Half duplex lamps");
#endif
enc28j60PhyWrite(PHLCON, PHLCON_DEFAULT_HD);
}
#endif
#ifdef DEBUG_ENC_INIT
SPrintln("Lamps set");
#endif
// do bank 0 stuff
// initialize receive buffer
// 16-bit transfers, must write low byte first
// set receive buffer start address
NextPacketPtr = RXSTART_INIT;
enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
enc28j60Write(ERXSTH, RXSTART_INIT>>8);
// set receive pointer address
enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
// set receive buffer end
// ERXND defaults to 0x1FFF (end of ram)
enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
// set transmit buffer start
// ETXST defaults to 0x0000 (beginnging of ram)
enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
enc28j60Write(ETXSTH, TXSTART_INIT>>8);
// Needs register implementation
#ifdef ENC28J60_PACKET_FILTER_ENABLED
// 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
//enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_PMEN);
enc28j60Write(EPMM0, 0x3f);
enc28j60Write(EPMM1, 0x30);
enc28j60Write(EPMCSL, 0xf9);
enc28j60Write(EPMCSH, 0xf7);
#endif
// do bank 2 stuff
// enable MAC receive
enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
// bring MAC out of reset
enc28j60Write(MACON2, 0x00);
// enable automatic padding and CRC operations
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
// enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
// set inter-frame gap (non-back-to-back)
enc28j60Write(MAIPGL, 0x12);
enc28j60Write(MAIPGH, 0x0C);
// set inter-frame gap (back-to-back)
enc28j60Write(MABBIPG, 0x12);
// Set the maximum packet size which the controller will accept
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, ENC28J60_MAC0);
enc28j60Write(MAADR4, ENC28J60_MAC1);
enc28j60Write(MAADR3, ENC28J60_MAC2);
enc28j60Write(MAADR2, ENC28J60_MAC3);
enc28j60Write(MAADR1, ENC28J60_MAC4);
enc28j60Write(MAADR0, ENC28J60_MAC5);
// no loopback of transmitted frames
enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);
// switch to bank 0
enc28j60SetBank(ECON1);
// enable interrutps
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
// enable packet reception
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
#ifdef DEBUG_ENC_INIT
SPrintln("Banks robbed");
#endif
/*
enc28j60PhyWrite(PHLCON, 0x0AA2);
// setup duplex ----------------------
// Disable receive logic and abort any packets currently being transmitted
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN);
{
uint16_t temp;
// Set the PHY to the proper duplex mode
temp = enc28j60PhyRead(PHCON1);
temp &= ~PHCON1_PDPXMD;
enc28j60PhyWrite(PHCON1, temp);
// Set the MAC to the proper duplex mode
temp = enc28j60Read(MACON3);
temp &= ~MACON3_FULDPX;
enc28j60Write(MACON3, temp);
}
// Set the back-to-back inter-packet gap time to IEEE specified
// requirements. The meaning of the MABBIPG value changes with the duplex
// state, so it must be updated in this function.
// In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex
//enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12);
// Reenable receive logic
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
// setup duplex ----------------------
*/
return 0;
}
#define ETHERNET_MIN_PACKET_LENGTH 0x3C
#define ETHERNET_HEADER_LENGTH 0x0E
#define IP_TCP_HEADER_LENGTH 40
#define TOTAL_HEADER_LENGTH (IP_TCP_HEADER_LENGTH+ETHERNET_HEADER_LENGTH)
void enc28j60PacketSend(uint16_t len, uint8_t* packet)
{
/*
// dump packet
int i,j;
for (i=0;i<len;i+=16)
{
printf("%04x ",i);
for (j=0;j<16;j++)
printf("%02x ",(i+j) < len ? packet[i+j] : 0);
printf(" ");
for (j=0;j<16;j++)
printf("%c", (i+j) < len ? isprint(packet[i+j]) ? packet[i+j] : '.' : '.');
printf("\n");
}
*/
// Errata workaround #10 Transmit Logic
if (enc28j60Read(EIR) & EIR_TXERIF)
{
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
}
// Set the write pointer to start of transmit buffer area
enc28j60Write(EWRPTL, TXSTART_INIT);
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
// Set the TXND pointer to correspond to the packet size given
enc28j60Write(ETXNDL, (TXSTART_INIT+len));
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
// write per-packet control byte
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
// TODO, fix this up
/*
if( uip_len <= TOTAL_HEADER_LENGTH )
{
// copy the packet into the transmit buffer
enc28j60WriteBuffer(len, packet);
}
else
{
len -= TOTAL_HEADER_LENGTH;
enc28j60WriteBuffer(TOTAL_HEADER_LENGTH, packet);
enc28j60WriteBuffer(len, (unsigned char *)uip_appdata);
}
*/
// 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);
// From errata Rev B.4
// if( (enc28j60Read(EIR) & EIR_TXERIF) ){
// enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
// }
}
#ifndef enc28j60ReadNextPtr
#define enc28j60ReadNextPtr(ptr) do { ptr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); \
ptr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; \
} while(0)
#endif
uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet)
{
uint16_t rxstat;
uint16_t len;
// check if a packet has been received and buffered
if( !(enc28j60Read(EIR) & EIR_PKTIF) )
{
// Errata workaround #4, PKTIF is not reliable
// double check by looking at EPKTCNT
if (enc28j60Read(EPKTCNT) == 0)
return 0;
}
// Set the read pointer to the start of the received packet
enc28j60Write(ERDPTL, (NextPacketPtr));
enc28j60Write(ERDPTH, (NextPacketPtr)>>8);
// read the next packet pointer
enc28j60ReadNextPtr(NextPacketPtr);
// read the packet length
enc28j60ReadNextPtr(len);
// read the receive status
enc28j60ReadNextPtr(rxstat);
// limit retrieve length
// (we reduce the MAC-reported length by 4 to remove the CRC)
len = MIN(len, maxlen);
// copy the packet from the receive buffer
enc28j60ReadBuffer(len, packet);
// Move the RX read pointer to the start of the next received packet
// This frees the memory we just read out
// Errata workaround #11. Make sure ERXRDPT is odd
//
{
uint16_t rs,re;
rs = enc28j60Read(ERXSTH);
rs <<= 8;
rs |= enc28j60Read(ERXSTL);
re = enc28j60Read(ERXNDH);
re <<= 8;
re |= enc28j60Read(ERXNDL);
if (NextPacketPtr - 1 < rs || NextPacketPtr - 1 > re)
{
enc28j60Write(ERXRDPTL, (re));
enc28j60Write(ERXRDPTH, (re)>>8);
}
else
{
enc28j60Write(ERXRDPTL, (NextPacketPtr-1));
enc28j60Write(ERXRDPTH, (NextPacketPtr-1)>>8);
}
}
// decrement the packet counter indicate we are done with this packet
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
return len;
}
void enc28j60ReceiveOverflowRecover(void)
{
// receive buffer overflow handling procedure
// recovery completed
}
#if defined(NET_DEBUG) || defined(NIC_DEBUG)
#define SPrint_D(str) SPrint(str); delayMicroseconds(100);
void enc28j60RegDump(void)
{
// unsigned char macaddr[6];
// result = ax88796Read(TR);
// SPrint("Media State: ");
// if(!(result & AUTOD))
// SPrint("Autonegotiation\r\n");
// else if(result & RST_B)
// SPrint("PHY in Reset \r\n");
// else if(!(result & RST_10B))
// SPrint("10BASE-T \r\n");
// else if(!(result & RST_TXB))
// SPrint("100BASE-T \r\n");
SPrint_D("RevID: ");
Serial.println(enc28j60Read(EREVID), HEX);
SPrint_D("Cntrl: ECON1 ECON2 ESTAT EIR EIE\r\n");
SPrint_D(" ");
Serial.print(enc28j60Read(ECON1), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ECON2), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ESTAT), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(EIR), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(EIE), HEX);
Serial.println();
SPrint_D("MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address\r\n");
SPrint_D(" ");
Serial.print(enc28j60Read(MACON1), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MACON2), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MACON3), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MACON4), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MAADR5), HEX);
Serial.print(enc28j60Read(MAADR4), HEX);
Serial.print(enc28j60Read(MAADR3), HEX);
Serial.print(enc28j60Read(MAADR2), HEX);
Serial.print(enc28j60Read(MAADR1), HEX);
Serial.print(enc28j60Read(MAADR0), HEX);
Serial.println();
SPrint_D("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n");
SPrint_D(" ");
Serial.print(enc28j60Read(ERXSTH), HEX);
Serial.print(enc28j60Read(ERXSTL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ERXNDH), HEX);
Serial.print(enc28j60Read(ERXNDL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ERXWRPTH), HEX);
Serial.print(enc28j60Read(ERXWRPTL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ERXRDPTH), HEX);
Serial.print(enc28j60Read(ERXRDPTL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ERXFCON), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(EPKTCNT), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MAMXFLH), HEX);
Serial.print(enc28j60Read(MAMXFLL), HEX);
Serial.println();
SPrint_D("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\r\n");
SPrint_D(" ");
Serial.print(enc28j60Read(ETXSTH), HEX);
Serial.print(enc28j60Read(ETXSTL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(ETXNDH), HEX);
Serial.print(enc28j60Read(ETXNDL), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MACLCON1), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MACLCON2), HEX);
SPrint_D(" ");
Serial.print(enc28j60Read(MAPHSUP), HEX);
Serial.println();
SPrint_D("PHLCON: 00");
Serial.println((long int)(enc28j60PhyRead(PHLCON)), BIN);
delay(1);
}
#endif