Question on the correct usage of the SD Card on Teensy 4.1

Status
Not open for further replies.
Hi All,

I have this RunCPM project which I build on the Teensy 3.5 and 3.6 using the SdFatSdio.
This is what I done and worked since the beginning when I got the 3.5 and never changed it.
However it doesn't seem to be working for the 4.1.
On the 4.0 I used SdFat only, as I had the SD connected to the "Audio Shield Rev.D".
I am using Greinman's SdFat library.
Is the 4.1 not supported on Greinman's lib? Should I use SdFat for the 4.1 as well? Maybe change something in SdFat lib?
Thanks in advance for any clue here.

Thanks,
Marcelo.
 
Yes, this is very unfortunate.
I have a lot of code, developed for T3.6, which uses "regular" SdFat with SdFatSdioEX objects.
Now I can't use it with T4.1, because SdFat Beta does not provide SdFatSdioEX objects and "regular" SdFat does not support T4.1.
 
Yes, this is very unfortunate.
I have a lot of code, developed for T3.6, which uses "regular" SdFat with SdFatSdioEX objects.
Now I can't use it with T4.1, because SdFat Beta does not provide SdFatSdioEX objects and "regular" SdFat does not support T4.1.

Yes. I understand Greiman is overwhelmed, so I hope we do get a solution for this.
 
The solution I've come up with is to rename the SdFat-beta library from SdFat to SdFat-beta: in library.properties change name=SdFat to name=SdFat-beta, rename src/SdFat.h to src/SdFat-beta.h, and change the library directory name to SdFat-beta. That way, I have both old SdFat library and the new SdFat-beta library available. Then you can do something like this:
Code:
#ifdef ARDUINO_TEENSY41
#include <SdFat-beta.h>
#else
#include <StFat.h>
#endif
RunCPM with a Teensy 4.1 and working SDIO is... verrrry nice indeed. :)
 
The solution I've come up with is to rename the SdFat-beta library from SdFat to SdFat-beta: in library.properties change name=SdFat to name=SdFat-beta, rename src/SdFat.h to src/SdFat-beta.h, and change the library directory name to SdFat-beta. That way, I have both old SdFat library and the new SdFat-beta library available. Then you can do something like this:
Code:
#ifdef ARDUINO_TEENSY41
#include <SdFat-beta.h>
#else
#include <StFat.h>
#endif
RunCPM with a Teensy 4.1 and working SDIO is... verrrry nice indeed. :)

Thanks .. this is what I thought about doing ... and I will probably do, but this adds some complication to newcomers, like having to download a lib, rename things, etc.
How did you initialize the SD card? I do not use SdFatSdioEx.
For the 3.5 and 3.6 I use SdFatSdio (is there an advantage on using SdFatSdioEx?)
For the 3.5 and 3.6 I use simply sd.begin(), but for the 4.1 I am not sure what to use.

Thanks,
Marcelo.
 
How did you initialize the SD card? I do not use SdFatSdioEx.
in void setup() { }
Code:
  if (!sd.begin(SdioConfig(FIFO_SDIO))) { // SdFat.h Ver 2.0.0 Beta
    Serial.println("m.SD initialization failed!");
  } else {
    Serial.println("m.SD initialization OK");
  }
 
Cool, thanks.

Also ... I am using this "dir_t" for reading directories. That seems to "not name a type" on the beta.
No idea what it was replaced with.
 
Thanks .. this is what I thought about doing ... and I will probably do, but this adds some complication to newcomers, like having to download a lib, rename things, etc.
How did you initialize the SD card? I do not use SdFatSdioEx.
For the 3.5 and 3.6 I use SdFatSdio (is there an advantage on using SdFatSdioEx?)
For the 3.5 and 3.6 I use simply sd.begin(), but for the 4.1 I am not sure what to use.

For both the T4.0 and the T4.1, I used SdFat SD;. It worked on the T4.0 and I really never thought of playing with it when I switched over to the 4.1.

In the SD.begin, I used SD.begin(SdioConfig(FIFO_SDIO)).
 
Cool, thanks.

Also ... I am using this "dir_t" for reading directories. That seems to "not name a type" on the beta.
No idea what it was replaced with.

Oh right, forgot about all those internal renaming bits... One sec... dir_t became DirFat_t.

There was also a function that went private (SD.vwd()) that was used in _sys_renamefile in abstraction_arduino.h. That had me going for a bit until I figured out that if (f.rename(SD.vwd(), (char*)newname)) { became if (f.rename((char*)newname)) {.
 
Awesome!!! ... I will try all this tonight.
I really hope 4.1 support gets migrated onto the standard SdFat. Would make things much easier.
 
If you don't mind, can you zip the changes and send over? I did the changes above and am still getting some errors when compiling.
I think I must not create SD as :
SdFat SD;
When using the 4.1?
 
Awesome!!! ... I will try all this tonight.
I think it took me about an hour of skullwork to get things migrated over to SdFat-beta before I got my T4.1 and plugged it in. The increase in speed is very, very noticeable.

On the T4.0 with the uSD hooked up to SPI, it took 4m10s to assemble and link SYSLIB4.5.

On the T4.1 with the onboard SDIO uSD, that dropped to 1m40s.

And that's just using the SdFat class. Now that you've nudged my elbow, I may just have to look into SdFatSdio...

I really hope 4.1 support gets migrated onto the standard SdFat. Would make things much easier.

It would make things easier, but I'm not holding my breath. I don't see it happening; but I'd love to be proved wrong!
 
Try this for a quick test:
Code:
//============================================================================
// SdFat version 2.0.0 BETA ONLY
//============================================================================
#include <SdFat.h> // SdFat V "2.0.0"
const char *SDFAT_ver = SD_FAT_VERSION;

// Use built-in SD for SPI modes on Teensy 3.5/3.6.
// Teensy 4.0 use first SPI port.
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SS;
#else  // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif  // SDCARD_SS_PIN

// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 3

SdFat sd; // SD
// SdFat SD;

// The file to be parsed.
File m_pSource;

const int DIR_max = 150; // [# of Directory - max]
const int max_DIR_name_lenght = 100;
char CURDIRname[max_DIR_name_lenght] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Elements with missing values will be initialized to 0;
uint32_t DIRcount = 1; // COUNT of all DIRs on SD CARD
char DIR_list_array[DIR_max][max_DIR_name_lenght]; // [# of DIRs max][max DIR name lenght];

// uint32_t TOTAL_PMF_FILE_counter = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400); // Teensy ignores this and use full USB speed:  T3.x USB 1.1/Full-Speed: 12 Mbps, T4.x Hi-Speed: 480 Mbps.
  byte i = 0;
  while (!Serial && millis() < 5000) { // wait for Arduino Serial Monitor
  }
  if (!sd.begin(SdioConfig(FIFO_SDIO))) { // SdFat.h Ver 2.0.0 Beta
    Serial.println("m.SD initialization failed!");
  } else {
    Serial.println("m.SD initialization OK");
    LISTDIRs();
    m_pSource = sd.open("/"); // ROOT
    PrintFiles(m_pSource);
    m_pSource.close();
  }

#if defined(SdFat_h)
  if (!strcmp("2.0.0", SDFAT_ver)) { // ver 2.0.0
    Serial.print( "SdFat version "), Serial.println( SD_FAT_VERSION );
  } else if ((SDFAT_ver[0] == '2') && (SDFAT_ver[1] == '.')) { // ver 2.
    Serial.println("Warning: MTP Library was only tested on SdFat Version 2.0.0 beta");
    Serial.print("SdFat Version currently installed "), Serial.println( SD_FAT_VERSION );
  } else { // ver 1
    Serial.print("Wrong SdFat Version "), Serial.println( SD_FAT_VERSION );
  }
#endif

}

void loop() {
  // put your main code here, to run repeatedly:

}

// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
//============================================================================
//------------ LIST ALL DIRs ON SD CARD & SAVE IN DIR_list_array -------------
//============================================================================
void LISTDIRs() {
  Serial.println("\t**List Directories**");
  m_pSource = sd.open("/"); // ROOT
  char dirname[max_DIR_name_lenght]; // SDFAT // max_DIR_name_lenght
  if (m_pSource.isDirectory()) {
    strcpy(DIR_list_array[DIRcount], "/"); // array

    Serial.print("ROOT# ");
    Serial.print(DIRcount);
    Serial.print("\t");
    Serial.println(DIR_list_array[DIRcount]); // SDFAT LIB
    DIRcount++;
  }
  while (true) {
    File DIR = m_pSource.openNextFile();

    if (! DIR) {
      // no more files
      Serial.println("\t **no more Directories** ");
      DIR.close();
      break;
    }
    DIR.getName(dirname, sizeof(dirname));
    if (DIR.isDirectory()) {
      //DIRcount++;
      strcpy(DIR_list_array[DIRcount], dirname); // array
      strcat(DIR_list_array[DIRcount], "/");
      Serial.print("DIR# ");
      Serial.print(DIRcount);
      Serial.print("\t");
      Serial.println(DIR_list_array[DIRcount]); // SDFAT LIB
      DIRcount++;
    }
    DIR.close();
  }
  DIRcount --;
  Serial.print("\t **Directory count ");
  Serial.print(DIRcount), Serial.println(" **"), Serial.println();
  m_pSource.close();
}
//----------------------------------------------------------------------------

//============================================================================
// Print Files in Cur. Directory
//============================================================================
void PrintFiles(File dir) {
  Serial.println("\t**List Files in Cur. Directory**");
  char filename[max_DIR_name_lenght]; // SDFAT

  int len = strlen(filename);
  char *extension = filename + len - 4;

  while (true) {

    File entry = dir.openNextFile();
    if (! entry) {
      // no more files
      Serial.println("\t **no more files**");
      entry.close();

      // Serial.print("\t TOTAL PMF_FILE_counter: "), Serial.println(TOTAL_PMF_FILE_counter), Serial.println();
      break;
    }
    entry.getName(filename, sizeof(filename));

    if (entry.isDirectory()) {
      // skip
    } else {
      Serial.print(filename); // SDFAT LIB
      // files have sizes, directories do not
      Serial.print("       \t");
      Serial.print(entry.size(), DEC);

      Serial.print("\t dirIndex  "), Serial.println(entry.dirIndex());

      // PMF File Format counter
      /*
        len = strlen(filename);
        extension = filename + len - 4;
        if (!strcmp(".pmf", extension) || !strcmp(".PMF", extension)) {
        TOTAL_PMF_FILE_counter++;
        }
      */
    }
    entry.close();
  }
}
//----------------------------------------------------------------------------
 
If you don't mind, can you zip the changes and send over? I did the changes above and am still getting some errors when compiling.
I think I must not create SD as :
SdFat SD;
When using the 4.1?

Unfortunately, it's not that easy... I've done all this on my own "gone way out in left field" fork of RunCPM. ZCPR3.3, ZSDOS, serial and parallel port (yeah, it's me, mecparts).

Let me start over with a current mainline copy and I'll get back to you. As I said, it only took me an hour to figure out the first time (and that included getting my SdFat extensions for setting file attributes and timestamps migrated to SdFat-beta), so it shouldn't take me too long.
 
Unfortunately, it's not that easy... I've done all this on my own "gone way out in left field" fork of RunCPM. ZCPR3.3, ZSDOS, serial and parallel port (yeah, it's me, mecparts).

Let me start over with a current mainline copy and I'll get back to you. As I said, it only took me an hour to figure out the first time (and that included getting my SdFat extensions for setting file attributes and timestamps migrated to SdFat-beta), so it shouldn't take me too long.

Cool, thanks.
I feel that I am really close. But it has been a long day so it is hard for me to concentrate.
 
Cool, thanks.
I feel that I am really close. But it has been a long day so it is hard for me to concentrate.
No trouble at all. I'd just finished a 22km bike ride before sitting down at the computer so my mind is fresh even if my knees are complaining.

And right now, grabbing a couple extra 4.1s as soon as DigiKey had them in stock is about to pay off. I don't even need to disturb the "TeensyBoard/Z80". ;)
 
I got it to work.

Looks like I will have to do a major cleanup, but I will probably upload a new version to GitHub soon.

Thanks a lot for the tips.
 
And I got my changes to work on the mainline code as well. If you want to check anything, I've pushed my changes to https://github.com/mecparts/RunCPM. It's up and running on one of the spare T4.1s. I'm just going to double check again a "clean but renamed" copy of SdFat-beta (i.e. without my file set attribute additions) but I don't expect any trouble.

Edit: checked out okay with a "clean but renamed" copy of SdFat-beta.
 
Last edited:
Status
Not open for further replies.
Back
Top