Teensy 3.6, after Reset SD Card does not always initialize.

Hmmm, I see I made a lot of posts on this thread. Since then, I have been working on other projects and not using SD cards on my T3.6 boards, so I've had no follow-up.

Frank, what size SD card are you using? Have you tried using several different cards, and especially maybe with smaller memory than this card? From what Bill Greiman has said in the past, not all cards are created equal, and some may be pirated knock-offs, even if they're labelled as from an official manufacturer. You should look at the info on the card using whatever means you can, and see if it looks at all suspicious.
 
In assembling Franks' Teensy64 [ C64 emulation system ] on T_3.6 I have seen this with my current SD card.

Debug spew says ' SD INIT ... ' and just sits.

I pull USB/power and then it typically comes up running - the card has always worked after that and still works as expected without having removed it. It did this the first time I put this card in the new build having just used the SD Formatter EXE, and a couple of times since. Frank says this mirrors his experience on this system and also in general use outside his Teensy64 emulator.
 
BTW, one thing I recall is that there are 2 different sketches in the SD library examples folder, CardInfo.ino and listfiles.ino, and the former never worked properly for me, going all the way back to Arduino chips and IDE version 1.0x and still would not work properly with T3.x modules. Namely, CardInfo.ino would crash at statement: root.ls(LS_R | LS_DATE | LS_SIZE);

On removing that statement, I could get the card info to display ok and without the program hanging up.

Another thing I recall is that, if I would try to initialize the card more than once it would hang the 2nd time, so I moved the card and volume init() code into setup(), and only ever called it one time.
 
It may also have do with the implementation od sdhc diriver (I assume we use onboard T3.6 uSD card)

Stange enough, I have recently been playing with uSD latency and wrote to disk at high speed. For this I used the PC to check buffer overflow etc.
I could remove disk from teensy put it into PC and back to teensy, modified/reloaded program, and do this multiple times, without any problem with initializing the sdhc. I did this even at full speed (by mistake of 60 MHz and not 400 kHz as by standard design).
OK, I do not use the SD library, but all our sdhc init routines are similar (they are comming from the same origin)
 
Another thing I recall is that, if I would try to initialize the card more than once it would hang the 2nd time, so I moved the card and volume init() code into setup(), and only ever called it one time.

Hm, might be something like this. If have it in setup() - but the card does know nothing about a teensy-reset.. there's no reset pin, and it is in the same state as before after a Teensy-reset. So, it makes no difference.
 
Ok.. I just found something..not sure if this is the problem.
The specification says, a pullup is needed (at least) on CS.
SDHC_ReleaseGPIO() disables all pins, so no pullup is present.
Various schematics show pullups on D0, D1, D2 and CMD. I'll modify the code to "input with pullup" and look what happens..

Edit: Regardless if this is part of my init - problem, the pullups are required in any case:
https://github.com/PaulStoffregen/SD/pull/9/files#diff-057aac1c8879c90fc49c6e53f75d4b59
 
Last edited:
Good catch. Does SdFat-beta have the same issue?

uSDFS has this type of code
Code:
static void sdhc_InitGPIO(Word init)
{  
  PORTE_PCR0 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D1  */
  PORTE_PCR1 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D0  */
  PORTE_PCR2 = init & (PORT_PCR_MUX(4) | PORT_PCR_DSE);                                /* SDHC.CLK */
  PORTE_PCR3 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.CMD */
  PORTE_PCR4 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D3  */
  PORTE_PCR5 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D2  */  
}

and is called with
Code:
	// De-Init GPIO
	sdhc_InitGPIO(0);

	// Set the SDHC default baud rate
	sdhc_SetBaudrate(kbaudrate);

	// Init GPIO
	sdhc_InitGPIO(0xFFFF);
 
Good find, Frank. It sounds like, for proper reset, the SD spec wants a pullup on CS, I am assuming, at the time when power is applied to the card. Is that how you interpret it? In which case, the only way to be certain is to have an "external" pullup-R on CS, as software can never guarantee it.

Could this have always been the problem with flakey SD operation going back to day-1 of Arduino?

EDIT: Answer to my own question = maybe not. I went to the following page and downloaded the "Physical Layer Simplified Specification" doco. On page 11, it says there is an internal 50K pullup on CS.
https://www.sdcard.org/downloads/pls/

BTW, I also looked at a bunch of SD interface schematics on google, and many of them show a pullup-R on CS and many do not, so no concensus there.
 
Last edited:
uSDFS has this type of code
Code:
static void sdhc_InitGPIO(Word init)
{  
  PORTE_PCR0 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D1  */
  PORTE_PCR1 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D0  */
  PORTE_PCR2 = init & (PORT_PCR_MUX(4) | PORT_PCR_DSE);                                /* SDHC.CLK */
  PORTE_PCR3 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.CMD */
  PORTE_PCR4 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D3  */
  PORTE_PCR5 = init & (PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE);    /* SDHC.D2  */  
}
This disables the pins and sets them to high-z state, too. I'd change this.
I've have it running for hours now, and the problem is gone..


@Oric_dan: This lib is a little different from others which use SPI only. Usually, on Ardino you don't change the pinmode for the card-cs to "floating". So, for SPI-access a problem can only occur at power-up. But most SD-adapters have one or more pullups. The audio-shield has this pullup, too.
The same can occur with the T3.6, but the main problem here is (I think), that the pins switch to a high-impendance state during a short time when init is called, which means they are floating for a short time. So their level is unpredictable and the card can, for example, interpret cs as low. Esp, if there are near traces which can influence the floating pins.
The T3.5 and T3.6 don't have a pull-up.
Whatever it exactly is, it solved my problem :)

