XENON SD Card and Ethernet not working

Hardware

  • XENON
  • SD 3v3 breakout
  • Ethernet FeatherWing

XENON and ethernet work - no problems

SD card connected to MISO,MOSI,SCLK and D2 as SS. SdFat library used (from Web IDE) and using the sdformatter.ino example from the sdFat library to test.

When using card.begin(D2) it fails to find card. Ethernet then becomes unavailable and XENON either reboots or halts. (non responsive from Web IDE or console. Mode and reset have to be used to get it back into safe mode.

Have tried SS = A5 and D6 - same result.

Any pointers for me to try ?

The Ethernet FeatherWing also uses SPI with CS on D5 but since you are not in control of the communication the device OS can claim SPI at any time potentially interfering with your SD communication.
The least you need to do is to check whether D5 is currently pulled low and refrain from doing anything on SPI in that case.
Whenever you intend to do SD stuff, you need to prevent the system from interfering. Unfortunately I don’t know of a simple way to do that as we seem to have not function in the Ethernet object via which we can tell the system to hold off any communication temporarily nor does the EtherWing code care to check for active SPI transactions.

I have filed a GitHub issue on that topic

1 Like

Thanks for you reply - I will try and move the SD to SPI1 and let you know how it works out

I don't think this is an option either since (for some obscure reason) the Particle Ethernet FeatherWing currently uses non-remappable control pins that interfere with SPI1 (D2..D4) too.

Well that seems to be pretty poor planning - that has just blown my 1000 device project right out of the water !!

If you look at the GitHub issue I’ve filed, there already is a response from rickkas7 and avtolstoy is aware of it already too.
So chances are that enough demand on that issue may push it up the priority list.

1 Like

Cool - let me go and add my vote there as well - Thanks !

I am glad to see more people talk about this. I had commented a few weeks ago that the choice of pins for the Ethernet Featherwing is poor as it also eliminates the ability to use the second serial port of the Xenon.

Thank you @ScruffR for filing this serious issue.

I am using an SD Feather (changed CS to A0) along with a Xenon in an Ethernet wing. I keep getting SD read/write errors most likely due to this problem.

I would appreciate if you can show me a workaround while this issue gets resolved. Do I use a while loop to check for D5 being low before writing? What happens if while the SD card is being written, activity occurs on the Ethernet port?

Is it also possible to “suspend” Ethernet communications while the SD card is being read/written to? How can this be done?

Thanks in advance.

Checking CS of the EtherWing is no option as it may happen any time after your check by which time it’ll be too late to counteract.

Not sure whether disabling Ethernet would stop all SPI traffic (or attempts thereof) but that may be the best option you currently have. Just leave enough time between disabling and starting your SD tasks.

Thank you @ScruffR.

I noticed that the problem occurs even before the statements below in setup() which would indicate that Device OS is doing something before the Ethernet wing is started (possibly to connect to the cloud).

STARTUP(System.enableFeature(FEATURE_ETHERNET_DETECTION));
    Ethernet.on();
    Ethernet.connect();

STARTUP() is a macro and its placement doesn’t provide you with any clue about its time of execution.
Additionally your code snippet doesn’t seem to make a lot of sense (without seeing the context).

On the one hand STARTUP() is a macro that has no business inside a function - on the other hand your Ethernet.xxxx() calls can only exist inside a function.
So both of these cannot be on consecutive code lines.

https://docs.particle.io/reference/device-os/firmware/xenon/#startup-

BTW, if you don’t want Ethernet to be active you need to also select a non-AUTOMATIC SYSTEM_MODE().

1 Like

Thank you @ScruffR very much. I was not aware of “STARTUP” and its application as a macro. I have moved that statement out.

I will also make the following changes:

SYSTEM_MODE(MANUAL); 

     Ethernet.off();
     delay(200);
    //Do SD Stuff
     Ethernet.on();
     Ethernet.connect();
     clientEthernet.connect(myTCPserverIP, tcpPort);

Hopefully this will work until the SPI issue is addressed.

Did this end up working for you? I found that as long as I had an SD card physically inserted into my hardware that the SPI lines would lock up the ethernet connection.

Switching off the ethernet module and reading the SD card is no problem, but visa versa is an issue.

If the SD card was removed or inserted only after the initial booting process, software would respond as expected.

On the hardware, I tested switching the power rail to the SD card via MOSFET, as well as switching the MISO line with a tri-state buffer. Neither of these hardware solutions worked.

It’s currently basically impossible to successfully use SPI and Ethernet at the same time. The reason is that the system thread can end up interrupting an SPI operation occurring on the main thread and vice versa. In theory SPI transactions should mitigate this problem, however there’s a bug in that the system and user wrappers for SPI (wiring) use two different mutexes, rendering them not all that helpful.

1 Like

This has been bugged already - see @ScruffR post above from Mar 5 … and its logged as an issue in the ethernet wing repo as well.

Unfortunately there has been no response from the team yet - I guess its a matter of priority…

1 Like

Thanks for the responses. I appreciate it. In my situation, I don’t necessarily need to use the SD card while ethernet is active. I just need to read it on first boot. Would the current software prevent me from successfully using a demultiplexer on the pins that are shared for the Ethernet and SPI1?

Probably not, however do you have more than 4K of stuff to get from the SD? if not then stash it in the EEPROM

1 Like

Hell @ndan. I just read this.

Using the code above, it “sometimes” works but then locks up so it is not a reliable solution.

It looks like using a demux is the best approach. Can you post your circuit?

Here’s just what I have in mind, I haven’t tried this yet.