Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 18 of 18

Thread: Teensy 4 SD card and WIZ820io not playing well together

  1. #1

    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 )

    Click image for larger version. 

Name:	IMG_20200911_141601.jpg 
Views:	11 
Size:	192.0 KB 
ID:	21698
    Click image for larger version. 

Name:	IMG_20200911_141605.jpg 
Views:	11 
Size:	163.5 KB 
ID:	21697

    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 = 10.0.0.2
    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 = 0.0.0.0
    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 = 0.0.0.0
    Ethernet cable is not connected
    Init SD.
    SD Card initialised OK
    Size = 32034 MB
    Done.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,612
    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.

  3. #3
    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.

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,612
    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...

  5. #5
    Senior Member
    Join Date
    Nov 2015
    Location
    Cold hollow VT
    Posts
    166
    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.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,642
    I tested on this known-good hardware.

    Click image for larger version. 

Name:	DSC_1047_web.jpg 
Views:	6 
Size:	167.0 KB 
ID:	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.

  7. #7
    Quote Originally Posted by KurtE View Post
    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.

  8. #8
    Quote Originally Posted by grease_lighting View Post
    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.

  9. #9
    Quote Originally Posted by PaulStoffregen View Post
    I tested on this known-good hardware.

    Click image for larger version. 

Name:	DSC_1047_web.jpg 
Views:	6 
Size:	167.0 KB 
ID:	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!

  10. #10
    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.

  11. #11
    Quote Originally Posted by winchymatt View Post
    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 ?

  12. #12
    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

    Click image for larger version. 

Name:	IMG_20200916_094740.jpg 
Views:	10 
Size:	175.7 KB 
ID:	21746

    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.
    Ethernet cable is not connected
    My IP Address = 10.0.0.2
    Done.
    Without SD card in:
    Code:
    Start.
    Init SD.
    SD Card initialisation failed!Init ETH.
    Ethernet shield was not found
    My IP Address = 0.0.0.0
    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

  13. #13
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,583
    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
    Click image for larger version. 

Name:	t4esd.jpg 
Views:	11 
Size:	106.0 KB 
ID:	21749
    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 by manitou; 09-16-2020 at 03:41 PM.

  14. #14
    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.

    Click image for larger version. 

Name:	IMG_20200916_160928.jpg 
Views:	6 
Size:	76.1 KB 
ID:	21748

  15. #15
    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

  16. #16
    Quote Originally Posted by wangnick View Post
    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.

  17. #17
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Quote Originally Posted by winchymatt View Post
    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
    Click image for larger version. 

Name:	20200924_182417.jpg 
Views:	10 
Size:	140.1 KB 
ID:	21846Click image for larger version. 

Name:	20200924_182410.jpg 
Views:	7 
Size:	132.9 KB 
ID:	21847

    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

  18. #18
    Quote Originally Posted by Dink1000 View Post
    i made this using some parts off LCSC and a pcb i designed
    Click image for larger version. 

Name:	20200924_182417.jpg 
Views:	10 
Size:	140.1 KB 
ID:	21846Click image for larger version. 

Name:	20200924_182410.jpg 
Views:	7 
Size:	132.9 KB 
ID:	21847

    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
    That's a nice solution, I'm going to look at doing something similar but with a really short cable straight down to a board mounted under the teensy 👍

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •