How to use SdFat with SPI1? Or change SPI pins.

tomicdesu

Member
I can't seem to puzzle out how to get SdFat to use SPI1, eg. pins 1, 26 and 27 (MISO1, MOSI1, SCK1). I tried to satisfy the SdSpiDriver config but nothing works -- I get an error return from begin(). I can't use the default pins as they're being used by VGA DMA done by the FlexIO.

Either of these solutions would solve my problem:

* Can the default SPI device driver be told to use different, arbitrary pins?

* How do I tell the SdFat driver to use SPI1 and not SPI?

The code below is about as simple as possible, and does only begin() on one drive. I posted a similar question in the Technical Support section. I don't mean to spam, I think that one is too complex and I wasn't sure what board to post in.

Any help appreciated.

tom


Code:
#include <SPI.h>
#include "sdios.h"
#include "SdFat.h"

#define SD_USE_CUSTOM_SPI

#define SDCARD_SD1_PIN 36
#define SDCARD_SD2_PIN 37

#define SDCARD_MISO_PIN 1
#define SDCARD_MOSI_PIN 26
#define SDCARD_SCLK_PIN 27

SdExFat sd1;

void setup() {
  Serial.begin(9600);

  // disable sd2 while initializing sd1
  pinMode(SDCARD_SD2_PIN, OUTPUT);
  digitalWrite(SDCARD_SD2_PIN, HIGH);
 
  delay (500);

  Serial.println ("\n\nsd1.begin()");
  if (!sd1.begin (SdSpiConfig (SDCARD_SD1_PIN, SHARED_SPI, SD_SCK_MHZ (16)))) {
    Serial.println ("SD1 begin error");
  }
}

void loop() {}
 
Look at the SD library SdFat_Usage example (in Arduino IDE, click File > Examples > SD > SdFat_Usage). The info you need starts at line 54.

Since Teensyduino 1.54 the SD library is really just a thin wrapper for SdFat, so even though you use simpler SD.h is really is SdFat and all the SdFat capabilities can be accessed.
 
Aargh, I don't know how I did not see that obvious example in SdFat_Usage. My apologies, and thanks, for you having to point it out.

That fixed my SPI problem. SPI signals now appear on the right pins (1, 26, 27), I can see them with my 'scope. They look approximately correct (select true-low, SCLK, data on MOSI, a short burst on MISO (not gonna try to decode SPI with an oscilloscope!).

Code:
chipSelect= 36;

// ok = SD.sdfs.begin(SdioConfig(FIFO_SDIO));
  ok= SD.sdfs.begin (SdSpiConfig (chipSelect, SHARED_SPI, SD_SCK_MHZ(4), &SPI1));

SdFat_Usage (and other examples, and my own code) works on the builtin, but the above fails, with init error. Bought new cards directly from Sandisk and they work on other machines.

Where is the SD.h and SdFat.h libraries peculiar to teensy reside? I've removed SD.h and SdFat.h from Arduino/libraries as suggested. There's usually a hardware folder in the Arduino folder but I just switched to Arduino IDE 2.3.4 on linux, to get teensy support, which runs as an AppImage, which I think contains the folder I need to look at.

The SD object is pre-instantiated, which so far prevents me from running multiple SD cards. Less worried about that at the moment.


This is my code, A: (built in SDIO card) succeeds, B: (second full size SD card) fails.

Code:
SdFs SDa, SDb;
public:

void setup () {
bool ok;

  L.log (F("setup SDCards"));
  T.begin (NUMTIMERS);
  T.setTimer (LOOPTIMER, 1);

  ok = SDa.begin (SdioConfig(FIFO_SDIO));
  L.log ("setup SDCard A:", ok ? "succeeded" : "failed");

  // Set B: and C: SD selects off.
  pinMode (SD1CS, OUTPUT); digitalWrite (SD1CS, 1);
  pinMode (SD2CS, OUTPUT); digitalWrite (SD2CS, 1);

  ok= SDb.begin (SdSpiConfig (SD1CS, SHARED_SPI, SD_SCK_MHZ(4), &SPI1));
  L.log ("setup SDCard B:", ok ? "succeeded" : "failed");
 
Last edited:
Well its a PCB, here's the deets. I agree, it should be working. I suspect I'm having an SD-code-not-SPI problem.

Oh, I know SPI1 is being used -- before this I could see the SPI signals on the SPI (default) pins. THey've moved to 1, 26, 27 as expected.
 

Attachments

  • IMG_20250128_174513_429.jpg
    IMG_20250128_174513_429.jpg
    251.8 KB · Views: 18
  • layout.png
    layout.png
    793.6 KB · Views: 19
  • cpu.png
    cpu.png
    1.1 MB · Views: 17
  • sds.png
    sds.png
    128.9 KB · Views: 15
Maybe try this?

Code:
#include <SD.h>

SDClass SD1;
SDClass SD2;

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  Serial.println("SD 3 card test");
  if (SD.begin()) {
    Serial.println("SD ok");
  }
  if (SD1.sdfs.begin(SdSpiConfig(36, SHARED_SPI, SD_SCK_MHZ(16), &SPI1))) {
    Serial.println("SD1 ok");
  }
  if (SD2.sdfs.begin(SdSpiConfig(37, SHARED_SPI, SD_SCK_MHZ(16), &SPI1))) {
    Serial.println("SD2 ok");
  }
}

void loop() {
}
 
Thanks Paul! Alas it made no difference. I think I need to go through the SD begin code and see where and why it is failing.

But I can't find it! The Teensy SD files are no where to be found. They're not in a library. Arduino runs out of an AppImage on linux, not my choice, I did mount that and looked for source code in there but I'm stumped where the Teensy-specific stuff resides. Do you have any ideas?

Then maybe I can also work out what the difference between these various objects are.

Or am I overlooking something really dumb and simple? Lol, I'm good at that. I had Greiman's SdFat installed but removed that also under earlier instructions. Clearly SD stuff is being satisfied by some code but it's a mystery which.

In fact I prefer my own mistakes, they're the easiest to fix!
 
No idea where the source might live. I haven't restored the Teensy environment on my Linux box since I had to replace it. But when you build a project, everything gets compiled and the objects stored in a temporary directory. Find that and you will find everything fed to the linker. With file names it shouldn't be too difficult to track down the source code.
 
OK, the teensy core libraries seem to be at

Code:
~/.arduino15/packages/teensy/hardware/avr/1.59.0/libraries

I'm poking at USB keyboard now, I'll do some debugging in the SD stuff this week.
 
The SD library apparently can provide more detailed error information than just, it didn't work.

TeensySdioDemo/TeensySdioDemo.ino: printSdErrorSymbol(&Serial, sd.sdErrorCode());
 
Hey, thanks UhClem. Lol the error code is SD_CARD_ERROR_CMD0. "0" sounds early... But I'll now go look that up and start to debug the SD library I think I found.

SDClass has no such member, but SdFs does.

EDIT: OMFG of course it was a stupid and basic misteak -- wrong MISO pin. I misread traces on my own PCB. Sheesh. Error 0 is as expected the initial test select fo the SD card, so an SPI issue. I'd seen the brief response from the card to Teensy on the pin, but the wrong pin. Off-by-one error.

I put a bunch of print statements into SdFat/SsSpiCard.cpp so in fact the SdFat library is the one at ~/.arduino15/packages/teensy/hardware/avr/1.59.0/libraries

Thanks again Paul and UhClem for your help and patience.
 
Last edited:
Back
Top