Teensy 4 SD card and WIZ820io not playing well together

Hi,

I've been using the Teensy 4 with the WIZ820io Ehternet adapter for the last week or so and having great success at 30Mhz, that is until I added an SPIO SD card. Now I have issues getting the Ethernet adapter to initialize correctly. If an SD card is plugged in the WIZ820 either doesn't initialize or the IP address is wrong after initialization. I've read various posts that seem to be on this issue but they all seem fairly old and it seems that the issue was resolved, which leads me to believe its my breadboard prototype that is the issue!

With this in mind I decided to re-wire the prototype with shorter leads and I have now made things worse! Now with no SD card inserted, the WIZ820 wont initialize at all if the SCK cable is also attached to the SD card adapter, unless I set up SPI mode at 14Mhz. Also added 10K pull-up resistors to both CS lines but made no difference.

So I guess my question is am I simply chasing problems that I'm not going to solve with this setup? I have ordered a SD/WIZ adapter to clean things up a bit in hope that this is the issue. I've also ordered a Teensy 4.1, but I was hooping to use the smaller format 4.0 and my own SD socket on a custom PCB.

( I always seem to get the "Ethernet cable is not connected" message even when the WIZ820 is working without SD card interference )

IMG_20200911_141601.jpg
IMG_20200911_141605.jpg

My test code:
Code:
// Quick hardware test for SPI card access.
//
#include <SPI.h>
#include "SdFat.h"
#include "sdios.h"
#include <Ethernet.h>

#define SPI_SPEED SD_SCK_MHZ(4)

SdFat sd;

#define ETHCS_PIN         10  // set in Ethernet library, see above
#define WIZ820_RST        9
#define SDCS_PIN          6

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress myIp(10, 0, 0, 2); 

void setup() 
{
  Serial.begin(115200);

  // Wait for USB Serial
  while (!Serial) 
  {
    SysCall::yield();
  }

  Serial.println("Start.");
  
  pinMode(WIZ820_RST, OUTPUT);
  digitalWrite(WIZ820_RST, LOW);    // begin reset the WIZ820io
  pinMode(ETHCS_PIN, OUTPUT);
  digitalWrite(ETHCS_PIN, HIGH);  // de-select WIZ820io
  pinMode(SDCS_PIN, OUTPUT);
  digitalWrite(SDCS_PIN, HIGH);   // de-select the SD Card
  delay(100);
  digitalWrite(WIZ820_RST, HIGH);   // end reset pulse
  delay(500);

  Serial.println("Init ETH.");
  
  Ethernet.init(ETHCS_PIN);  // Most Arduino shields CS pin
  Ethernet.begin(mac,myIp);
  
  IPAddress ip = Ethernet.localIP();
  Serial.print("My IP Address = ");
  Serial.println(ip);

  if (Ethernet.hardwareStatus() == EthernetNoHardware) Serial.println("Ethernet shield was not found");
  if (Ethernet.linkStatus() == LinkOFF) Serial.println("Ethernet cable is not connected");

   Serial.println("Init SD.");
   if (!sd.begin(SDCS_PIN, SPI_SPEED)) 
   {
    if (sd.card()->errorCode()) 
    {
      Serial.print("SD Card initialisation failed! Error: ");
      Serial.println(sd.card()->errorCode());
    }
    
   }
   else
   {
    Serial.println("SD Card initialised OK");
    uint32_t size = sd.card()->cardSize();
    uint32_t sizeMB = 0.000512 * size + 0.5;
    if( size == 0 ) Serial.println("Can't determine the card size.");
    else
      {
      Serial.print("Size = ");
      Serial.print(sizeMB);
      Serial.println(" MB");
      }
   }

  Serial.println("Done.");
}


void loop() {
}

Output with no SD card and SD card SCK wire disconnected:
Code:
Start.
Init ETH.
My IP Address = [B][COLOR="#0000FF"]10.0.0.2[/COLOR][/B]
Ethernet cable is not connected
Init SD.
SD Card initialisation failed! Error: 32
Done.

Output with no SD card and SD card SCK wire connected:
Code:
Start.
Init ETH.
My IP Address = [B][COLOR="#FF0000"]0.0.0.0[/COLOR][/B]
Ethernet cable is not connected
Init SD.
SD Card initialisation failed! Error: 32
Done.

Output with SD card inserted and SD card SCK wire connected:
Code:
Start.
Init ETH.
My IP Address = [B][COLOR="#FF0000"]0.0.0.0[/COLOR][/B]
Ethernet cable is not connected
Init SD.
SD Card initialised OK
Size = 32034 MB
Done.
 
Sorry, I am probably not much help, but my quick look at the discontinued Hobbytronics SD Adapter does not give much (any information)...
https://www.hobbytronics.co.uk/microsd-breakout

But what I see, looks like without an SD Card plugged in, it should more or less do nothing? Unless maybe some short or???

But if it were me, my next step might be to try the SD Adapter by itself and and see if it works.
 
Hi Kurt,

The SD adapter on its own works fine, as does the Ethernet on its own. Which leads me to believe its something to do with the breadboard signal issues.

The discontinued SD adapter just has the pins wired straight through to the SD card with not passive or active components.
 
That is what I thought, so unless you daisy-chained some of the signals, you would think it would not impact each other as long as an SDCard was not in place.

You say it works if the CLK pin of the SD Card reader is not connected? Even with the current software that includes the SD library code?

Not sure what else to suggest.

I assume you probably already tried to rewire it to make sure you did not get off by one or ... Try maybe adding PU resistor(s)... I would probably look at signals using Logic Analyzer, but...
 
Sounds like an SPI bus contention issue. Does your SD Card adaptor use Tri-State buffers on the SCLK, MISO & MOSI lines controlled by CS? ISTR some SD Cards play nice while others don't on shared SPI interface.
 
I tested on this known-good hardware.

DSC_1047_web.jpg

First I ran the Ethernet WebClient example, to check the network really was working. Indeed it is able to fetch the web page.

Next, I ran your code from msg #1, but with SDCS_PIN set to 4, since that board has the SD card CS on pin 4.

With no card install, I get this:

Code:
Start.
Init ETH.
My IP Address = 10.0.0.2
Ethernet cable is not connected
Init SD.
SD Card initialisation failed! Error: 32
Done.

With a SD card in the socket, I get this:

Code:
Start.
Init ETH.
My IP Address = 10.0.0.2
Ethernet cable is not connected
Init SD.
SD Card initialised OK
Size = 7948 MB
Done.

