microSD slot on teensy 3.6

Status
Not open for further replies.
If anyone wants to try this, just replace your copy of the SD lib in hardware/teensy/avr/libraries/SD with this copy from github. Do *not* edit SD_t3.h for the optimized stuff.

In your program, use BUILTIN_SDCARD for the chip select pin. If you use it, please reply here to let me know how it works for you? My hope is to release 1.31-beta2 by this weekend, with this and several other fixes.

I keep getting: 'BUILTIN_SDCARD' was not declared in this scope even after dowloading the Github version of SD directory and placing as you suggest.
This happens for IDE SD cardinfo example, and with drmartin's code as posted earlier in this thread (with SS replaced by BUILTIN_SDCARD)

What might be causing this ?
I'm running IDE 1.6.12 and a recent teensyduino
(where do I find my current teensyduino version number?)
 
Last edited:
You need to update both your version of the Arduino IDE and your version of Teensyduino.

The core libraries were updated to include the definition of BUILTIN_SDCARD on 10/23/2016 beginning with Teensyduino 1.31.

Clicking HELP - ABOUT on the Teensy Loader when it is displayed will show you the version.
 
Last edited:
I'm already using teensyduino 1.32 ... I can update but is there another possible cause?
(I would prefer not to update to 1.8.1/1.34 until 1.34 is not a beta)
 
Update to Arduino 1.8.0 (not 1.8.1) and Teensyduino 1.34. No betas.

It's 1.35 that's currently in beta. But 1.35-beta1 is pretty much exactly the same as 1.34 with an update for 1.8.1.

Teensyduino 1.35-beta2 will bring a bunch of new fixes and updates, probably later today. My hope is to finalize all that later this week. Even though it's quite a bit fixes, they're all low-risk stuff.

But 1.34 is fully released, no beta at all. It supports Arduino 1.8.0. Just use that. There's nothing new in 1.8.1 for Teensy. 1.8.1 fixed driver problems affecting certain Arduino brand boards, and a SD library bug that isn't present Teensyduino's version of the SD library, so you probably *do* want 1.8.1 if you're using SD cards on regular Arduino boards. If only using Teensy, 1.8.1 makes no difference at all.
 
