Skip to content

Commit

Permalink
make hardwareStatus() and linkStatus() work without Erhernet.begin(mac)
Browse files Browse the repository at this point in the history
  • Loading branch information
JAndrassy committed Oct 1, 2020
1 parent b9203c7 commit 67cd5df
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 36 deletions.
3 changes: 3 additions & 0 deletions UIPEthernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,14 @@ int UIPEthernetClass::maintain(){

EthernetLinkStatus UIPEthernetClass::linkStatus()
{
Enc28J60Network::initSPI();
if (!Enc28J60Network::geterevid())
return Unknown;
return Enc28J60Network::linkStatus() ? LinkON : LinkOFF;
}

EthernetHardwareStatus UIPEthernetClass::hardwareStatus() {
Enc28J60Network::initSPI();
if (!Enc28J60Network::geterevid())
return EthernetNoHardware;
return EthernetENC28J60;
Expand Down Expand Up @@ -403,6 +405,7 @@ void UIPEthernetClass::netInit(const uint8_t* mac) {
#endif
periodic_timer = millis() + UIP_PERIODIC_TIMER;

Enc28J60Network::initSPI();
Enc28J60Network::init((uint8_t*)mac);
uip_seteth_addr(mac);

Expand Down
2 changes: 1 addition & 1 deletion hardware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The ENC8266 is powered by 3.3 V and can require 180 mA as top current draw while

### Nano Ethernet Shield

There are at least 3 versions of the Nano Ethernet shield in shops. Black version is by Robotdyn, red and blue version are from different manufacturers. All this shields use the same [schematics](https://www.open-electronics.org/low-cost-ethernet-shield-with-enc28j60/), but Robotdyn has a different PCB layout. The shields use logic gates (74HCT08) instead of a Tri-State Digital Buffer (74HC125) to convert the MISO line to 5 V . This creates problems. SPI device not selected by CS pin should release the MISO line by setting the output pin to HI-Z state. The enc28j60 of course does this, but the logic gate can't. It stays HIGH, blocking the bus. No other device can be used on SPI with this shield attached. (Many 5 V SD card adapters have the same problem with then level conversion on the MISO line.)
There are at least 3 versions of the Nano Ethernet shield in shops. Black version is by Robotdyn, red and blue version are from different manufacturers. All these shields use the same [schematics](https://www.open-electronics.org/low-cost-ethernet-shield-with-enc28j60/), but Robotdyn has a different PCB layout. The shields use logic gates (74HCT08) instead of a Tri-State Digital Buffer (74HC125) to convert the MISO line to 5 V . This creates problems. SPI device not selected by CS pin should release the MISO line by setting the output pin to HI-Z state. The enc28j60 of course does this, but the logic gate can't. It stays HIGH, blocking the bus. No other device can be used on SPI with this shield attached. (Many 5 V SD card adapters have the same problem with then level conversion on the MISO line.)

The new 3.3 V Nano boards could be damaged by this shield, while without the 5 V conversion the shield would be OK for a 3.3 V Nano. This applies to any 3.3 V MCU with this shield wired as module.

Expand Down
81 changes: 46 additions & 35 deletions utility/Enc28J60Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,22 @@ struct memblock Enc28J60Network::receivePkt;

bool Enc28J60Network::broadcast_enabled = false;

void Enc28J60Network::initSPI() {

if (erevid != 0)
return;

void Enc28J60Network::init(uint8_t* macaddr)
{
#if ACTLOGLEVEL>=LOG_DEBUG_V3
LogObject.uart_send_strln(F("Enc28J60Network::init(uint8_t* macaddr) DEBUG_V3:Function started"));
LogObject.uart_send_strln(F("Enc28J60Network::initSPI() DEBUG_V3:Function started"));
#endif
receivePkt.begin = 0;
receivePkt.size = 0;

unsigned int timeout = 15;
MemoryPool::init(); // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
// initialize I/O
// ss as output:
#if defined(ARDUINO)
pinMode(ENC28J60ControlCS, OUTPUT);
#endif
#if defined(__MBED__)
millis_start();
millis_start();
#endif
CSPASSIVE; // ss=0
//
Expand Down Expand Up @@ -192,6 +190,35 @@ void Enc28J60Network::init(uint8_t* macaddr)
SPSR |= (1<<SPI2X);
#endif


#if ACTLOGLEVEL>=LOG_DEBUG_V3
LogObject.uart_send_strln(F("ENC28J60::init DEBUG_V3:Before readReg(EREVID);"));
#endif
erevid=readReg(EREVID);
if (erevid==0xFF) {erevid=0;}
// microchip forgot to step the number on the silcon when they
// released the revision B7. 6 is now rev B7. We still have
// to see what they do when they release B8. At the moment
// there is no B8 out yet
//if (erevid > 5) ++erevid;
#if ACTLOGLEVEL>=LOG_INFO
LogObject.uart_send_str(F("ENC28J60::init INFO: Chip erevid="));
LogObject.uart_send_dec(erevid);
LogObject.uart_send_strln(F(" initialization completed."));
#endif
}

void Enc28J60Network::init(uint8_t* macaddr)
{
#if ACTLOGLEVEL>=LOG_DEBUG_V3
LogObject.uart_send_strln(F("Enc28J60Network::init(uint8_t* macaddr) DEBUG_V3:Function started"));
#endif
receivePkt.begin = 0;
receivePkt.size = 0;

unsigned int timeout = 15;
MemoryPool::init(); // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte

// perform system reset
writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
delay(2); // errata B7/2
Expand Down Expand Up @@ -302,22 +329,6 @@ void Enc28J60Network::init(uint8_t* macaddr)
//Configure leds
phyWrite(PHLCON,0x476);

#if ACTLOGLEVEL>=LOG_DEBUG_V3
LogObject.uart_send_strln(F("ENC28J60::init DEBUG_V3:Before readReg(EREVID);"));
#endif
erevid=readReg(EREVID);
if (erevid==0xFF) {erevid=0;}
// microchip forgot to step the number on the silcon when they
// released the revision B7. 6 is now rev B7. We still have
// to see what they do when they release B8. At the moment
// there is no B8 out yet
//if (erevid > 5) ++erevid;
#if ACTLOGLEVEL>=LOG_INFO
LogObject.uart_send_str(F("ENC28J60::init INFO: Chip erevid="));
LogObject.uart_send_dec(erevid);
LogObject.uart_send_strln(F(" initialization completed."));
#endif

// return Enc28J60Network::erevid;
}

Expand Down Expand Up @@ -462,7 +473,7 @@ Enc28J60Network::sendPacket(memhandle handle)
writeRegPair(ETXSTL, start);
// Set the TXND pointer to correspond to the packet size given
writeRegPair(ETXNDL, end);

bool success = false;
// See Rev. B7 Silicon Errata issues 12 and 13
for (uint8_t retry = 0; retry < TX_COLLISION_RETRY_COUNT; retry++)
Expand All @@ -471,7 +482,7 @@ Enc28J60Network::sendPacket(memhandle handle)
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
writeOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF | EIR_TXIF);

// send the contents of the transmit buffer onto the network
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);

Expand Down Expand Up @@ -505,7 +516,7 @@ Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len)
memaddress start = handle == UIP_RECEIVEBUFFERHANDLE && packet->begin + position > RXSTOP_INIT ? packet->begin + position-((RXSTOP_INIT + 1)-RXSTART_INIT) : packet->begin + position;

writeRegPair(ERDPTL, start);

if (len > packet->size - position)
len = packet->size - position;
return len;
Expand Down Expand Up @@ -661,7 +672,7 @@ uint8_t Enc28J60Network::readByte(uint16_t addr)
waitspi();
CSPASSIVE;
return (SPDR);
#endif
#endif
}

void Enc28J60Network::writeByte(uint16_t addr, uint8_t data)
Expand Down Expand Up @@ -873,7 +884,7 @@ Enc28J60Network::readBuffer(uint16_t len, uint8_t* data)
#endif
CSACTIVE;
// issue read command
#if ENC28J60_USE_SPILIB
#if ENC28J60_USE_SPILIB
#if defined(ARDUINO)
SPI.transfer(ENC28J60_READ_BUF_MEM);
#endif
Expand All @@ -888,7 +899,7 @@ Enc28J60Network::readBuffer(uint16_t len, uint8_t* data)
{
len--;
// read data
#if ENC28J60_USE_SPILIB
#if ENC28J60_USE_SPILIB
#if defined(ARDUINO)
*data = SPI.transfer(0x00);
#endif
Expand All @@ -899,7 +910,7 @@ Enc28J60Network::readBuffer(uint16_t len, uint8_t* data)
SPDR = 0x00;
waitspi();
*data = SPDR;
#endif
#endif
data++;
}
//*data='\0';
Expand All @@ -914,7 +925,7 @@ Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data)
#endif
CSACTIVE;
// issue write command
#if ENC28J60_USE_SPILIB
#if ENC28J60_USE_SPILIB
#if defined(ARDUINO)
SPI.transfer(ENC28J60_WRITE_BUF_MEM);
#endif
Expand All @@ -929,7 +940,7 @@ Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data)
{
len--;
// write data
#if ENC28J60_USE_SPILIB
#if ENC28J60_USE_SPILIB
#if defined(ARDUINO)
SPI.transfer(*data);
#endif
Expand Down Expand Up @@ -1115,7 +1126,7 @@ Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t
}
if(i == len)
{
#if ENC28J60_USE_SPILIB
#if ENC28J60_USE_SPILIB
#if defined(ARDUINO)
t = (SPI.transfer(0x00) << 8) + 0;
#endif
Expand All @@ -1126,7 +1137,7 @@ Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t
SPDR = 0x00;
waitspi();
t = (SPDR << 8) + 0;
#endif
#endif
sum += t;
if(sum < t)
{
Expand Down
1 change: 1 addition & 0 deletions utility/Enc28J60Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ class Enc28J60Network : public MemoryPool
uint16_t PhyStatus(void);
static bool linkStatus(void);

static void initSPI();
static void init(uint8_t* macaddr);
static memhandle receivePacket(void);
static void freePacket(void);
Expand Down

0 comments on commit 67cd5df

Please sign in to comment.