Sunday, September 6, 2015

RPi-A to ethernet

 

Use the following at your own risk

--------------------------------------

 ENC28J60 SPI Ethernet

Selected comments:

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.
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
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

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 specificsby 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.

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
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)

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...

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


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: 3452
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

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?
 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 it shows the syntax as


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

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?

Please post technical questions on the forum, not by personal message. Thanks.
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 it shows the syntax as


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

No comments:

Post a Comment