oops - mixed up 1.34 and 1.35 :(
I have a second machine already at 1.6.13 + 1.34, but BUILTIN_SDCARD not recognised there either.
OK I'll upgrade to 1.8.0
 
Also make sure you are using library installed by Teensyduino and not one in you sketch folder/libraries
 
hmmm ... still not solved :(

I've just upgraded to 1.8.0 with 1.34 (and I'm using TyQt).
I did find SD in my libraries folder, so I moved it out. (it was dated 18Dec16 so probably a prior download from Paul's GitHub)

more suggestions (please :) ) ?

Here's the error message:

Arduino: 1.8.0 (Windows 10), TD: 1.34, Board: "Teensy 3.5, Serial, 120 MHz, Fast, US English"

teensySDproto:22: error: 'BUILTIN_SDCARD' was not declared in this scope
const uint8_t SD_CHIP_SELECT = BUILTIN_SDCARD;

^

'BUILTIN_SDCARD' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.


and the code:
Code:
#define CJ_ID "teensySDproto.c"

/* Initialises an SD card and analyzes its structure using either 
    1) grieman's SdFat_beta for teensy 3.5/6 at
       https://github.com/greiman/SdFat-beta/blob/master/changes.txt or
    2) teensy SD library (SDIO = 0) */

// 15Jan: SPI mode not working (but SDIO mode working)
#define USE_SDIO 0                             // 0: access SD via SPI, 1:use SDIO 

#define sdErrorMsg(msg) sd.errorPrint(F(msg)); // store error strings in flash


#include <SPI.h>
#include <SdFat.h>                             // grieman's SdFat_beta 

/* Default SD chip select (CS) is the SPI SS pin. Other common pins:
    - Arduino Ethernet shield, pin 4.
    - SparkFun SD shield, pin 8.
    - Adafruit SD shields and modules, pin 10 */
//const uint8_t SD_CHIP_SELECT = SS;
const uint8_t SD_CHIP_SELECT = BUILTIN_SDCARD;

/* Set DISABLE_CHIP_SELECT to disable a second SPI device. For example, with the 
 * Ethernet shield, set DISABLE_CHIP_SELECT = 10 to disable the Ethernet controller. */
const int8_t DISABLE_CHIP_SELECT = -1;

#if USE_SDIO
  //SdFatSdio sd;
  SdFatSdioEX sd; // faster
#else
  SdFat sd;
#endif

ArduinoOutStream cout(Serial); // serial output steam

uint32_t cardSize;
uint32_t eraseSize;

//------------------------------------------------------------------------------
void setup() {
  delay(2000);
  Serial.begin(9600);
  while (!Serial && (millis() <= 4000)) {SysCall::yield();} // Wait up to 4 seconds for USB Serial 
  cout << uppercase << showbase << '\n';  // use uppercase hex and 0X base prefix
  cout << F("SdFat version: ") << SD_FAT_VERSION << '\n';
  #if !USE_SDIO  
    if (DISABLE_CHIP_SELECT < 0) {
      cout << F("\nAssuming the SD is the only SPI device.\n"
             "Edit DISABLE_CHIP_SELECT to disable another device.\n");
      }
    else {
      cout << F("\nDisabling SPI device on pin ");
      cout << int(DISABLE_CHIP_SELECT) << endl;
      pinMode(DISABLE_CHIP_SELECT, OUTPUT);
      digitalWrite(DISABLE_CHIP_SELECT, HIGH);
      }
    cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
    cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
  #endif
  }

//------------------------------------------------------------------------------
void loop() {
  do {delay(10);} while (Serial.available() && Serial.read() >= 0); // Flush any existing Serial data.
  cout << F("\ntype any character to start\n");
  while (!Serial.available()) {SysCall::yield();}
  uint32_t t = millis();
  #if USE_SDIO
    if (!sd.cardBegin()) {sdErrorMsg("\ncardBegin failed"); return;}
  #else // Initialize at the highest speed supported by the board that is
        // not over 50 MHz. Try a lower speed if SPI errors occur.
    if (!sd.cardBegin(SD_CHIP_SELECT, SD_SCK_MHZ(50))) {
      sdErrorMsg("cardBegin failed"); return;}
   #endif  
  t = millis() - t;
  cardSize = sd.card()->cardSize();
  if (cardSize == 0) {
    sdErrorMsg("cardSize failed");
    return;}
  cout << F("\ninit time: ") << t << " ms" << '\n';
  cout << F("\nCard type: ");
  switch (sd.card()->type()) {
    case SD_CARD_TYPE_SD1:
      cout << F("SD1\n");
      break;
    case SD_CARD_TYPE_SD2:
      cout << F("SD2\n");
      break;
    case SD_CARD_TYPE_SDHC:
      if (cardSize < 70000000) {cout << F("SDHC\n");}
      else {cout << F("SDXC\n");}
      break;
    default: cout << F("Unknown\n");
    }
  if (!cidDmp()) {return;  }
  if (!csdDmp()) {return;}
  uint32_t ocr;
  if (!sd.card()->readOCR(&ocr)) {
    sdErrorMsg("\nreadOCR failed");
    return;}
  cout << F("OCR: ") << hex << ocr << dec << '\n';
  if (!partDmp()){return;}
  if (!sd.fsBegin()) {
    sdErrorMsg("\nFile System initialization failed.\n");
    return;}
  volDmp();
  }

Code:
//------------------------------------------------------------------------------
// store error strings in flash
//#define sdErrorMsg(msg) sd.errorPrint(F(msg));
//------------------------------------------------------------------------------
uint8_t cidDmp() {
  cid_t cid;
  if (!sd.card()->readCID(&cid)) {
    sdErrorMsg("readCID failed");
    return false;
  }
  cout << F("\nManufacturer ID: ");
  cout << hex << int(cid.mid) << dec << '\n';
  cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << '\n';
  cout << F("Product: ");
  for (uint8_t i = 0; i < 5; i++) {
    cout << cid.pnm[i];
  }
  cout << F("\nVersion: ");
  cout << int(cid.prv_n) << '.' << int(cid.prv_m) << '\n';
  cout << F("Serial number: ") << hex << cid.psn << dec << '\n';
  cout << F("Manufacturing date: ");
  cout << int(cid.mdt_month) << '/';
  cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << '\n';
  cout << '\n';
  return true;
}
//------------------------------------------------------------------------------
uint8_t csdDmp() {
  csd_t csd;
  uint8_t eraseSingleBlock;
  if (!sd.card()->readCSD(&csd)) {
    sdErrorMsg("readCSD failed");
    return false;
  }
  if (csd.v1.csd_ver == 0) {
    eraseSingleBlock = csd.v1.erase_blk_en;
    eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
  } else if (csd.v2.csd_ver == 1) {
    eraseSingleBlock = csd.v2.erase_blk_en;
    eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
  } else {
    cout << F("csd version error\n");
    return false;
  }
  eraseSize++;
  cout << F("cardSize: ") << 0.000512*cardSize;
  cout << F(" MB (MB = 1,000,000 bytes)\n");

  cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
  cout << F("eraseSingleBlock: ");
  if (eraseSingleBlock) {
    cout << F("true\n");
  } else {
    cout << F("false\n");
  }
  return true;
}
//------------------------------------------------------------------------------
// print partition table
uint8_t partDmp() {
  mbr_t mbr;
  if (!sd.card()->readBlock(0, (uint8_t*)&mbr)) {
    sdErrorMsg("read MBR failed");
    return false;
  }
  for (uint8_t ip = 1; ip < 5; ip++) {
    part_t *pt = &mbr.part[ip - 1];
    if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
      cout << F("\nNo MBR. Assuming Super Floppy format.\n");
      return true;
    }
  }
  cout << F("\nSD Partition Table\n");
  cout << F("part,boot,type,start,length\n");
  for (uint8_t ip = 1; ip < 5; ip++) {
    part_t *pt = &mbr.part[ip - 1];
    cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
    cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << '\n';
  }
  return true;
}
//------------------------------------------------------------------------------
void volDmp() {
  cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << '\n';
  cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << '\n';
  cout << F("clusterCount: ") << sd.vol()->clusterCount() << '\n';
  cout << F("freeClusters: ");
  uint32_t volFree = sd.vol()->freeClusterCount();
  cout <<  volFree << '\n';
  float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
  cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n");
  cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << '\n';
  cout << F("fatCount: ") << int(sd.vol()->fatCount()) << '\n';
  cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << '\n';
  cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << '\n';
  cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << '\n';
  if (sd.vol()->dataStartBlock() % eraseSize) {
    cout << F("Data area is not aligned on flash erase boundaries!\n");
    cout << F("Download and use formatter from www.sdcard.org!\n");
  }
}
 
Last edited:
Hi,

Just skimmed the thread, so apologies if I missed this, but have you tried changing
#define USE_SDIO 0
to
#define USE_SDIO 1
?

--Michael
 
Also maybe I am off here, but I think this assumes you are including the SD library. My quick look at your code looks like you are including the SDFAT library...
 
Yes USE_SDIO = 1 works ... but my aim is to reuse extensive logging code I developed on Mega using SdFat library.

I started with drmartin's code in this thread at post #8, which does not include SD library. And the error also happens for IDE SD cardinfo example.

Maybe I am misunderstanding relationship between these uses:
1) SD
2) SD for teensy
3) SdFat
4) SdFat for teensy?

From what I've seen so far using SDIO mode appears to force a large rewrite of my old code. Hence why I'm keen to get non-SDIO mode. But as I said, I maybe misunderstanding

A workaround idea - what is the numeric pin value of BUILTIN_SDCARD for T3.5 and 3.6?
 
Last edited:
A workaround idea - what is the numeric pin value of BUILTIN_SDCARD for T3.5 and 3.6?

What many people appear to be missing is that the SD Card Socket on the Teensy 3.5 and Teensy 3.6 is connected to an entirely new interface inside the microprocessor from where the SD Cards on prior Teensy products were connected.

The on-board Teensy 3.5/3.6 SD Card Sockets are connected to the micro's SDIO interface logic -- NOT the micro's SPI interface logic.

The new SDIO and the old SPI Interfaces are different and each requires a specific command set to communicate properly.

