How to use w5500 on SPI1 /and/ keep Cellular?

Using the w5500 chip to SPI1 on Electron (pins D2 thru D5 = #27 thru 30; w/o interrupt, reset),
But it doesn't seem to come alive; in fact Electron breathes white and doesn't output to "particle serial monitor" either.

Starting from the top with SPI1 -
image

Confirmed default vs optional pins -

With libs (and cascades to other libs like w5500.h, EthernetClient.h, etc.) -
image

And updated lib w5500.cpp / .h with both "SPI1" and its pin "D5" -
image

Also in Ethernet.cpp / .h (apparently optional parameter now D5) -
image

So not sure if I'm missing some libs yet or SPI1 inadvertently took over the Cellular connection? Because I have not touched that part..

And forgive but I didn't see the NCD thread / lib rounded out on the w5500 chip...
(For example NCD_Ethernet_Overlay.cpp / .h doesn't contain real functions yet.)

What does your actual main application source look like? What system mode and threading mode are you using?

Breathing white indicates the device is running in cloud disconnected mode, so my guess is that your main code is not attempting to connect, which will only ever use cellular on the Electron. The Electron can't use Ethernet for the cloud connection or for built-in classes like TCPClient or UDP so it shouldn't conflict.

Ah so that hasn't changed,
image

And -

void setup() {
    startSerialX();                                                  
    setupTCP();
    setupParticleCloud()                                       // For Particle funcs, vars to cloud
}

void loop() {
    if (Particle.connected() == false) {
        Particle.connect();
    }
    loopTCP();
}

Along with -

#include "TCP.h"

unsigned long lastLogT = 0;                              
unsigned long tcpRead = 5000;                              // 5, 10, etc. ms           

EthernetClient eClient;
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
IPAddress servIP(10,1,1,39);
int servPort = 1701;


void setupTCP() 
{
    lastLogT = millis();
    if (Ethernet.begin(mac) == 0) {
        Log.info("Failed to config Eth using DHCP");
    }
    Log.info("Eth IP addr is: %s", Ethernet.localIP().toString().c_str());
}

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();
        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
                eClient.println("user1");
            } else {
                Log.info("Could not cnx to serv");
            }
        }

        if (eClient.connected() && eClient.available() > 0) {
            while (eClient.available() > 0){
                Log.info((const char*)eClient.read());
            }
        }
    }
}

Noting I throttled the TCP loop so it's easier to debug and doesn't run amok if I put the wrong address or something :joy:

Since you don't connect to the cloud until loop() I'd guess that something called from setup() is blocking. I'd just keep adding serial debug statements until you figure out what.

Ok see that's another thing, not getting any serial debug statements, even tho 'particle serial monitor' connects fine... and even tho I'm using Log.info (avoid Serial.Println that may block).

And you think Particle.connect() should go up in Setup()?
Coz I have it in Loop() so that my setupParticleCloud() has time to run in Setup();

Believe you / the docs said that Particle.function and Particle.variable should be put at end of Setup() such that -

  1. any user code can register with the cloud, and
  2. still has to happen quickly so that cloud actually registers (doesn't timeout)

In fact that's the only reason (I can recall) to do SYSTEM_MODE(SEMI_AUTOMATIC) and SYSTEM_THREAD(ENABLED), so that Particle.connect() can be run manually again (even tho it's prob run automatically earlier, no?)

And,

Not entirely sure what could block, like wrong MAC (does it even matter)? DHCP didn't issue? etc.

Do you have the serial log handler enabled? This should be a global.

SerialLogHandler logHandler;

I'd do Particle.function and Particle.variable, then call Particle.connect() after those are done.

Yessir,
I prob should have mentioned but yet it's been working great before this -

SerialLogHandler logHandler(115200, LOG_LEVEL_INFO);                // Default is Log.info, but can do trace, can 'overload' w/ specifics

Ok, and no need to re-run Particle.connect() in Loop(), because of SYSTEM_MODE(SEMI_AUTOMATIC)?

Correct. Just call Particle.connect() once in SEMI_AUTOMATIC mode, assuming you don't manually disconnect, of course.

Ok, thanks.

And suppose that setupTCP() call is also blocking the global SerialLogHandler ?


EDIT
Yes, this line seems to block both (logs and cellular) -

     if (Ethernet.begin(mac) == 0) {
         Log.info("Failed to config Eth using DHCP");
     }

Back to 1st part,
What's the trick to get w5500 working on SPI1?

Aside from that above (change - pin assignment from A2 to D5; SPI to SPI1 in libs w5500.h, Ethernet.h; uncomment SPI1.beginTransaction)

Noting this is a bit cleaner -

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();

        if (!cnxT) {
            Log.info("Trying Eth.begin");
            Ethernet.begin(mac, locIP, locIP, locIP);
            Log.info("Eth IP addr is: %s", Ethernet.localIP().toString().c_str());
        }

        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
            } else {
                Log.info("Could not cnx to serv");
            }
        } else {
            eClient.println("user1");

            if (eClient.available() > 0) {
                while (eClient.available() > 0){
                    Log.info((const char*)eClient.read());
                }
            }
        }
    }
}

Also note

  1. Gen2 running OS 3.0.0
  2. Going thru a switch (to auto MDIX, so don't have to worry about crossover cable)
  3. Can confirm socket on server w/ telnet program

Which Ethernet library are you using? You'd have to search there, as the Electron does not support the Ethernet class that's described in the docs and I've never used Ethernet on Gen 2.

This one in community libs -

And the repo -

Not sure what that mean.. Even if it leverages the same spark_wiring_'xyz' libs?

That's using the class Ethernet in the NCD_Ethernet_Overlay library in the file Ethernet.h in the library.

The definition of the Ethernet class in spark_wiriing_ethernet.h isn't used because the header file is protected with #if test and Wiring_Ethernet is 0 for Gen 2 devices including the Electron.

Forgive my ignorance,

So I do have the NCD_ lib in Workbench -
image

And you're saying don't call Ethernet.begin but rather EthernetClass.begin (more specifically, eClass.begin, below) as defined in the NCD lib (vs the other / default / incompatible Ethernet lib)?
So then -

EthernetClass eClass;
EthernetClient eClient;
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
IPAddress locIP(10,1,1,102);                            
IPAddress servIP(10,1,1,39);
int servPort = 1701;


void setupTCP() 
{
    lastLogT = millis();

}

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();

        if (!cnxT) {
            Log.info("Trying Eth.begin");
            eClass.begin(mac, locIP, locIP, locIP);
            Log.info("Eth IP addr is: %s", eClass.localIP().toString().c_str());
        }

        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
            } else {
                Log.info("Could not cnx to serv");
            }
        } 
    }
}

Noting the repeat locIP is just repeating the same IP as a default value for the local w5500, before it connects to remote (server) TCP socket.

And that I don't really want to alter the NCD lib, just use as-is and then further implement read, write in my own TCP file.


EDIT
And following the lib chain -
image

That <Ethernet.h> above resolves to NCD_Ethernet_Overlay (and so forth) -
image

No, Ethernet.begin() is correct. EthernetClass is the C++ class name, Ethernet is the single instance of that class (scroll down to the bottom of the Ethernet.h file to see it).

But in looking at W5500.cpp, the problem is that the library does not work with SPI1. Every call to SPI is hardcoded to SPI to you'd need to modify the library to use SPI1.

Ah yes thanks

Yes exactly! Tried to show that in screenshots above, but doesn't seem to open a client..

You'll have to dig in farther then. I'd add serial print statement when it reads a register. If it's coming back all 0xff or 255, then the W5500 is not responding, which could be a connection issue.

Hm ok,

I did also uncomment the SPI1.beginTransaction statements in w5500.cpp / .h, going by other forum threads where I believe you said the beginTransaction is important for traffic on SPI bus