T3.1 and SD card CS pin

Status
Not open for further replies.

Epyon

Well-known member
Didn't find something about this on the forum, but I have a strange bug with the T3.1 and the SD library (perhaps because of the latest Teensyduino update?). I'm using an Arduino ethernet shield connected to a Teensy 3.1, with the CS for the SD card (pin 4 on the shield) wired to pin 9 on the T3.1. I can't use the SD card however, it fails to initialize. With exactly the same wiring on a T3, it works perfectly. By manually setting pin 9 low and high on the T3.1, it works too.

Is there perhaps a problem with the CS pin and the SD library on the T3.1? Connecting to the ethernet works (CS pin 10).
 
Are you doing a
Code:
card.init(SPI_HALF_SPEED, SD_CS)
where SD_CS is 9?

Also try and add a
Code:
pinMode(SD_CS,OUTPUT);
digitalWriteFast(SD_CS,HIGH);

At the start of the Setup.
 
Are you doing a
Code:
card.init(SPI_HALF_SPEED, SD_CS)
where SD_CS is 9?
I'm using the standard SD library, not the SDFat.

Also try and add a
Code:
pinMode(SD_CS,OUTPUT);
digitalWriteFast(SD_CS,HIGH);

At the start of the Setup.
No effect. This is the codesample I use for testing. Works perfect on T3 but not on T3.1 :( .

Code:
#include <SD.h>

File root;

const int chipSelect = 9;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

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

  root = SD.open("/");
  
  printDirectory(root, 0);
  
  Serial.println("done!");
}

void loop()
{
  // nothing happens after setup finishes.
}

Note: printDirectory() not included in above code.
 
Try

Code:
#include <SD.h>

#define SDCS 9

Sd2Card card;