The old SPI interface was generally a four wire system - Chip Select - CS, Serial Clock - SCk, Master Out / Slave in - MOSI, and Master In / Slave Out - MISI0. Note the SPI interface uses a single bit data line as it clocks data in and out of the connected device. (One Bit transferred per Clock cycle).

The new SDIO interface (as connected to the on-board SD Card Socket) is six wires and can be configured to use FOUR data lines at the same time to transfer data with the connected device. In theory, this allows for faster transfers but requires a significantly different interface driver in the associated library. (Four Bits transferred per Clock cycle)

Several SD Card libraries have been modified to use the new SDIO interface but do so by utilizing unique low level routines to access the SD Card depending on whether they are configured for the SPI or SDIO mode.

Essentially either the USE_SDIO=1 or the BUILTIN_SDCARD parameter is a flag to inform the SD Card library to completely "switch gears" and use a whole new set of low level routines to access the SD Card.

The BUILTIN_SDCARD parameter is NOT just a CS Pin Number.

Unmodified libraries can not "speak SDIO" by simply changing the CS Pin Number.

Great effort has been expended to "hide" the low level details from the user and make the libraries "just work" with either interface by setting a parameter. BUT the user needs to realize that the underlying structures need to be able to "switch modes" for the library to work with the new SDIO interface.

If you application uses libraries that only "speak SPI" then you may wish to consider connecting an external SD Card Socket to the appropriate SPI pins and just push forward until the libraries are updated.

-----------------

PS - The above explanation is slightly simplified.

Almost every pin on the Teensy 3.5 / 3.6 can be connected to serve alternate functions inside the micro via the K66 Signal Multiplexer. The micro pins wired to the on-board micro SD Socket can actually be "connected to" and used as Digital IO, ADC inputs, UART IO, SPI IO, I2C, or SDIO.

So it is POSSIBLE to reconfigure the K66 Signal Multiplexer to connect the on-board micro SD Socket pins to the SPI1 interface in the micro instead of the more common connection to the SDIO interface.

That would solve the SPI vs SDIO problem but the SD Library would still need some serious work to configure, setup, and use the new pins on the SPI1 bus....... (note this involves the SPI1 bus - not the usual SPI bus -- more things to mess with).

The return on investment would push me towards just updating a SPI only SD Library to support use of the new SDIO interface also. This is the solution most developers have adopted with schemes like USE_SDIO=1
 
Last edited:
thanks for the detailed explanation drmartin, helps a lot.

So the teensy hardware is very different to other SD cards used on arduinos, but what about SdFat?

Perhaps if I put my question another way. Below is my typical code based on SdFat extracted from several mature sketches I have been using on a Uno/Mega/Due for some time, focussing on the SD card usage (with many lines omitted). This is what I would like re-use in teensy, but the SdFat examples I have tried use quite different SD commands.

For example I can't use: logfile = SD.open(logFileName,FILE_WRITE);

and have to use something like this instead:
if (!logfile.open(logFileName, O_CREAT | O_WRITE | O_EXCL)) {..}

Is this simply because SdFat support for teensy has not been coded yet, or is it never going to happen?
TIA

Code:
#include <SdFat.h>                              // microSD interface
#include <SPI.h>     
#include <Streaming.h>                          // for simplified Serial string commands
.
.
#define CS_pin    48                            // (microSD:8, EtherMEGA:4, adafruit shield:10)
.
.
SdFat SD;
boolean SD_OK = true;                           // assume SD card OK as default
File root;                                      // SD card top directory
File logfile;                                   // SD card logfile
.
.
void setup(){
  pinMode(CS_pin, OUTPUT);
  if (!SD.begin(CS_pin)){
    Serial << F("[SD init FAILED]\n");
    SD_OK = false;
  } 
  else {
	Serial << F("[SD OK]\n");
    root = SD.open("/"); 
    printDirectory(root, 0);
  }
}
	
void loop(){
  .
  .
  if (logButtonPressed) processLogButton();              // see toggleLogging Interrupt Service Routine
  if (loggingActive) {addLogEntry();}
  .
  .
}


