ENC28J60 initializing and reading firmware version, but not receiving packets on T3.6

Status
Not open for further replies.

Mike Chambers

Well-known member
I've got an ENC28J60 hooked up to my Teensy 3.6. It initializes properly, but even after setting promiscuous mode, it never receives any packets. I'm using the low-level raw packet functions from the EtherCard library. This same code worked fine when I tried it on a Mega 2560. Does anybody have any tips for getting this working correctly on the Teensy?

I need raw packet access because it's going to be used to emulate an ethernet adapter in a Teensy-based 8086 PC emulator. I will be making a post about it soon in the project submission section. :D

It's already working other than the ethernet thing. It's not a must-have, but it would be really cool to be able to IRC from DOS with this.

For anybody interested in this sort of project: https://i.imgur.com/4dpErbv.jpg
 
The forum rule requests that you provide a working sketch (use CODE tags #) that demonstrates the problem. How have you wired up the ENC28J60 to the T3.6? Which version of IDE are you using, and do you have a link to which EtherCard library you are using? You can search this forum for ENC28J60 and see others have had success.

You might consider the UIPEthernet lib.

Most teensy Ethernet support is for wiznet adapter, wiz850io
 
Sorry about not including code. I've just made a simple sketch to demonstrate the problem.

The firmware value returned is 7 for me. I don't think the wiznet adapter is an option for me, because the last time I looked into it (some years ago), it didn't appear to give access to raw packet send/receive. Only a TCP/IP stack.

Code:
#include <SPI.h>
#include <enc28j60.h>

#define NET_PIN 29

byte ENC28J60::buffer[2000];
//uint8_t net_mac[6] = { 0x90, 0xAD, 0xBE, 0xEF, 0x13, 0x37 };
uint8_t net_mac[6] = { 0x2C, 0xFD, 0x13, 0x37, 0x13, 0x37 };

void setup() {
  uint8_t ret;
  Serial.begin(9600);
  while (!Serial) { }
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  ret = ENC28J60::initialize(2000, net_mac, NET_PIN);
  Serial.print("net init result = ");
  Serial.println(ret);
  ENC28J60::enablePromiscuous();
}

void loop() {
  uint16_t len, i;
  len = ENC28J60::packetReceive();
  if (len > 0) {
    Serial.print("Received "); Serial.print(len); Serial.println(" byte pkt:");
    for (i=0; i<len; i++) {
      Serial.print(ENC28J60::buffer[i], HEX);
      Serial.write(' ');
    }
    Serial.println("");
    Serial.println("");
  }
}
 
Hmm, so I tried the UIPEthernet library. Compiled one of the examples. That doesn't work, either.

Just to make sure my board hasn't gone bad since it was tested on my Arduino, I hooked it back up to an Uno and ran my test sketch provided above. It worked just fine, here's the output:

Code:
net init result = 7
Received 233 byte pkt:
FF FF FF FF FF FF 0 50 56 A1 6F CE 8 0 45 0 0 DB 0 0 40 0 40 11 B5 5F C0 A8 1 63 C0 A8 1 FF 0 8A 0 8A 0 C7 FB EA 11 A 3F 78 C0 A8 1 63 0 8A 0 B1 0 0 20 46 41 45 42 46 47 45 4A 45 4D 45 4A 45 50 45 4F 43 41 43 41 43 41 43 41 43 41 43 41 43 41 41 41 0 20 46 48 45 50 46 43 45 4C 45 48 46 43 45 50 46 46 46 41 43 41 43 41 43 41 43 41 43 41 43 41 42 4F 0 FF 53 4D 42 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 0 56 0 3 0 1 0 1 0 2 0 28 0 5C 4D 41 49 4C 53 4C 4F 54 5C 42 52 4F 57 53 45 0 8 1 7 F 1 14 E0 31 36 25 0 0 0 0 50 41 56 49 4C 49 4F 4E 0

And it just continues after that, happily receiving packets until I kill the power. The UIPEthernet example sketches worked fine on the Arduino as well.

The unusual thing about this, to me, is that the board DOES appear to initialize on the Teensy 3.6. It reports the same firmware version (7) that it does on the Arduino. It's clearly talking to the ENC28J60. It just never receives any packets.
 
I had to remove SPI.begin() to get your sketch to work on T3.2@96mhz. and if you really want to change SPI clock, SPI.setClockDivider() needs to follow ENC28J60::initialize(). HOWEVER, sketch didn't work on T3.6@180mhz, if i built T3.6@96mhz, sketch worked. Also worked @120mhz. For 180 mhz, it may be necessary to add some delays to library after pulling SS LOW and before pulling SS HIGH.

EDIT: Ok i modified lib's enc28j60.cpp
Code:
static void enableChip () {
    cli();
    digitalWrite(selectPin, LOW);
    delayMicroseconds(100);
}

static void disableChip () {
    delayMicroseconds(100);
    digitalWrite(selectPin, HIGH);
    sei();
}
And your sketch works on T3.6@180mhz

I am using IDE 1.8.5/1.42 with lib https://github.com/jcw/ethercard

FYI, I think the wiznet command set will support raw Ether packets, but most high-level libs don't provide raw Ether interface (raw IP is available). Here is raw Ether example for old w5100 chip.
https://github.com/njh/W5100MacRaw
 
Last edited:
Thanks, yeah that makes sense. I'm actually running at 240 mhz. (Necessary for this project)

I did try it at 96 MHz, but did not remove SPI.begin(). I know the enc28j60 library also initializes the SPI bus itself, but in my emulator sketch, I am initing the SPI bus for some other peripherals before I call it, so I wanted to leave that there.

I'll give this a try when I get home tonight. The 100 us delays will also hurt performance a lot if called frequently, I will see if I can work something out with a timer interrupt to handle that so I can keep executing other code during the delay.
 
The 100 us delays will also hurt performance a lot if called frequently, I will see if I can work something out with a timer interrupt to handle that so I can keep executing other code during the delay.

I just picked 100 us delay at random. You can experiment to see what works.

Also the ethercard lib uses AVR SPI hardware registers. Paul's teensy core emulates many of the AVR registers, but sometimes that emulation may not be sufficient. To better manage multiple SPI devices the latest SPI library uses
SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE0));
 