void setup() {

pinMode(SDCS, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(115200);

if (!card.init(SPI_HALF_SPEED, SDCS)) {
	 Serial.println("Failed to Init SD CARD");
 } else {
        Serial.println("SD CARD Inited Successfully");
}
}

void loop(){}

The SD Library begin does a Card Init, a volumn init and a root open in one hit, so we need to piecemeal it to rule out that it's not the volumn init or root init failing.

Also try a different pin for the CS.
 
Try

Code:
#include <SD.h>

#define SDCS 9

Sd2Card card;

void setup() {

pinMode(SDCS, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(115200);

if (!card.init(SPI_HALF_SPEED, SDCS)) {
	 Serial.println("Failed to Init SD CARD");
 } else {
        Serial.println("SD CARD Inited Successfully");
}
}

void loop(){}

The SD Library begin does a Card Init, a volumn init and a root open in one hit, so we need to piecemeal it to rule out that it's not the volumn init or root init failing.

Also try a different pin for the CS.
Okay, that seems to work. SD card gets initiated. However, when I add this code to the previous sketch, it still fails during SD.Begin(chipSelect). :(
 
Ok, then could well mean it's not a Hardware fault but something in software.

Lets up the ante and add some extra code.

Try

Code:
#include <SD.h>

#define SDCS 9

Sd2Card card;
SdVolume volume;
SdFile root;

void setup() {

pinMode(SDCS, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(115200);

if (!card.init(SPI_HALF_SPEED, SDCS)) {
	 Serial.println("Failed to Init SD CARD");
 } else {
        Serial.println("SD CARD Inited Successfully");
        if (!volume.init(card)) {
		 Serial.println("Failed to get SD Volume");
	 } else {
                 Serial.println("Volume Initilized OK Size");
		 uint32_t volumesize;
		 volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
		 volumesize *= volume.clusterCount();       // we'll have a lot of clusters
		 volumesize *= 512;
		 volumesize /= 1024;
		 volumesize /= 1024;
		 Serial.println(volumesize);
                 if(!root.openRoot(volume)) {
                     Serial.println("Failed to open root, Are you formated as a Fat16 partition?");
                 } else {
                      Serial.println("Root opened OK");
                 }
	 }
}
}

void loop(){}
 
I'm afraid it was a lucky shot and there's is something wrong with the hardware. I wired up my scope to the CLK, MISO en MOSI pins and got some strange results.

First, this is the standard Ethernet DHCP address printer sketch (which runs perfect):
TEK00074.PNG

This is the SD sketch which you posted:
TEK00073.PNG

Remark how the CLK line goes totally bonkers, and the MISO is pulled into an undefined state. Very strange considering how SPI communication when running the Ethernet sketch is perfect. Perhaps some bug in the SD library?
 
Can you try one more thing.

I've added a MUX setting on pin 9 to the code. Just incase.

Can you probe and trigger on the CS line as well, see if changes.

Try this code
Code:
#include <SD.h>

#define SDCS 9

Sd2Card card;
SdVolume volume;
SdFile root;

void setup() {

pinMode(SDCS, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(115200);

CORE_PIN9_CONFIG = PORT_PCR_MUX(2);

if (!card.init(SPI_HALF_SPEED, SDCS)) {
	 Serial.println("Failed to Init SD CARD");
 } else {
        Serial.println("SD CARD Inited Successfully");
        if (!volume.init(card)) {
		 Serial.println("Failed to get SD Volume");
	 } else {
                 Serial.println("Volume Initilized OK Size");
		 uint32_t volumesize;
		 volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
		 volumesize *= volume.clusterCount();       // we'll have a lot of clusters
		 volumesize *= 512;
		 volumesize /= 1024;
		 volumesize /= 1024;
		 Serial.println(volumesize);
                 if(!root.openRoot(volume)) {
                     Serial.println("Failed to open root, Are you formated as a Fat16 partition?");
                 } else {
                      Serial.println("Root opened OK");
                 }
	 }
}
}

void loop(){}
 
Can you try one more thing.

I've added a MUX setting on pin 9 to the code. Just incase.

Can you probe and trigger on the CS line as well, see if changes.
Hello again. I waited for the release of the Teensyloader 1.19 in the hope it would fix this problem, but alas.

I ran your code, but with the same result. See scope images below. The probe numbers are as follows:
1: MISO
2: MOSI
3: CLK
4: CS

This is your last sketch running, with scale set to 400ms/div.
SD_400ms.PNG

This is the standard Ethernet sketch running on the same time scale.
ETH_400ms.PNG

This is your sketch, but now on 10ms/div.
SD_10ms.PNG

Again the Ethernet sketch, but also on 10ms/div.
ETH_10ms.PNG

Finally, your sketch zoomed in on 10µs/div.
SD_10us.PNG

And a little more on 4µs/div.
SD_4us.PNG

The MISO line really behaves awkward in the SD sketches, while when running the Ethernet sketch it behaves consistent. It also stays at a pretty low 2V, while on the Ethernet sketch it's at 3.3V.

The serial output of your sketch says:
Code:
SD CARD Inited Successfully
Failed to get SD Volume

I've tested with other SD cards, but results remain the same or even worse (Failed to Init SD CARD).
 
Last edited:
The attachments are all broken except for the last picture.

But I think I may have found your issue.

Can you probe both pin 2 (red box) and pin 4 (Yellow box) of the small SOT23-5 chips next to the SD card. See what you are getting.

I think the issue is that this Arduino Board is 5v. So you are supplying 5v. But these SN74LVC1G125DCKR chips are line level shifters that shift 5v to 3v. Looking at the datasheet I can see that if Vcc is 5v then it thinks a High is 0.7 x Vcc which equates to 3.5v for a high, Teensy will only be outputting 3.3v so it could be that this buffer is just not working properly as it only sometimes sees a high, thus mangling the signal to the SD card.

If you feel confident you could short out pin 2 to 4 on each of these chips and see what happens. Just note that you should then NOT use this shield on anything other than the Teensy.

Probe.jpg
 
The Arduino Ethernet shield regulates its own 3.3V from the 5V rail, so everything should work at 3.3V levels. The level shifter itself is also powered by the 3.3V rail so it should accept 0.7*3.3V.

Anyway, I still gave it a shot, with some strange results but no solution.

In this figure, line 1 is CLK, line 2 is MOSI before the level shifter, line 3 is MOSI after the level shifter, line 4 is the CS. I'm running your sketch here.
Both MOSI lines are at 3.3V, but no communication seems to happen.
TEK00001.PNG

This is the same sketch and probe configuration, but with the level shifter bridged (both MOSI lines connected).
TEK00003.PNG

This is again the same sketch and probe configuration, but now with line 3 connected to MISO.
There doesn't really seem to be going data from the SD card to the Teensy, and even when it does it's below 2V.
TEK00005.PNG

Again same sketch and config, but now with line 2 connected to MOSI before the level shifter and the level shifter unbridged again.
Same behavior of the MISO line as the previous test.
TEK00006.PNG

Same as previous figure, but now with line 2 connected to MOSI after the level shifter.
TEK00007.PNG

Same as previous figure, but now with line 2 connected to MISO and line 3 to MOSI before the level shifter.
There is some communication from the SD card to the Teensy here, but it's below 2V.
TEK00009.PNG

For comparison, the Ethernet sketch with the same probe config as previous figure.
Both MISO and MOSI lines are at 3.3V.
TEK00010.PNG

I've tried with different shields and SD cards, but no effect. Only thing I haven't tried is a different Teensy, but it would strike me as odd if the problem were the Teensy hardware, because it runs the Ethernet sketch just fine.
 
Curiouser and curiouser. Do you have a micro sd card socket or sd card socket that you can breadboard or ratnest.

Also, try changing the teensy if you have a spare (as you sugguested)

As for the shield, if its a standard arduino ethernet shield, then the arduino side will be 5v, even if the board has a 3v3 regulator on board. Thats to power tge Sd card and wiznet.

Another thing to try is lower the speed of the spi bus, maybe the sd card can't cope.
 
This may be off topic, but earlier when I was trying out a couple of the Adafruit TFT displays (1.8" and 2.8" with touch), they both have SD card hardware on them. On both of them, the example sketch to show a bitmap on the display failed in the SD card init (they did the all in one init). I was able to make them both work when I switched the apps to using the SDFat library.

I kept meaning to come back and figure out why the SD library failed, maybe this is a good excuse to dig into again.

Kurt
 
As a followup, I verified again that I could use the Quickstart example program that is part of SDFAT and it worked fine and showed the two files on my SD card. I then tried the cardinfo program part of the SD library, which fails in the volume.init() call.

The Init all is failing when it calls through sd2card to read a block, the function: Sd2Card::readData
In that function:
Code:
  if (!inBlock_ || block != block_ || offset < offset_) {
    block_ = block;
    // use address if not SDHC card
    if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
    if (cardCommand(CMD17, block)) {
      error(SD_CARD_ERROR_CMD17);
      goto fail;
    }
    if (!waitStartBlock()) {
      goto fail;
    }
It is calling off to send CMD17, which returns, but the function WaitStartBlock fails and it setting the error: SD_CARD_ERROR_READ. Still doing a little tracing on this.

I have been playing around some with the hardware SPI, but things I still throw me, at times is knowing when I can change things in the MCR register. Example: in the functions:
Code:
static  uint8_t spiRec() {
  SPI0_MCR |= SPI_MCR_CLR_RXF;
  SPI0_SR = SPI_SR_TCF;
  SPI0_PUSHR = 0xFF;
  while (!(SPI0_SR & SPI_SR_TCF)) {}
  return SPI0_POPR;
}

static void spiSend(uint8_t b) {
  SPI0_MCR |= SPI_MCR_CLR_RXF;
  SPI0_SR = SPI_SR_TCF;
  SPI0_PUSHR = b;
  while (!(SPI0_SR & SPI_SR_TCF)) {}
}
They update the state of the MCR register, but the doc says, you can only change the HALT and MDIS bits while the module is in a running state. Still trying to figure some of this stuff out.

Kurt
 
I got it to work for me :D

I have several other changes I tried, but finally found that the clock speed on SD was a lot faster than it was when I try SDFAT library. Earlier I wondered about some code, so, I changed it and now the Example App CardInfo works. I verified the change on another machine running Ubuntu 14.04 with a fresh copy of Arduino 1.05 and Teensyduino 1.19. Without the change it failed, with the change it worked.

The change is in the file <arduino install>/libraries/SD/Utility/Sd2Card.cpp
Look for the function: static void spiInit(uint8_t spiRate) {

Look at the switch statement: switch (spiRate/2)

The /2 made no sense as the comments above talked about the different rates, so simply change that line to: switch (spiRate)

And now the program works.

Kurt
 
Your scope output looks a lot like a problem I was having with the SD card (standard SD lib) and Ethernet (both using paul's sd/wiznet board) working together on 3.1. I finally got it to work by starting Ethernet first, then SD.....I always thought it was a bit of a hack as it isn't supposed to matter. Perhaps I'll try your change to my current code to see if I can break anything, and then to the older version to see if I can get it to work.

Mike
 
As I mentioned in my previous post on this thread, when I first tried using SD library on two different Adafruit displays, it failed on both of them. Neither the example cardinfo nor the Adafruit example to display bitmaps on the screen would work. When I looked at the logic Analyzer, I was finding that nothing was being output or input. But if I first ran the SDFat quickstart example it would work, and if I then reprogrammed the Teensy (without power cycle) and load the cardinfo sketch, the Logic Analyzer would then see stuff on the SPI pins, which was weird, but I noticed that the clock pulses were getting screwed up. I also checked the pulse width and noticed that SD sketch the pulses were much shorter... So I then looked at sources and found:
Code:
static void spiInit(uint8_t spiRate) {
  // spiRate = 0 : 24 or 12 Mbit/sec
  // spiRate = 1 : 12 or 6 Mbit/sec
  // spiRate = 2 : 6 or 3 Mbit/sec
  // spiRate = 3 : 4 or 2.0 Mbit/sec
  // spiRate = 4 : 3 or 1.5 Mbit/sec
  // spiRate = 5 : 250 kbit/sec
  // spiRate = 6 : 125 kbit/sec
  uint32_t ctar, ctar0, ctar1;
  switch (spiRate/2) {
    // 1/2 speed
    case 0: ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
    // 1/4 speed
    case 1: ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
    // 1/8 speed
    case 2: ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); break;
    // 1/12 speed
    case 3: ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2); break;
    // 1/16 speed
    case 4: ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3); break;
#if F_BUS == 48000000
    case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5); break;
    default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
#elif F_BUS == 24000000
    case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); break;
    default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5);
#else
#error "MK20DX128 bus frequency must be 48 or 24 MHz"
#endif
  }
...
The /2 felt wrong, so I removed (We pass in a value of 6). When I removed the /2, cardinfo started to work, likewise the adafruit example worked as well... Again not sure if that is the right fix, but it made it work on my machine.

Kurt
 
I got it to work for me :D

I have several other changes I tried, but finally found that the clock speed on SD was a lot faster than it was when I try SDFAT library. Earlier I wondered about some code, so, I changed it and now the Example App CardInfo works. I verified the change on another machine running Ubuntu 14.04 with a fresh copy of Arduino 1.05 and Teensyduino 1.19. Without the change it failed, with the change it worked.

The change is in the file <arduino install>/libraries/SD/Utility/Sd2Card.cpp
Look for the function: static void spiInit(uint8_t spiRate) {

Look at the switch statement: switch (spiRate/2)

The /2 made no sense as the comments above talked about the different rates, so simply change that line to: switch (spiRate)

And now the program works.

Kurt
Very strangely, this worked for me too, somewhat. When I first use the Ethernet chip (Ethernet.begin()) and after that the SD card (card.init(spiSpeed, chipSelect)) I can read the card contents. I can't write to it (it's not write protected) or read individual files though.

Curiouser and curiouser. Do you have a micro sd card socket or sd card socket that you can breadboard or ratnest.

Also, try changing the teensy if you have a spare (as you sugguested)

As for the shield, if its a standard arduino ethernet shield, then the arduino side will be 5v, even if the board has a 3v3 regulator on board. Thats to power tge Sd card and wiznet.

Another thing to try is lower the speed of the spi bus, maybe the sd card can't cope.
The Wiznet chip and SD card are actually 3.3V parts. There is only a 3.3V power rail on the Arduino Ethernet shield, the 5V input is only connected to the 3.3V regulator.

I modified the SD library a bit like Kurt did, and it did show some improvement (I can now list the files on the SD card) but it's still nothing really useful.

I tried with another Teensy and another Ethernet shield, but results stayed the same.

I have a Sparkfun SD shield laying somewhere around, I'll try with that if I find it.
 
Status
Not open for further replies.
Back
Top