Just over a year ago I started work on adding support for the enc28j60 ethernet chip – as an alternative for the enc424j600.
Since Digilent stopped selling the PMODNIC100, boards with the enc424j600 became somewhat difficult to find – not impossible maybe, and also the bigger enc624j600 version can also be used with the older XU core. But the major vendors mostly don’t carry the alternatives for the PMODNIC100, and for some people the only option was to buy directly from a producer, with shipping costs etc spoiling the fun. So the most logical thing to do was to add support for enc28j60 – essentially the predecessor of, the older variant of the enc424j600, and widely available from many sources (even though Digilent also no longer sells the PMODNIC).
The XU/DEUNA needed some attention anyway – after adding the esp32-based wireless network backend to it, the configuration of which backend should be included was a bit confusing. And I already had a couple enc28j60 in my parts box – one that was shipped instead of a PMODNIC100 a long time ago, and another that came as a freebie with another order. So I briefly read the manual, thought it was very similar to the enc424 – basically, just copy that and make some minor changes, how hard could it be.
Well, it took me about a year, that’s how hard. Not that I worked on it all that time, far from it. But it’s still one of the most aggravating chips I’ve ever tried to interface. The worst probably was that the interface is very finicky – and the control registers have different requirements for timing; what works for buffer memory or a regular control register won’t work for a mac or phy register. The documentation doesn’t help either, with the errata sheet throwing lots of unhelpful clues – or the data sheet itself that presents the information in such a confusing way that I needed three or more copies each open on a different page.
Then of course it’s only 10Mbps – which brings us back to the time when autonegotiation for half or full duplex was not a given, and just about everything that’s needed to handle collisions needs to be set. And neither does it have a burnt-in MAC address. That made things somewhat difficult because it took a very long time for me to figure out the correct timing to set the MAC- and PHY related registers – but I could get around that by setting the chip to receive all frames promiscuously and filtering for ‘my’ MAC address in software.
It kind of worked – I could receive frames sort-of ok, and send them out too. Except there was one really weird problem that almost drove me crazy: the chip would keep sending out frames with a destination address of 0x’46’:0x’37’ followed by 4 bytes with the destination IP in them. At first I suspected that the bus masters in my XU design were somehow corrupting data, but I couldn’t find why or how, and it took a while to figure out how to instrument the hardware to find out – but when I did, it pointed to an issue in 2.11bsd. Of which we now know is caused by an unforeseen effect of patch #490.
Soon after I also found the issues with the interface timing for updating the MAC registers in the chip, and everything now works as expected – in fact, besides these issues it seems to work remarkably stable. In the test setup I’m now working with I’m consistently getting 180KBytes/s throughput on a long FTP transfer, telnetting feels snappy, and flood pings run almost without packet loss.
There’s some work left to do – more testing, some trickery to configure the MAC address and duplex settings, and documentation. But that won’t take too long.
And there’s more exciting news for the upcoming release, watch this space for more updates!