Last edited:
Since 240 / 96 = 2.5, I'll just try throwing 3 or 4 NOPs in there and seeing what it does first.

I noticed that about the AVR SPI reigsters as well. One of my troubleshooting steps was replacing all of those AVR-specific lines of code with equivalent calls to the standard SPI library, but it didn't help.

EDIT: After a cursory Google search, it appears that due to how the ARM Cortex pipeline works, this may not have the desired effect. I can just try putting some other short nonsense code in there that doesn't do anything useful.
 
I'm still having no luck with this, I need to investigate some more. Thanks for the link about the W5100 and raw Ethernet frames! Unfortunately, it still is not suitable because it cannot be placed into promiscuous mode like the ENC28J60 can.

If I can't figure this out soon, I may just resort to writing a PC program to transfer Ethernet packets back and forth via the serial USB connection. Easy to do, but I'd rather see this thing have a dedicated Ethernet adapter so that it doesn't have to be tethered.
 
Wiznet can receive broadcast/multicast -- switches and routers won't pass other packets to your device if MAC address doesn't match. I guess if your ENC28J60 is directly attached to your PC ether interface, promiscuous would be helpful. All i was seeing on my test of your sketch was just muliticast and broadcast traffic.
 
Yes, I know how switches work. Broadcast/multicast and packets directed at its own MAC are what it needs. The Teensy will be running (via emulation) MS-DOS and a DOS-based packet driver, so it just needs all the packets that a real DOS machine with a packet driver would receive when plugged into a switch.

I hooked up an old W5100 Arduino shield I had and did not see any broadcast frames, but it's very very possible that the shield is damaged somehow. It's been sitting in a drawer unprotected for years. I'll try it on an AVR Arduino tonight and see if it acts any differently. If not, I'll just get a new one.
 
I hooked up an old W5100 Arduino shield I had and did not see any broadcast frames, but it's very very possible that the shield is damaged somehow. It's been sitting in a drawer unprotected for years. I'll try it on an AVR Arduino tonight and see if it acts any differently. If not, I'll just get a new one.

I should qualify that I have successfully received only UDP broadcasts to listening UDP socket on wiznet, and have used multicast with wiznet.

Besides IPRAW, wiznet low level commands also support MACRAW, and there is a setting to disable MAC filtering (MF bit in socket mode register).
 
I've just made a simple sketch to demonstrate the problem.
...
Code:
#include <SPI.h>
#include <enc28j60.h>

Mike, can you confirm where I should download the library for enc28j60.h, to run your program?

Is it the same ethercard lib, from Nicholas Humfrey "njh", which Manitou is using?
 
Hi Paul! Yes, that's the one, from here: https://github.com/njh/EtherCard

I've been just using packet forwarding from Windows through the USB serial interface, which has been working well. I appreciate your efforts. If this can be solved, it would be a nice plus for the project, but certainly not a necessity so please don't spend too much of your time on it.
 
Status
Not open for further replies.
Back
Top