Electronic – Are all connections to the ENC28J60 required

beaglebone blackenc28j60spi

I'm trying to connect a ENC28J60 module that exposes a SPI interface to my Beaglebone Black. I only have pins 1 (NET_CS), 2 (SCK), 3 (MOSI, i.e., D0), 4 (MISO, i.e., D1), 5 (GND), 10 (VCC) connected to my Beaglebone's SPI1 interface. The pins that I have connected are as follows. The pins that I don't have connected are labeled N/A in the BBB PIN column.

ENC PIN  | FUNCTION | BBB PIN
-----------------------------
      1  | NET_CS   | P9.28
      2  | SCK      | P9.31
      3  | MOSI     | P9.29
      4  | MISO     | P9.30
      5  | GND      | P9.03
      6  | WOL      | <N/A>
      7  | NET_INT  | <N/A>
      8  | CLKOUT   | <N/A>
      9  | NET_RST  | <N/A>
      10 | VCC      | P9.01

I've used the following device tree overlay to configure my pins.

/dts-v1/;
/plugin/;

/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";

/* identification */
part-number = "BB-ENC28J60";

/* version */
version = "00A0";

/* state the resources this cape uses */
exclusive-use =
  /* the pin header uses */
  "P9.24",
  "P9.25",
  "P9.26",
  "P9.27",
  "P9.28",
  "P9.29",
  "P9.30",
  "P9.31",
  "spi1";

fragment@0 {
  target = <&am33xx_pinmux>;
  __overlay__ {
    pinctrl_spi1: pinctrl_spi1_pins {
    pinctrl-single,pins = <                                        
      0x184 0x37  /* P9_24 RST       | IN_PULLUP     | MODE7 */
      0x1ac 0x37  /* P9_25 INT       | IN_PULLUP     | MODE7 */
      0x180 0x37  /* P9_26 WOL       | IN_PULLUP     | MODE7 */
      0x1a4 0x37  /* P9_27 CLKOUT    | IN_PULLUP     | MODE7 */
      0x19c 0x13  /* P9_28 SPI1_CS   | OUTPUT_PULLUP | MODE3 */
      0x194 0x33  /* P9_29 SPI1_D0   | INPUT_PULLUP  | MODE3 */
      0x198 0x13  /* P9_30 SPI1_D1   | OUTPUT_PULLUP | MODE3 */
      0x190 0x3B  /* P9_31 SPI1_SCLK | INPUT_PULLUP  | MODE3 */
      >;
    };
  };
};

fragment@1 {
  target = <&spi1>;
     __overlay__ {
       #address-cells       = <1>;
       #size-cells          = <0>;
       status               = "okay";
       pinctrl-names        = "default";
       pinctrl-0            = <&pinctrl_spi1>;    

       spidev@0{
         compatible         = "microchip,enc28j60";
         reg                = <0>;
         interrupt-parent   = <&gpio3>;
         interrupts         = <21>;
         spi-max-frequency  = <20000000>;
       };
       spidev@1{
         compatible         = "spidev";
         reg                = <1>;
         spi-max-frequency  = <24000000>;
       };            
    };
  };
};

Note, for other readers, I have no idea what I'm doing with this device tree, especially with regards to the interrupt I chose in this example. So don't cut and paste it.

Having only these pins connected seems to be sufficient for identifying the module as a networking interface from a Debian running on my Beaglebone. I checked the dmesg log after the cape was applied and saw the following. When I play around with the wiring by reversing MISO and MOSI or some other combination involving CS or CLK, I consistently get errors in dmesg. That makes me think I'm on the right track, or at least that my wiring is correct.