@tni: I'll take a look in the next days..
edit: the code is somewhat similar:
Code:
[TABLE="class: highlight tab-size js-file-line-container"]
[TR]
[TD="class: blob-code blob-code-inner js-file-line"]static void enableGPIO(bool enable) {
  const uint32_t PORT_CLK = PORT_PCR_MUX(4) | PORT_PCR_DSE;
  const uint32_t PORT_CMD_DATA = PORT_CLK | PORT_PCR_PS | PORT_PCR_PE;

  PORTE_PCR0 = enable ? PORT_CMD_DATA : 0;  // SDHC_D1
  PORTE_PCR1 = enable ? PORT_CMD_DATA : 0;  // SDHC_D0
  PORTE_PCR2 = enable ? PORT_CLK : 0;       // SDHC_CLK
  PORTE_PCR3 = enable ? PORT_CMD_DATA : 0;  // SDHC_CMD
  PORTE_PCR4 = enable ? PORT_CMD_DATA : 0;  // SDHC_D3
  PORTE_PCR5 = enable ? PORT_CMD_DATA : 0;  // SDHC_D2
}[/TD]
[/TR]
[TR]
[/TR]
[/TABLE]
The code of SD.h does way more between disable and enable the GPIOs and spends longer time with floating pins than WMXZs' and Bills' code. So the problem might be more visible in SD.h but exists in all versions (SD.h is patched now, please DL the new version from Pauls` Github)
 
Last edited:
This disables the pins and sets them to high-z state, too. I'd change this.

OK, I see what you mean. Will change
from
Code:
// De-Init GPIO
	sdhc_InitGPIO(0);
to
Code:
// De-Init GPIO
	sdhc_InitGPIO(3);
which should keep pull-up in place
Mux will be then default (analog)
 
Last edited:
problem persists with current libraries

I am in the process of moving a big project from various hardware to Teensys. I have a Teensy 3.5 that has no trouble with the cardinfo example from the SD library, but when I use near-identical code in my own program (attached), the code hangs somewhere inside the Sd2Card::init(speed, pin) routine.
What you'll see in my code are the lines
Code:
    TellWindows("Initializing SD card...", 101);

    if (!TheCard.init(SPI_HALF_SPEED, chipSelect))
      { TellWindows("Card failed, or not present", 102, whAttention); 
        return Result;
       }
    else
      { TellWindows("card exists, wiring OK", 103); }
where TellWindows is essentially a cover for Serial.print. What happens every time is that message #101 appears, then silence. In particular, neither message #102 nor #103 appears.

Any suggestions will be appreciated.
 

Attachments

  • BaseStation.ino
    50 KB · Views: 125
I have done limited further experimentation, and the SD library works only inconsistently for me. I believe that there is some sort of timing issue involved, but the library code is, as others on this thread have remarked, intimidatingly complex. In my experiments I have used one 16GB uSD card and one 2GB uSD card, with no difference in the results. The test bed is a Teensy 3.5 running on USB power.
The example programs cardinfo, Files, lstFiles, and ReadWrite execute properly.
I have slightly changed the program that causes a crash within the library routines, so I here repeat the key section. Lines 393-408 of my code are
Code:
   TellWindows("Initializing SD card...", 101);

    if (!TheCard.init(SPI_HALF_SPEED, chipSelect))
      { TellWindows("Card failed, or not present", 102, whAttention); 
        return Result;
      }
    else
      { TellWindows("card exists, wiring OK", 103); }
    
    TellWindows("Initializing SD volume...", 104);
    if (!TheVolume.init(TheCard))
      { TellWindows("Could not find FAT16/FAT32 partition.", 105, whAttention); 
        return Result;
      }
    printf(Message, "FAT%d volume found", TheVolume.fatType());
    TellWindows(Message, 106);
where TellWindows is little more than a wrapper for Serial.println. The output produced by this code is
Code:
  0 101 Initializing SD card...
  0 103 card exists, wiring OK
  0 104 Initializing SD volume..
and that's it. The Teensy is then unresponsive until it is reset.
I understand that those responsible for the Teensy libraries have a long list of projects to work on, and I am not asking to jump the queue. It would help me, however, if I could get some idea of when the SD library is likely to be attended to.
 

Attachments

  • BaseStation.ino
    52 KB · Views: 134
I can't say that yet. I need to do some more testing. All I can say now is that I can demonstrate in a 10-line program that using printf instead of sprintf will be accepted by the compiler, but then it will hang at run time.
I need to replace a lot of printfs with sprintfs. I will be back with a more definitive word in a day or two.
 
I can't say that yet. I need to do some more testing. All I can say now is that I can demonstrate in a 10-line program that using printf instead of sprintf will be accepted by the compiler, but then it will hang at run time.
I need to replace a lot of printfs with sprintfs. I will be back with a more definitive word in a day or two.

Okay - I was hoping False Alarm meant all was well.

You might try some delay(500) in setup() before doing the begin on the SD?
 
Okay - I was hoping False Alarm meant all was well.
I wrote in haste; by "false alarm" I meant that no one should drop other projects and come running to my aid. Not yet, anyway.

You might try some delay(500) in setup() before doing the begin on the SD?
My setup already has a delay before I start organizing the SD. In pseudocode, it is
Code:
Serial.begin(9600);
delay(1000);

[FONT=Comic Sans MS](set some pin modes)
(read some pins)
(organize two display units)
(organize the SD)
(other stuff)[/FONT]
As of late last night, it was never getting back from organizing the SD, but I no longer think (erroneously) that the problem must be in the SD library.
 
I was doing SD with ILI9341 display with touch to work - and others were having trouble … perhaps order matters? It seems others saw it work using my sketch. Posts on this will be 2 years back - perhaps on an XPT2046 touchscreen thread - but that would predate T_3.5 and possibly a test using the SD on the display.

Indeed SD can be finicky - but seems to have a path to success. Finding a simple sample showing a problem if possible would be the first step.
 
I started by copying the code from one of the examples, then expanded what I thought was the result of the top-level call to try to track down my problem. Your observation suggests that I got lost in the SD library's forest of #defines, and that the true result of the top-level call is, as you say, one better adapted to the Teensy. I'll simplify. Thanks.
 
apparent success

@UhClem's observation seems to have done the trick. I had one hang earlier today, but I can't reproduce it. The system being redone onto Teensies runs for years at a time, so I can't yet say that I am sure that the current code (mine and that of the libraries) is truly solid, but for now I am content:). Thanks to those who chipped in comments.
 
Back
Top