void processLogButton(){
  if (!loggingActive){                                    // if first time in this logging session
    loggingActive = true;                                 // start logging, but only if SD OK
    Serial << F("LOGGING to: <") << logFileName << ">\n";
    logfile = SD.open(logFileName,FILE_WRITE);            // only Open/Close once, not every row
  else {                                                  // button pressed while logging is active = request for OFF
    loggingActive = false;                                // toggle logging OFF
    logfile.close();                                      // close the file (once only, not every row)
  }
}
	
void addLogEntry(){
  .
  .
  if (logfile){
    logfile << entryNo << ',' << data1 << ',' << data2 << '\n';
	.
	.
  }
}
 
Last edited:
Did you try the examples and followed the instructions provided by Bill?
AFAIK yes

I cannot see any "SdFatSdio sd;" in your code
It's there .... but commented out in lieu of "SdFatSdioEX sd" as suggested by bill (code is in my post #32). EDIT: also tried "SdFatSdio sd;" - no luck

So I just unprgraded to IDE 1.8.1 + teensyduino 1.35.

Being conservative I reverted to drmartin's code at post 8 ( which is essentially SdFat/SdInfo example)

If I #define USE_SDIO 1 everything still works (same for my code)

If I #define USE_SDIO 0 and SD_CHIP_SELECT = SS the sketch it starts but fails reporting error below (also same for my code)
error: cardBegin failed
SD errorCode: 0X20,0X0

If I #define USE_SDIO 0 and SD_CHIP_SELECT = BUILTIN_SDCARD the compile fails with:
'BUILTIN_SDCARD' was not declared in this scope

BTW exact same happens if I run SD cardinfo example with chipSelect = BUILTIN_SDCARD

getting nowhere fast :(
 
Last edited:
Just saw some odd behaviour in the IDE Library Manager for
"SD Built-In by Arduino, Sparkfun Version 1.0.8 INSTALLED"
choosing 1.0.9 from pull-down and Update results in "Version 1.1.0 INSTALLED" WTF??
then choosing 1.1.1 from pull-down and Install reverts to "Version 1.0.8 INSTALLED" WTF^2 ??
I reverted to "Version 1.1.0 INSTALLED"
After this I see SKETCHES/libraries/SD directory has reappeared

Could this be the culprit, maybe this is subverting the SD library in teensyduino?

BTW serial shows "SdFat version:20160913"
 
Last edited:
Well finally a little progress. I develop my sketches on 2 PCs, so I revisited the SD cardinfo example on my other PC and got "Multiple libraries were found" error message:

CardInfo:36: error: 'BUILTIN_SDCARD' was not declared in this scope
const int chipSelect = BUILTIN_SDCARD;

Multiple libraries were found for "SD.h"
Used: C:\Users\cj\Documents\ARDUINO\SKETCHES\libraries\SD
Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD
Not used: C:\Program Files (x86)\Arduino\libraries\SD
'BUILTIN_SDCARD' was not declared in this scope


So I removed ARDUINO\SKETCHES\libraries\SD (again!) and cardinfo compiled and worked OK ... yay.
So at least BUILTIN_SDCARD now works with the SD library.
I guess the lesson here is to ignore SD library updates when offered by the IDE?

But what about using SdFat library in non-SDIO mode? (that's what I want/need)

Did you check to see if BUILTIN_SDCARD is defined in the "particular" version of Bill Greiman's library you are using? His libraries change daily.
I am using Bills latest, but I searched and there is no mention of BUILTIN_SDCARD therein, so presumably it makes no sense to use BUILTIN_SDCARD with SdFat lib ?

And the SD still doesn't work with SdFat lib, USE_SDIO = 0 and const uint8_t SD_CHIP_SELECT = SS;

oh well... maybe I should take up gardening, or trout fishing ...
 
Last edited:
This is the SD library you need Arduino to use:


Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD

If you delete or move the one you've got in Documents\ARDUINO\SKETCHES\libraries\SD, hopefully Arduino will start making use of the correct lib.

Or there's other ways you could try solving this, like copying the right one to Documents\ARDUINO\SKETCHES\libraries\SD. Perhaps first make a backup of whatever you currently have there, in some location where Arduino won't notice and try to use it. That "multiple libraries" message is there to help you resolve these sorts of problems.
 
But what about using SdFat library in non-SDIO mode? (that's what I want/need)

I thought I pointed you to a Teensy 3.5/3.6 version of the SdFat Library that was compatible with the on-board Teensy 3.5/3.6 SD Card Socket in my previous post.....

However, if you insist in using another SdFat library then two things have to happen:

a) The library must support the Teensy AVR Architecture. Paul has spent years attempting to make the transition from Ardunio ARM to the NXP AVR microprocessor painless but occasionally the library author has done something that does not translate cleanly.

Does your sketch compile cleanly using the version of the SdFat Library that you want to use ??

(Note this is a compile only question -- We know and understand it won't actually access the SD card but we should make sure it compiles ok before taking the next step.)

b) You HAVE to connect a SD Card Socket to the pins available for use by your selected library.

Everything in this adventure suggests that your selected SdFat Library has to access the SD Card using only the SPI interface.

If the library uses the SPI Interface pins to communicate but the SD Card is actually connected to the SDIO interface pins then obviously no communications will occur.

As you know and have tried, there are some options available to move the pin assignments around. However, nothing I've seen suggests that your selected version of the SdFat Library can be configured to use the pins connected to the Teensy 3.5/3.6 on-board SD Card Socket.

Your selected version of the SdFat Library simply does not seem to have the options needed to configure the SPI interface to use pins connected to the on-board SD Card Socket.

A solution would be to back up a step and connect an external Sd Card Socket to the proper SPI Pins.

IE Use Pins that your selected library knows about and can use. Look at any SD Card connected to a Teensy 3.2 for an example and working solution that also can be applied to the the 3.5/3.6.

This should get you going as:

1) your are using your preferred version of the (Teensy Compatable) SdFat Library,
2) it uses the SPI Interface in the micro,
3) and the SPI Interface is actually wired to the SD Card Socket pins !!!!!

This appears to be a $6 solution until a version of the SdFat Library that meets your needs and is compatible with the on-board SD Card Socket connections becomes available. See https://www.pjrc.com/store/wiz820_sd_adaptor.html

Below is an example showing a Teensy 3.6 with two SD Card Sockets attached. The on-board socket is wired to the SDIO interface and works great with libraries that know how to use that interface. The "external" SD Card Socket happens to live on an Audio Board but is simply connected to the Teensy 3.6's SPI interface.

Libraries that only "speak SPI" work great with the "external" SD Card Socket.

I just plug the SD Card into the proper socket for the library I'm using at the moment.

Teensy SD Card.jpg
 
Last edited:
If you delete or move the one you've got in Documents\ARDUINO\SKETCHES\libraries\SD, hopefully Arduino will start making use of the correct lib.

yes that's what I did and Examples >SD>cardinfo now works fine (i.e using SD.h is good now)

For my future reference - when the IDE pop-up offers library updates and the Library Manager lists "SD" as Updatable, should I ignore this ? It seems some of my difficulties arose because the teensyDuino SD library is not updated by this mechanism, and in fact get's hidden by the new Arduino version loaded into SKETCHES/libraries/SD directory by the Library Manager.

TIA
 
However, if you insist in using another SdFat library ...
There's no other SdFat version. I have always been trying to use Bill Greiman's SdFat-beta library (per your link) throughout this discussion. And I reloaded it again recently, just in case.

Does your sketch compile cleanly using the version of the SdFat Library that you want to use ??
Yes

b) You HAVE to connect a SD Card Socket to the pins available for use by your selected library.
See below - I'm only using the built in SD socket on a T3.5.

A solution would be to back up a step and connect an external Sd Card Socket to the proper SPI Pins

I could try that, but since I am using the correct SdFat beta library, and I have several known proven code examples (e.g. yours at post#8 and greiman's examples) then I expect my setup to work once my issue is resolved.

In any event I will be not be fitting an extra SD socket as a long term solution (would kinda defeat reasons I went for T3.5/6). In the worst case I will just have to revamp my legacy SD code to use SDIO mode, but I remain optimistic :cool:

Just to be sure can you confirm the following configuration works for you:

1) using Bill Grieman's SdFat-beta library, and

2) using built in SD on T3.5 (or T3.6) with a working, formatted microSD card inserted, and

3) using your code at post #8 with USE_SDIO = 0 and SD_CHIP_SELECT = SS (*not* BUILTIN_SDCARD)

If I do exactly the three steps above, this is what Serial reports:

SdFat version: 20160913

Assuming the SD is the only SPI device.
Edit DISABLE_CHIP_SELECT to disable another device.

Assuming the SD chip select pin is: 10
Edit SD_CHIP_SELECT to change the SD chip select pin.

type any character to start
error: cardBegin failed
SD errorCode: 0X20,0X0

type any character to start


PS: I just tried same on my T3.6 - same result.

If you still think there's value in trying an external SD card to find the underlying cause, I will be happy to do that (as a test ... not permanent)

many thanks again for your persistence ...
 
Last edited:
thanks for your suggestions oric_dan, but per my last three posts I no longer have the issue around 'BUILTIN_SDCARD was not declared in this scope' when including SD.h library

c. do not worry about deleting the SD library located in the main \libraries directory of the IDE, as those libraries will not be linked in.
Are you sure that will not be linked in? The solution in my case was to delete SKETCHES/libraries/SD directory
 
Last edited:
No - I'm only using the built in SD socket on a T3.5.

Since you are using the built-in SD socket and since this SD socket is wired to the SDIO interface you ABSOLUTELY MUST tell your SdFat_beta library to use the SDIO interface.

1) using Bill Grieman's SdFat-beta library, and
2) using built in SD on T3.5 (or T3.6) and
3) using your code at post #8 with USE_SDIO = 0 and SD_CHIP_SELECT = SS (*not* BUILTIN_SDCARD)

If I do exactly the three steps above, this is what Serial reports:

SdFat version: 20160913

Assuming the SD is the only SPI device.
Edit DISABLE_CHIP_SELECT to disable another device.

Assuming the SD chip select pin is: 10
Edit SD_CHIP_SELECT to change the SD chip select pin.

type any character to start
error: cardBegin failed
SD errorCode: 0X20,0X0

type any character to start

This is exactly what I've been talking about for several rounds of your adventure. In step 3 above, you explicitly say NOT to use the SDIO interface "USE_SDIO = 0" so the library follows your instructions and reverts to using the SPI interface.

Notice your serial output where it says

Assuming the SD is the only SPI device.
Assuming the SD chip select pin is: 10

This confirms that the SdFat library is expecting to find the SD card connected to the SPI interface using Pins 10, 11, 12, and 13.

Now, since the built in SD Card socket is NOT CONNECTED to any of the above pins "cardBegin WILL fail".

-------------------------

if you are going to use the built in SD Card socket which is connected to the SDIO interface -- you must tell the SdFat library to use the SDIO interface --> USE_SDIO = 1

((Warning to others who may read this saga -- other libraries use different techniques to switch between the SDIO interface and the SPI interface. For example, Paul uses a special "pin definition" -- BUILTIN_SDCARD -- to inform the library to switch between the two interfaces. You must check the library you intend to use to verify it supports the SDIO interface and discover how to tell it which interface should be used. Your interface selection technique must match that expected by the library.))

------------------------

You have proven in several posts that other test examples using other libraries will work by using the SDIO interface and the built in SD Card socket.

Your challenge is to verify that your selected SdFat library can be configured to use the SDIO interface and the built in SD Card socket.

It appears that this may be possible when using the SdFat Beta Library if you say --> USE_SDIO = 1

-------------------------
 
Last edited:
Are you sure that will not be linked in?

Yes, very sure. When Arduino gives you that "Multiple libraries found..." message, you can be very certain Arduino really is using the one it say it's using, and ignoring the one(s) it claims it is not using.

But if you're really paranoid, of course you can examine the full pathnames on the excessive amount if verbose info while compiling, if enabled from File > Preferences. I'm very confident you will confirm Arduino does actually do as it says in that message. But if you find evidence to the contrary, please do report it, as that's almost certainly a bug in Arduino's build process. Arduino is far from 100% bug free, but that particular part seems to be very solid. I'll be very, very surprised if any case can be found where it doesn't actually do (include paths, compile command and linker command) as that message claims.
 
Status
Not open for further replies.
Back
Top