ENC28J60 SPI Ethernet


22 posts
by psergiu » Tue Sep 25, 2012 1:08 pm
Hi everyone,

I want to use a ENC28J60 SPI ethernet board with the latest Raspbian.

It's possible, the driver exists in the kernel source code, and Chris Boot already did-it before.

Can anyone give me some hints on how i can accomplish this ? Do i need to recompile the whole kernel or just the enc28j60.c kernel module ? Any pointers on the kernel source (shall i use the kernel.org image or shall i download a RPi-speciffic one, from where) ?

Thanks a lot.
User avatar
Posts: 218
Joined: Mon Nov 07, 2011 8:36 am
Location: TX, U.S.A. (was: RO, E.U.)
by RaTTuS » Tue Sep 25, 2012 1:14 pm
sudo apt-get update && sudo apt-get upgrade -y
reboot
git clone --depth 1 https://github.com/raspberrypi/linux.git
cd linux
zcat /proc/config.gz >.config
edit .config and enable
CONFIG_ENC28J6
make modules
sudo make modules_install
sacrifice 1st born
reboot

YMMV
http://www.catb.org/esr/faqs/smart-questions.html Ask Questions
http://www.raspberrypi.org/forums/viewtopic.php?f=29&t=7192 AutoStart Script

"That's not right, the badgers have moved the goalposts."
1QC43qbL5FySu2Pi51vGqKqxy3UiJgukSX
User avatar
Posts: 6475
Joined: Tue Nov 29, 2011 11:12 am
Location: North West UK
by psergiu » Tue Sep 25, 2012 7:14 pm
Thank you very much.

Thankfully i skiped the last step. And i backed up the old modules.

I somehow managed to compile broken kernel modules. "modinfo" says the are the same as the old ones, "file" says they are the same as the old ones but they are a couple ok Kb smaller and "modprobe" says: "ERROR: could not insert 'enc28j60': Exec format error"

and in "dmesg" i get "enc28j60: no symbol version for module_layout"

s/enc28j60/every_other_newly_compiled_module_i_tried/g
User avatar
Posts: 218
Joined: Mon Nov 07, 2011 8:36 am
Location: TX, U.S.A. (was: RO, E.U.)
by psergiu » Wed Sep 26, 2012 5:56 am
I succesfuly compiled the module

ln -s /wherever/i/downloaded/the/kernel /usr/src/linux
ln -s /usr/src/linux /lib/modules/`uname -r`/build
cd /lib/modules/`uname -r`/build
make -C /lib/modules/`uname -r`/build

i insmod the enc28j60 module aaaand ... nothing.

further reading on the interwebs tells me that for the 3.2.x kernel i have to edit a file somewhere to tell the kernel where my board is physically connected SPI BUS & CS

something like:
Code: Select all
static struct spi_board_info spi1_board_info[] __initdata = {
 

   {
      .modalias       = "enc28j60",
      .mode          = SPI_MODE_0,
      .irq         = AT32_EXTINT(0),
      .max_speed_hz      = 12000000,
      .chip_select      = 0,   
   },
};

and some init code.

http://www.avrfreaks.net/index.php?name ... ic&t=75282
http://ww2.cs.fsu.edu/~rosentha/linux/2 ... e1197.html
http://www.jumpnowtek.com/index.php?opt ... &Itemid=62

But where i'm supposed to put those code snippets and are there any specifics for Raspberry Pi ?
User avatar
Posts: 218
Joined: Mon Nov 07, 2011 8:36 am
Location: TX, U.S.A. (was: RO, E.U.)
by psergiu » Thu Sep 27, 2012 10:00 pm
Success.

file to edit: arch/arm/mach-bcm2708/bcm2708.c

