Based on the hardware abstraction layer for my TCP/IP stack, I wrote a software driver for the ENC28J60 ethernet module. As said before the module is very cheap but has quite some issues and the software is trying to cover these issues as much as possible. However there was one I couldn’t solve completely: interrupt on packet reception; that one is completely unreliable even with the workarounds proposed by Microchip. Thus I decided to stay away from the interrupts, which is not so bad, as I have now more control on the packet buffer usage.
The ENC28J60 module communicates with the micro controller via SPI, the maximum speed of the SPI interface is 20MHz, so I had to downscale the STM32F407 as the APB2 clock is running at 84MHz, a prescaler of 8 is doing the trick. I tried to run with prescaler of 4 but it yielded an unstable ENC28J60. Besides the SPI connection, you’ll also need the /CS (chip select for the SPI) and the /RESET pins.
The hardware abstraction layer requires at least 3 methods:
- initialization of the hardware
- read a packet
- send a packet
Developing the driver is not so difficult if you keep the datasheet at hand but at several occasions you also need to take into account the errata:
ENC28J60 (1.2 MiB)
ENC28J60 ERRATA (261.8 KiB)
My version of the hardware driver can be found here:
drvEnc28j60.h (12.9 KiB)
drvEnc28j60.c (11.4 KiB)
In the drvEnc28j60_packetRecv function you’ll see a strange piece of code at the end which forces the Rx read pointer to next packet to be odd all the time; this was one of the errata I had to implement in the driver. Without this the ENC28J60’s internal packet buffer got corrupted very often.