[   57.074485] bone-capemgr bone_capemgr.9: part_number 'BB-ENC28J60', version 'N/A'
[   57.074670] bone-capemgr bone_capemgr.9: slot #7: generic override
[   57.074721] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 7
[   57.074774] bone-capemgr bone_capemgr.9: slot #7: 'Override Board Name,00A0,Override Manuf,BB-ENC28J60'
[   57.075043] bone-capemgr bone_capemgr.9: slot #7: Requesting part number/version based 'BB-ENC28J60-00A0.dtbo
[   57.075098] bone-capemgr bone_capemgr.9: slot #7: Requesting firmware 'BB-ENC28J60-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
[   57.086968] bone-capemgr bone_capemgr.9: slot #7: dtbo 'BB-ENC28J60-00A0.dtbo' loaded; converting to live tree
[   57.088829] bone-capemgr bone_capemgr.9: slot #7: #2 overlays
[   57.140361] edma-dma-engine edma-dma-engine.0: allocated channel for 0:45
[   57.140553] edma-dma-engine edma-dma-engine.0: allocated channel for 0:44
[   57.222844] edma-dma-engine edma-dma-engine.0: allocated channel for 0:43
[   57.223015] edma-dma-engine edma-dma-engine.0: allocated channel for 0:42
[   57.223509] enc28j60 spi1.0: enc28j60 Ethernet driver 1.01 loaded
[   57.237571] net eth1: enc28j60 driver registered
[   57.247437] bone-capemgr bone_capemgr.9: slot #7: Applied #2 overlays.

If I crank up the debugging level on the interface and ifconfig up the new interface I see the output below in my kernel log.

Nov 24 08:58:53 arm kernel: [  117.451971] enc28j60: enc28j60_net_open() enter
Nov 24 08:58:53 arm kernel: [  117.456764] enc28j60: enc28j60_hw_init() - HalfDuplex
Nov 24 08:58:53 arm kernel: [  117.456813] enc28j60: enc28j60_soft_reset() enter
Nov 24 08:58:53 arm kernel: [  117.461525] enc28j60: chip RevID: 0x06
Nov 24 08:58:53 arm kernel: [  117.469000] enc28j60 Hw initialized.
Nov 24 08:58:53 arm kernel: [  117.469000] HwRevID: 0x06
Nov 24 08:58:53 arm kernel: [  117.469000] Cntrl: ECON1 ECON2 ESTAT  EIR  EIE
Nov 24 08:58:53 arm kernel: [  117.469000]        0x03  0x88  0x01  0x00  0x00
Nov 24 08:58:53 arm kernel: [  117.469000] MAC  : MACON1 MACON3 MACON4
Nov 24 08:58:53 arm kernel: [  117.469000]        0x0d   0x32   0x40
Nov 24 08:58:53 arm kernel: [  117.469000] Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
Nov 24 08:58:53 arm kernel: [  117.469000]        0x0000 0x19ff 0x0000  0x19ff  0xa1    0x00    0x05ee
Nov 24 08:58:53 arm kernel: [  117.469000] Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP
Nov 24 08:58:53 arm kernel: [  117.469000]        0x1a00 0x1fff 0x0f     0x37     0x10
Nov 24 08:58:53 arm kernel: [  117.469118] enc28j60: eth1: Setting MAC address to 62:78:04:14:a4:b6
Nov 24 08:58:53 arm kernel: [  117.469602] enc28j60: enc28j60_hw_enable() enabling interrupts.
Nov 24 08:58:53 arm kernel: [  117.472893] enc28j60: enc28j60_check_link_status() PHSTAT1: 1800, PHSTAT2: 0000
Nov 24 08:58:53 arm kernel: [  117.472942] net eth1: link down
Nov 24 08:58:53 arm kernel: [  117.472982] net eth1: normal mode
Nov 24 08:58:53 arm kernel: [  117.473035] net eth1: normal mode
Nov 24 08:58:53 arm kernel: [  117.473208] net eth1: multicast mode
Nov 24 08:58:53 arm kernel: [  117.473295] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
Nov 24 08:58:53 arm kernel: [  117.473376] enc28j60: multicast mode

At this point, I'm stuck. My question is if all pins of my module required, or just the SPI-centric ones? If not, any pointers on debugging this further?

Best Answer

Assuming the ENC28J60 is otherwise correctly connected to run, you only need the connections you mention to a host to communicate with it over SPI. In theory, a host can do everything it needs to do by connecting to:

PWR and GND
CS (SPI chip select, driven by the host)
SCK (SPI clock, driven by the host)
MISO (chip to host data line)
MOSI (host to chip data line)

It can be handy for the host to also control the reset line, and there is a interrupt signal out of the chip if I remember right, but these connections are not strictly required. All management of the ENC28J60 can be done over the SPI. Using some of the additional lines is for convenience only.

Related Topic