Looks like the "Ethernet cable is not connected" message is showing up even with the cable is indeed plugged in. :(
 
That is what I thought, so unless you daisy-chained some of the signals, you would think it would not impact each other as long as an SDCard was not in place.

You say it works if the CLK pin of the SD Card reader is not connected? Even with the current software that includes the SD library code?

Not sure what else to suggest.

I assume you probably already tried to rewire it to make sure you did not get off by one or ... Try maybe adding PU resistor(s)... I would probably look at signals using Logic Analyzer, but...

I had added PU resistors to the CS lines, I could also try on the clk and signal lines. I do have an analyzer so I will see whats happening to the bus when card is plugged in.
 
Sounds like an SPI bus contention issue. Does your SD Card adaptor use Tri-State buffers on the SCLK, MISO & MOSI lines controlled by CS? ISTR some SD Cards play nice while others don't on shared SPI interface.

The card adapter has no active or passive components on-board, just the signals routed through to the card pins.
 
I tested on this known-good hardware.

View attachment 21705

First I ran the Ethernet WebClient example, to check the network really was working. Indeed it is able to fetch the web page.

Next, I ran your code from msg #1, but with SDCS_PIN set to 4, since that board has the SD card CS on pin 4.

With no card install, I get this:

Code:
Start.
Init ETH.
My IP Address = 10.0.0.2
Ethernet cable is not connected
Init SD.
SD Card initialisation failed! Error: 32
Done.

With a SD card in the socket, I get this:

Code:
Start.
Init ETH.
My IP Address = 10.0.0.2
Ethernet cable is not connected
Init SD.
SD Card initialised OK
Size = 7948 MB
Done.

Looks like the "Ethernet cable is not connected" message is showing up even with the cable is indeed plugged in. :(

Thank's for testing on your hardware, confirms what I thought that it is something to do with my hardware. I will plug in an analyzer today and have a poke around, but if I can't get it working I will wait for the new hardware to turn up and start again.

Good to know you get the same cable unplugged error though!
 
My Teensy 4.1 arrived today, and I'm getting it rigged up but have hit a slight stumbling block. How do I get the Ethernet library to use an external device such as the WIZ820io or ultimately an SPI wifi device. When I run my test code on the 4.1 with the WIZ820io it doesn't seem to work, I'm assuming this is because the internal Ethernet is being used?

I will run further tests on my initial setup of Teensy 4.0 and try to get to the bottom of the SD card issue.
 
My Teensy 4.1 arrived today, and I'm getting it rigged up but have hit a slight stumbling block. How do I get the Ethernet library to use an external device such as the WIZ820io or ultimately an SPI wifi device. When I run my test code on the 4.1 with the WIZ820io it doesn't seem to work, I'm assuming this is because the internal Ethernet is being used?

I will run further tests on my initial setup of Teensy 4.0 and try to get to the bottom of the SD card issue.

Replying to my own post, I now have the Teensy 4.1 working with the WIZ820io. The issue in this case was a breadboard issue! cheap prototyping board! Anyway, now that is resolved, this leads me to the question how do you use the Internal Ethernet over the external SPI WIZ820io ?
 
Well I purchased the Teensy WIZ820IO & SD card adapter but I'm still having problems getting both to work together! But now I'm getting different results! I changed the code to use the SD library rather than the sdFat lib, and I moved the SD initialization before the Ethernet init as this seemed to help with other projects, but now with this adapter and a Teensy 4, it ONLY works if the SD card is inserted! Without the SD card the Ethernet does not initialize correctly :confused:

IMG_20200916_094740.jpg

Code:
// Quick hardware test for SPI card access.
//
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>

#define ETHCS_PIN         10  // set in Ethernet library, see above
#define WIZ820_RST        9
#define SDCS_PIN          4

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress myIp(10, 0, 0, 2); 

void setup() 
{
  Serial.begin(115200);

  // Wait for USB Serial
  while (!Serial);
  Serial.println("Start.");

  pinMode(WIZ820_RST, OUTPUT);
  digitalWrite(WIZ820_RST, LOW);    // begin reset the WIZ820io 
  pinMode(ETHCS_PIN, OUTPUT);
  digitalWrite(ETHCS_PIN, HIGH);  // de-select WIZ820io
  pinMode(SDCS_PIN, OUTPUT);
  digitalWrite(SDCS_PIN, HIGH);   // de-select the SD Card
  delay(100);
  digitalWrite(WIZ820_RST, HIGH);   // end reset pulse
  delay(500);
  
   Serial.println("Init SD.");
   if (!SD.begin(SDCS_PIN)) 
   {
      Serial.print("SD Card initialisation failed!");
   }
   else
   {
      Serial.println("SD Card initialised OK");
   }  

  Serial.println("Init ETH.");
  
  Ethernet.init(ETHCS_PIN);  // Most Arduino shields CS pin
  Ethernet.begin(mac,myIp);

  if (Ethernet.hardwareStatus() == EthernetNoHardware) Serial.println("Ethernet shield was not found");
  if (Ethernet.linkStatus() == LinkOFF) Serial.println("Ethernet cable is not connected");

  IPAddress ip = Ethernet.localIP();
  Serial.print("My IP Address = ");
  Serial.println(ip);


  Serial.println("Done.");
}


void loop() {
}

With SD card in:
Code:
Start.
Init SD.
SD Card initialisation failed!Init ETH.
[COLOR="#0000FF"]Ethernet cable is not connected
My IP Address = 10.0.0.2[/COLOR]
Done.

Without SD card in:
Code:
Start.
Init SD.
SD Card initialisation failed!Init ETH.
[COLOR="#FF0000"]Ethernet shield was not found
My IP Address = 0.0.0.0[/COLOR]
Done.

So out of frustration I tried the same setup with a Teensy 3.2, but with the 3.2 I get different behavior, basically it won't work with the SD card in, which is where I was before :confused:
 
With PJRC wiznet adapter (WIZ850io) and T3.2, I successfully ran a sketch that initialized Ether, then initialized SD and listed SD directory, then sent UDP packets to/from NTP server. Adapter was mounted on female headers of T3.2 and I used SD lib (CS set to pin 4)

UPDATE: plugged adapter into T4.0 with female headers, and sketch worked
t4esd.jpg
Code:
#include <stdint.h>
#include <SPI.h>
//#include <SPIFIFO.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <utility/w5100.h>
#include <time.h>
#include <SD.h>

#define swap4 __builtin_bswap32

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
static byte mac[6] = {0x0A, 0x1B, 0x3C, 0x4D, 0x5E, 0x6F};
IPAddress ip(192, 168, 1, 15);

#define NBYTES 100000
#define RECLTH 1000
#define TTCP_PORT 5001
EthernetServer server(TTCP_PORT);
EthernetClient client;


unsigned int localPort = 8888;      // local port to listen for UDP packets
unsigned int dstport = 7654;      //  dst port

IPAddress udpServer(192, 168, 1, 4);

#define PACKET_SIZE 1024

byte packetBuffer[ PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

#define SS  10


void udp_ntp() {
  uint32_t secs, nus, us, rtt;
  static uint32_t us0 = 0, secs0, nus0;
  while (1) {
    packetBuffer[0] = 0x1b;   // ntp query
    Udp.beginPacket(udpServer, 123);
    Udp.write(packetBuffer, 48);
    Udp.endPacket();
    rtt = micros();
    while (!Udp.parsePacket()); // wait  ? timeout
    us = micros();
    rtt = us - rtt;
    Udp.read(packetBuffer, sizeof(packetBuffer));
    secs = swap4(*(uint32_t *) (packetBuffer + 40));
    //nus = swap4(*(uint32_t *) (packetBuffer + 44)) / 4295; // fract sec
    uint64_t x = swap4(*(uint32_t *) (packetBuffer + 44));
    nus = (1000000 * x) >> 32;
    if (us0 == 0) {
      us0 = us;
      secs0 = secs;
      nus0 = nus;
      time_t edt = secs - 2208988800 - 4 * 3600; // NTP 1990 to unix 1970 and EDT
      Serial.print(ctime(&edt));
    }
    double t = 1000000 * (secs - secs0) + (nus - nus0); // elapsed remote us
    Serial.printf("ntp %u.%06d  rtt %d us   %.0f ppm over %d s\n",
                  secs, nus, rtt, (1000000. * ((us - us0) - t)) / t, secs - secs0);
    delay(10000);
  }
}


File root;
void setup()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);    // begin reset the WIZ820io
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);  // de-select WIZ820io
  delay(1);
  digitalWrite(9, HIGH);   // end reset pulse
  // start Ethernet and UDP
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  Serial.begin(9600);
  while (!Serial);
  Serial.print("IP  address:");
  Serial.println(Ethernet.localIP());
  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  root = SD.open("/");
  printDirectory(root, 0);
}

void loop()
{

  udp_ntp();

  delay(5000);
}
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}
 
Last edited:
After trying many variations of hardware it simply comes down to this: The SPI bus does NOT behave well on a breadboard setup! I have spent way too long resolving this issue and even broke out the Logic analyzer, anyway, I ended up stacking the PJRC adapter directly onto the Teensy 4 and all is now working consistently. I did get my test board to work some of the time, but it was very flaky!

This is good to know because I was thinking of having an external SPI bus for either WIZ820 or WIfi module, but I very much doubt it would work.

IMG_20200916_160928.jpg
 
Hi winchymatt,

things are tricky when an SD card shares the SPI bus with other SPI devices. Reason is that at startup every SD card is in SD mode and requires a command sequence to switch into SPI mode. Of course you can (and must) handle that situation gracefully upon Teensy startup by pulling all CS lines of all other SPI devices high and then sending CMD0 to the SD card before starting any other SPI communication. But if you would hot-plug an SD card onto the SPI bus it would inevitably listen to the communication ongoing on the SPI bus in SD mode and would start to interpret that communication as SD mode commands, and reply accordingly spoiling the SPI bus, even if the SD card CS line is high, because in SD mode the CS line of the SD card is not a CS line but is rather used as one of the data lines. For details refer to the Physical Layer Simplified Specification at https://www.sdcard.org/downloads/pls.

Kind regards,
Sebastian
 
Hi winchymatt,

things are tricky when an SD card shares the SPI bus with other SPI devices. Reason is that at startup every SD card is in SD mode and requires a command sequence to switch into SPI mode. Of course you can (and must) handle that situation gracefully upon Teensy startup by pulling all CS lines of all other SPI devices high and then sending CMD0 to the SD card before starting any other SPI communication. But if you would hot-plug an SD card onto the SPI bus it would inevitably listen to the communication ongoing on the SPI bus in SD mode and would start to interpret that communication as SD mode commands, and reply accordingly spoiling the SPI bus, even if the SD card CS line is high, because in SD mode the CS line of the SD card is not a CS line but is rather used as one of the data lines. For details refer to the Physical Layer Simplified Specification at https://www.sdcard.org/downloads/pls.

Kind regards,
Sebastian

Thanks Sebastian,

Good information to know! I guess this is why its better to use the onboard SD socket! I wish there was a socket available to fit the Teensy 4.0.

Matt.
 
Thanks Sebastian,

Good information to know! I guess this is why its better to use the onboard SD socket! I wish there was a socket available to fit the Teensy 4.0.

Matt.

i made this using some parts off LCSC and a pcb i designed
20200924_182417.jpg20200924_182410.jpg

the connector on the teensy is Part No C264990
the sd card holder is C114218
and the flat flex is 100mm (any longer doesn't work for me) is C45200
 
Back
Top