2
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ Tell us what pins 1, 2, 3, 4, 5 and 10 on the ENC28J60 are. No, I'm not going to look it up. That's your job. Obviously a lot more pins that than needed to be connected to the ENC28J60 for it to work, but only a small set of those need to be connected to the host so that it can communicate to the chip via SPI. We can't tell whether those are the right pins without their description. \$\endgroup\$ – Olin Lathrop Nov 26 '14 at 17:15
  • \$\begingroup\$ Updated the question which makes this more clear. I preserved the schematic link, though, because it is helpful for double checking. I also added a link to the BBB's SPI1 interface pin layout that I think I am using. \$\endgroup\$ – sholsapp Nov 26 '14 at 17:40
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Thanks @Olin, so it sounds like, given my situation (viz., overlay is applied correctly, driver is loaded correctly, etc.), that the chip should be working, albeit in some degraded state without interrupts. Any pointers on how debugging is done at this level, and if question (4) might have anything to do with my issue? \$\endgroup\$ – sholsapp Nov 26 '14 at 18:51
  • 1
    \$\begingroup\$ @Shol: The ENC28J60 is a complex device, so debugging a existing implementation by watching the SPI traffic will be nearly impossible. Make sure the signals look good, but beyond that it's all about the code, not the electronics. There are also a lot of poorly written implementations out there that set the banks manually and do other things just asking for software errors. If the code is properly documented you can single step thru it and see where it's getting stuck. \$\endgroup\$ – Olin Lathrop Nov 26 '14 at 19:53
  • \$\begingroup\$ Thanks @Olin. I've cranked up the debugging level on the ENC28J60's driver and can now see that the link can never get into an up state, viz., that at cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/… the PHSTAT2 is always the value 0. I reversed to that line from the log line enc28j60: enc28j60_check_link_status() PHSTAT1: 1800, PHSTAT2: 0000 . Does this indicate a problem with my devicetree or interrupt handling? \$\endgroup\$ – sholsapp Dec 9 '14 at 5:01
  • \$\begingroup\$ @Shol: Most of what you are asking seems to be related to the specific driver you are using, which I am not familiar with. It's been a long time since I wrote my own driver, so I also don't remember the details of register values inside the device. The best thing is to read the datasheet - very carefully - several times. That's how I got my driver up and running. Also check the errata. Always set the ENC28J60 to full duplex. Don't let it try to negotiate. This chip is complex, but it is well documented. \$\endgroup\$ – Olin Lathrop Dec 10 '14 at 18:19
  • \$\begingroup\$ You were right, it was a driver problem. I've moved over to electronics.stackexchange.com/questions/152211/… now. \$\endgroup\$ – sholsapp Feb 4 '15 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.