search for "spi_board_info bcm2708_spi_devices" and modify as follows (assuming your ENC28J60 is connected to spi0.0 (CE0):

Code: Select all
static struct spi_board_info bcm2708_spi_devices[] = {
        {
                .modalias = "enc28j60",
                .max_speed_hz = 12000000,
                .bus_num = 0,
                .chip_select = 0,
                .mode = SPI_MODE_0,
        }, {
                .modalias = "spidev",
                .max_speed_hz = 500000,
                .bus_num = 0,
                .chip_select = 1,
                .mode = SPI_MODE_0,
        }
};


Recompile kernel & modules as in the previous post
cp arch/arm/boot/zImage /boot/kernel.img
cp drivers/net/ethernet/microchip/enc28j60.ko /lib/modules/`uname -r`/kernel/drivers/net/ethernet/microchip/
shutdown -r now

then after it starts up: modprobe enc28j60
and victory:
Code: Select all
[  847.810450] enc28j60 spi0.0: enc28j60 Ethernet driver 1.01 loaded
[  847.822819] net eth1: enc28j60 driver registered
[  847.947228] net eth1: link down
[  847.947297] net eth1: normal mode
[  847.947331] net eth1: normal mode
[  847.947558] net eth1: multicast mode
[  850.154955] net eth1: link up - Half duplex


Right now, the network card is working "IRQ-less" so the speed is not great ( ~100KB/sec).
Next step - connecting the network card's IRQ signal to a GPIO.
User avatar
Posts: 218
Joined: Mon Nov 07, 2011 8:36 am
Location: TX, U.S.A. (was: RO, E.U.)
by RaTTuS » Fri Sep 28, 2012 8:20 am
psergiu wrote:...
cp arch/arm/boot/zImage /boot/kernel.img
....

ooh I never knew you could just copy the zImage .... I've been using the imagetoo-uncompressed.py script ...
/me goes to change my special build machine
http://www.catb.org/esr/faqs/smart-questions.html Ask Questions
http://www.raspberrypi.org/forums/viewtopic.php?f=29&t=7192 AutoStart Script

"That's not right, the badgers have moved the goalposts."
1QC43qbL5FySu2Pi51vGqKqxy3UiJgukSX
User avatar
Posts: 6475
Joined: Tue Nov 29, 2011 11:12 am
Location: North West UK
by ezz » Fri Dec 28, 2012 10:20 pm
Anybody has a schematics of connection ?
Posts: 7
Joined: Fri Dec 21, 2012 4:08 pm
by psergiu » Fri Dec 28, 2012 10:50 pm
6 jumper wires:

ENC - RPi
=======
VCC - 3v3
GND - GND
CS - CE0 (gpio 8)
SI - MOSI (gpio 10)
SCK - SCKL (gpio 11)
SO - MISO (gpio 9)

Also, pin INT can be connected to another GPIO pin and the driver configured to use-it as IRQ (haven't done this yet so i cannot tell you exactly how)
User avatar
Posts: 218
Joined: Mon Nov 07, 2011 8:36 am
Location: TX, U.S.A. (was: RO, E.U.)
by msperl » Wed Nov 06, 2013 1:43 pm
For those of you who try to use this device with a current kernel:
you will need to configure the interrupt edge outside of the driver.

If you use spi-config to configure the SPI-parts (see: viewtopic.php?f=44&t=57157), then assuming you have:
  • the IRQ line on GPIO 25
  • the ENC28j60 CS on CS1

Then with this you can set up the network:
Code: Select all
echo "25" > /sys/class/gpio/export
echo "falling" > /sys/class/gpio/gpio25/edge
echo "25" > /sys/class/gpio/unexport
modprobe spi-config devices=bus=0:cs=1:modalias=enc28j60:speed=12000000:gpioirq=25


the above will load the enc28j60 driver (if you have it compiled as a module) and then start it up as "expected"...
Network is up almost immediately - but do not expect an extremely fast network...

Martin
Posts: 313
Joined: Thu Sep 20, 2012 3:40 pm
by psegura » Wed Mar 19, 2014 7:21 pm
Hello!
As I understand the steps are:

Wired connection:
6 jumper wires:

ENC - RPi
=======
VCC - 3v3
GND - GND
CS - CE0 (gpio 8)
SI - MOSI (gpio 10)
SCK - SCKL (gpio 11)
SO - MISO (gpio 9)

1.-
sudo apt-get update && sudo apt-get upgrade -y
reboot
git clone --depth 1 https://github.com/raspberrypi/linux.git
cd linux
zcat /proc/config.gz >.config
edit .config and enable
CONFIG_ENC28J6

2.-
edit: arch/arm/mach-bcm2708/bcm2708.c
search for "spi_board_info bcm2708_spi_devices" and modify as follows (assuming your ENC28J60 is connected to spi0.0 (CE0):

static struct spi_board_info bcm2708_spi_devices[] = {
{
.modalias = "enc28j60",
.max_speed_hz = 12000000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
}, {
.modalias = "spidev",
.max_speed_hz = 500000,
.bus_num = 0,
.chip_select = 1,
.mode = SPI_MODE_0,
}
};

3.-
ln -s /wherever/i/downloaded/the/kernel /usr/src/linux
ln -s /usr/src/linux /lib/modules/`uname -r`/build
cd /lib/modules/`uname -r`/build
make -C /lib/modules/`uname -r`/build

4.-
cp arch/arm/boot/zImage /boot/kernel.img
cp drivers/net/ethernet/microchip/enc28j60.ko /lib/modules/`uname -r`/kernel/drivers/net/ethernet/microchip/
shutdown -r now

If I'm not forgetting nothing please let me know why I do not have the enc28j60.ko file? Can I use enc28j60.o? And, how? modprobe? insmod?
I tried to recompile the module with this:
make -C /lib/modules/3.10.25+/build M=drivers/net/ethernet/microchip/enc28j60.ko
But just recived a ko directory:
root@raspberrypi:/lib/modules/3.10.25+/build# ls -l drivers/net/ethernet/microchip/
total 132
-rw-r--r-- 1 root root 24982 Mar 18 18:29 built-in.o
-rw-r--r-- 1 root root 45356 Mar 4 18:02 enc28j60.c
-rw-r--r-- 1 root root 8913 Mar 4 18:02 enc28j60_hw.h
drwxr-xr-x 3 root root 4096 Mar 19 12:57 enc28j60.ko
-rw-r--r-- 1 root root 24984 Mar 18 18:29 enc28j60.o
-rw-r--r-- 1 root root 1035 Mar 4 18:02 Kconfig
-rw-r--r-- 1 root root 95 Mar 4 18:02 Makefile
-rw-r--r-- 1 root root 50 Mar 18 23:02 modules.builtin
-rw-r--r-- 1 root root 0 Mar 19 12:40 modules.order
-rw-r--r-- 1 root root 0 Mar 19 12:40 Module.symvers

Thanks.
Posts: 1
Joined: Wed Mar 19, 2014 6:45 pm
by DirkS » Thu Dec 18, 2014 7:24 pm
I have the ENC28J60 working but not as I want it.

First time I cross-compiled the RPF kernel with the module enabled and the code changes mentioned above I had some problems so I decided to try it with Martin's spi-config (also cross-compiled).
Added spi-config to rc.local (including enabling the irq) and it works great (better than I expected actually).

Now I decided to go back to changing bcm2708.c; using above mentioned change
Code: Select all
edit: arch/arm/mach-bcm2708/bcm2708.c
search for "spi_board_info bcm2708_spi_devices" and modify as follows (assuming your ENC28J60 is connected to spi0.0 (CE0):

static struct spi_board_info bcm2708_spi_devices[] = {
{
  .modalias = "enc28j60",
  .max_speed_hz = 12000000,
  .bus_num = 0,
  .chip_select = 0,
  .mode = SPI_MODE_0,
};
<etcetera>

It compiles fine, but the result is slow and fairly unstable. Don't have a lot of experience with these things, but my guess is that this has something to do with the IRQ.

So my question is: are there any additional changes needed?

Gr.
Dirk.
Posts: 3428
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex
by DougieLawson » Thu Dec 18, 2014 7:58 pm
It gets easier with the 3.18.y kernel and the device tree.

For 3.12.33 I got it running with this code modification
Code: Select all
#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
#ifdef CONFIG_SPI_SPIDEV
        {
                .modalias = "enc28j60",  # changed for SPI ethernet
                .max_speed_hz = 12000000, # changed for SPI ethernet
                .bus_num = 0,
                .chip_select = 0,
                .mode = SPI_MODE_0,
        }, {
                .modalias = "spidev",
                .max_speed_hz = 500000,
                .bus_num = 0,
                .chip_select = 1,
                .mode = SPI_MODE_0,
        }
#endif
};
#endif


And
Code: Select all
CONFIG_ENC28J60=m
...
CONFIG_SPI=y
...
CONFIG_SPI_MASTER=y
...
CONFIG_SPI_BCM2708=y
...
CONFIG_SPI_SPIDEV=y
in .config

For 3.18.y
Code: Select all
CONFIG_ENC28J60=m
in .config is all that's needed. The hard work is done in the dts/dtb.
Code: Select all
                spi@7e204000 {
                        compatible = "brcm,bcm2708-spi";
                        reg = <0x7e204000 0x1000>;
                        interrupts = <0x2 0x16>;
                        clocks = <0x3>;
                        #address-cells = <0x1>;
                        #size-cells = <0x0>;
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <0x4>;

                        spidev@0 {
                                compatible = "enc28j60";
                                reg = <0x0>;
                                #address-cells = <0x1>;
                                #size-cells = <0x0>;
                                spi-max-frequency = <0xb71b00>;
                        };

                        spidev@1 {
                                compatible = "spidev";
                                reg = <0x1>;
                                #address-cells = <0x1>;
                                #size-cells = <0x0>;
                                spi-max-frequency = <0x7a120>;
                        };
                };
Note: 0xB71B00 == 12,000,000. There's no IRQ values in there at all. I've got mine wired on SCLK, MISO, MOSI and pin# 24 SPI CS0.
[SIG]
Hacker on ZX80, Microtan65, Raspberry Pi & Arduinos
Mainframe Database troubleshooter
MQTT Evangelist
RPi owner since 2012.
Twitter: @DougieLawson

2B, B+, A+, 5Bs

Please post technical questions on the forum, not by personal message. Thanks.
[/SIG]
User avatar
Posts: 14849
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
by DirkS » Thu Dec 18, 2014 8:08 pm
Cheers, Dougie.
I'll give that a go...

Gr.
Dirk.
Posts: 3428
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex
by BMS Doug » Sat Dec 20, 2014 2:41 pm
I've got one of these on order now (delivery in mid january), I'm hoping to use it with my A+ to make a NAS drive.
Doug.
Building Management Systems Engineer.
Posts: 2219
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK
by DougieLawson » Sun Feb 08, 2015 10:25 pm
Good news. The very nice folks who build the kernel are giving us a device tree overlay for the ENC28J60.
https://github.com/raspberrypi/linux/issues/795
[SIG]
Hacker on ZX80, Microtan65, Raspberry Pi & Arduinos
Mainframe Database troubleshooter
MQTT Evangelist
RPi owner since 2012.
Twitter: @DougieLawson

2B, B+, A+, 5Bs

Please post technical questions on the forum, not by personal message. Thanks.
[/SIG]
User avatar
Posts: 14849
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
by abishur » Sun Feb 15, 2015 1:42 am
DougieLawson wrote:Good news. The very nice folks who build the kernel are giving us a device tree overlay for the ENC28J60.
https://github.com/raspberrypi/linux/issues/795


So how does one actually make use of the device tree overlay for the enc28j60? Surely it's not just connect the device to the pi as described above and you're essentially plug and play, right?
Dear forum: Play nice ;-)
User avatar
Forum Moderator
Forum Moderator
Posts: 4475
Joined: Thu Jul 28, 2011 4:10 am
Location: USA
by DougieLawson » Sun Feb 15, 2015 1:50 am
Don't know yet, because PhilE hasn't finished the code or the docs for it.
[SIG]
Hacker on ZX80, Microtan65, Raspberry Pi & Arduinos
Mainframe Database troubleshooter
MQTT Evangelist
RPi owner since 2012.
Twitter: @DougieLawson

2B, B+, A+, 5Bs

Please post technical questions on the forum, not by personal message. Thanks.
[/SIG]
User avatar
Posts: 14849
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
by plugwash » Sun Feb 15, 2015 2:17 am
AIUI you add an entry in config.txt (or possiblly a HAT eeprom) to load the device tree overlay. That overlay tells the kernel to expect an enc28j60 and where to expect it. Then it should just work like any other ethernet controller.
Forum Moderator
Forum Moderator
Posts: 2775
Joined: Wed Dec 28, 2011 11:45 pm
by abishur » Sun Feb 15, 2015 3:04 am
DougieLawson wrote:Don't know yet, because PhilE hasn't finished the code or the docs for it.

Ah, my bad, I thought the dts you were refering to in a previous post was the a device tree thing. How are you loading this module right now?
Dear forum: Play nice ;-)
User avatar
Forum Moderator
Forum Moderator
Posts: 4475
Joined: Thu Jul 28, 2011 4:10 am
Location: USA
by abishur » Sun Feb 15, 2015 3:09 am
plugwash wrote:AIUI you add an entry in config.txt (or possiblly a HAT eeprom) to load the device tree overlay. That overlay tells the kernel to expect an enc28j60 and where to expect it. Then it should just work like any other ethernet controller.


Do you know the syntax for it by the way? I notice that in the documentation for the device tree on the raspberrypi github (here) it shows the syntax as

Code: Select all
#device_tree_param=spi=on


But in the latest version of raspi-config I enabled the device tree and it added an entry like this for SPI

Code: Select all
dtparam=spi=on
Dear forum: Play nice ;-)
User avatar
Forum Moderator
Forum Moderator
Posts: 4475
Joined: Thu Jul 28, 2011 4:10 am
Location: USA
by DougieLawson » Sun Feb 15, 2015 9:35 am
abishur wrote:
DougieLawson wrote:Don't know yet, because PhilE hasn't finished the code or the docs for it.

Ah, my bad, I thought the dts you were refering to in a previous post was the a device tree thing. How are you loading this module right now?


At the moment my A+ is running on WiFi. I'll experiment with the ENC28J60 when the code from PhilE is ready.
[SIG]
Hacker on ZX80, Microtan65, Raspberry Pi & Arduinos
Mainframe Database troubleshooter
MQTT Evangelist
RPi owner since 2012.
Twitter: @DougieLawson

2B, B+, A+, 5Bs

Please post technical questions on the forum, not by personal message. Thanks.
[/SIG]
User avatar
Posts: 14849
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
by DirkS » Sun Feb 15, 2015 10:05 am
abishur wrote:
plugwash wrote:AIUI you add an entry in config.txt (or possiblly a HAT eeprom) to load the device tree overlay. That overlay tells the kernel to expect an enc28j60 and where to expect it. Then it should just work like any other ethernet controller.


Do you know the syntax for it by the way? I notice that in the documentation for the device tree on the raspberrypi github (here) it shows the syntax as

Code: Select all
#device_tree_param=spi=on


But in the latest version of raspi-config I enabled the device tree and it added an entry like this for SPI

Code: Select all
dtparam=spi=on

Both are valid, you can also leave out '=on'. See https://github.com/raspberrypi/document ... short-cuts
Posts: 3428
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex